Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spec: Document rules for recursive type and other self-referential decls #5069

Open
nico opened this issue Mar 18, 2013 · 7 comments
Open

spec: Document rules for recursive type and other self-referential decls #5069

nico opened this issue Mar 18, 2013 · 7 comments
Assignees
Milestone

Comments

@nico
Copy link

@nico nico commented Mar 18, 2013

The spec says "An interface type T may not embed itself or any interface type that
embeds T, recursively.", but nothing like this is mentioned for structs.

(A struct containing itself would obviously need infty memory, but the spec should
probably still explicitly mention that these are illegal while a struct containing a
pointer to itself is fine
@robpike
Copy link
Contributor

@robpike robpike commented Mar 18, 2013

Comment 1:

It could embed a pointer to itself, though, and that works just fine. It's pointless to
embed a non-pointer recursively this way. Is that really worth explaining in the spec?

@griesemer
Copy link
Contributor

@griesemer griesemer commented Apr 1, 2013

Comment 2:

This applies also to named fields for structs, and arrays, too.
In general, all "composite value types" cannot contain themselves directly or indirectly
unless there's a reference type between.
It's somewhat obvious but it probably should be spec'ed out explicitly, after all it's
something that typecheckers go though some length to check.

Labels changed: added documentation.

Owner changed to @griesemer.

Status changed to Accepted.

@rsc
Copy link
Contributor

@rsc rsc commented Nov 27, 2013

Comment 3:

Labels changed: added go1.3maybe.

@rsc
Copy link
Contributor

@rsc rsc commented Dec 4, 2013

Comment 4:

Labels changed: added release-none, removed go1.3maybe.

@rsc
Copy link
Contributor

@rsc rsc commented Dec 4, 2013

Comment 5:

Labels changed: added repo-main.

@rsc rsc added this to the Unplanned milestone Apr 10, 2015
@griesemer griesemer changed the title spec: Recursive structs aren't mentioned spec: Document rules for recursive type decls and other self-referential decls Jan 7, 2016
@griesemer griesemer changed the title spec: Document rules for recursive type decls and other self-referential decls spec: Document rules for recursive type and other self-referential decls Jan 7, 2016
@jub0bs
Copy link

@jub0bs jub0bs commented Jun 17, 2021

Any update on this issue? As a Go trainer, I'd like to be able to point participants to an authoritative passage of the spec that would elucidate the restriction.

@griesemer
Copy link
Contributor

@griesemer griesemer commented Jun 17, 2021

No, this has not been addressed yet, sorry.

But the rules are fairly simple:

  1. Array and struct types are invalid if they require infinite amounts of memory.
  2. For interface types the rule is written down in the spec.
  3. For all other types, there are no restrictions on self-reference.

There's a rule of thumb for 1):
Is it possible to write down a corresponding composite literal in a finite amount of source text, without using a variable of the type in question? If not, the type is invalid.

For example, given:

type S struct {
   a S
}

there is no way to write down a composite literal for S in a finite amount of source text:

var s = S{a: S{a: S{a: ... // never ends

(and note that you're not allowed to use a variable of type S inside the composite literal to "shortcut": var t = S{s} is not permitted because it's using s of type S).

This may be a reasonable and intuitive way to teach this restrictions to new Go programmers. It's also accurately reflecting the reason for the restriction (the type checker does exactly this test).

@griesemer griesemer removed this from the Unplanned milestone Aug 10, 2021
@griesemer griesemer added this to the Go1.18 milestone Aug 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants