-
Notifications
You must be signed in to change notification settings - Fork 18k
spec: document cycle restrictions for alias type declarations #25187
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
Comments
Terminology: I use "type alias cycles" to refer to things like I see three options here:
I think with the type alias proposal we had decided on option 1 (and subsequently mostly implemented it), but I'm thinking now it was done without considering the larger scope. As far as I can tell, the problem that type alias cycles introduce shouldn't be any fundamentally trickier than interface cycles. (E.g., we already have types that cannot be expanded out: https://play.golang.org/p/8KQfNRbGwRV) For consistency, I'd be inclined to favor options 2 or 3 over option 1. Option 2 is definitely the simplest (other than how to explain it in the spec), but may risk breaking backwards compatibility. I expect option 3 is necessary if we're interested in accepting #8082. -- I think we could perhaps pursue option 3 by defining a type serialization format that avoids needing to "expand out" the types. For example, if we use
We'd need to make sure there's a canonical mapping though. For example, |
@mdempsky Since such cycles can only be created via names in the first place, why not keep the names? Specifically, that might mean that in the compiler we would have to keep an Alias type node around (and always go to the aliased type before we use it). But it would also allow better error messages (that may refer to the alias name used in the error scenario, if any). |
@griesemer I think keeping extra type information around at compile-time is fine, but I'm concerned about what we do at link-time and run-time. There are a lot of ways that we depend on identical types mapping to the same runtime type descriptor. For example, type assertions, interface comparisons, or comparing reflect.Type values with ==. So if we have We could arbitrarily pick one, but that doesn't seem any better to me than creating an artificial type descriptor using synthetic placeholders like Alternatively, we could possibly modify the runtime code to not depend on a correspondence between type identity and type descriptor uniqueness, but that seems invasive and likely to (mildly, but negatively) impact even Go programs that don't use anonymous cycles. I'm also not even certain we could keep == working on reflect.Type if we get rid of type descriptor uniqueness. |
@mdempsky Good point. A numbering scheme seems like a better choice. Instead of counting "backwards" (or outwards), one could also just number the types that are referenced from left to right (when written out); that might be a bit easier to understand. So |
On the other hand, the inside out numbering may allow simpler composition: An outer type ( |
I see 4 different possible encoding schemes. For each one, I'll use
I think all of these should work, so it seems like a matter of preference on which to use. I'd argue we shouldn't use 2, because it would be inconsistent with how we handle non-cyclic DAG types. For example, I don't imagine we'd start encoding I'd also argue we shouldn't use 3, because it makes it too easy for people to accidentally implement 2 instead, with it working most of the time, but not always. (Again, trickier/subtler, but not impossible.) And lastly, I'd argue that 1 is nicer than 4 because it has the property that each time |
The “inside out” encodings are similar to de Bruijn indices, which similarly keep terms local and composable. (I'm not sure whether they correspond to (1) or (4) above, but it doesn't really matter.) |
Per the original type-alias design doc from @rsc, it must be possible to "expand out" type alias declarations; this wouldn't be possible for
type T = *T
without expanding endlessly.The spec doesn't say anything in this regard; and is generally vague or silent on the subject of cycles.
The text was updated successfully, but these errors were encountered: