-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Clarify the relationship between Void
and ()
#443
Comments
I don't have specific thoughts about these three options, but I do want to observe that Carbon's type(s) in this space probably should behave differently from C++'s
In C++, |
I would advocate for the unit type to be spelled |
I think there is substantial value in having n-ary tuples with uniform behavior for arbitrary n, and that should include the n=0 and n=1 cases, so I think we want a As for C++
I don't find any motivation in that list to specifically retain a void type in Carbon that is distinct from Let's not have a distinct [Edit: Previously I suggested removing |
I'm not advocating for a distinct But I think there is value in an alias of I don't think the downsides of having the alias are too bad. I think from a teaching perspective there is an easy suggestion: in a context where a tuple might be relevant, expected, or more obvious, use |
The alias option may be a good test case for the mooted principle that Carbon should minimize the need for a style guide, because experience from Swift makes it very clear that if we define such an alias, people will make style rules and even lint rules about it (and those rules will probably be less nuanced than the one @chandlerc suggests). Note that those examples aren't cherry-picked; the first three links are to the top three Google results for "swift style guide" (and the only actual style guides on the first results page, apart from a book that I don't have access to, but that does mention "Returning void" in its table of contents), and the last link is to what appears to be the canonical Swift linting tool. All of the problems with such a type alias will be compounded by the fact that (unlike in Swift) it will also be a value alias: if |
Agreed with @geoffromer, if we want |
I don't think that necessarily follows, but the polytypic nature of
... and these to be invalid:
Making Regarding the question of whether we permit
... then
... then |
I'm not at all sure about the restricted model of But I'm down with the suggestion from @jonmeow and the second half of @zygoloid's post about how to start minimally and how to handle So maybe we have a good consensus initial position here? |
No concerns raised with @chandlerc's suggestion that we have consensus. Decision: We will initially not have My suggestion for avoiding writing |
The placeholder design currently states that Carbon will have a primitive type
Void
, which it defines as "a type with only one possible value: empty". It also states that Carbon will have tuple types, and in the absence of any statement to the contrary, it is natural to assume that this will include()
, the arity-0 tuple type. In other words, our placeholder design calls for Carbon to have two built-in unit types, with no evident difference in meaning between them. This raises the question of what the relationship between these two types is. I can see a few possible answers:Void
and()
are distinct types that can be used in all the same ways. This would imply that()->()
and()->Void
are distinct function types, and so even if I know a function doesn't return anything, I still need to know which kind of nothing it returns before I can e.g. wrap it in the equivalent of astd::function
. This seems very unlikely to lead to good ergonomic outcomes.Void
is an alias for()
. This avoids the problems of the previous option, but does still force programmers to make an arbitrary choice between the two canonical spellings for this type, and force readers to internalize that the conspicuous syntactic difference between the two has no semantic significance. It could also cause confusion for programmers coming from C++, wherevoid
behaves very differently fromstd::tuple<>
.Void
and()
are distinct types, and support different usages. For example, we could follow C++ by saying thatVoid
can be the return type of a function, but not the type of a variable or constant. This might help mitigate the problems of the first option, by pushing programmers toward a consistent way of choosing between the two types. However, the restrictions that C++ imposes onvoid
have proven to have substantial drawbacks, with few offsetting benefits (if any).Alternatively, we could avoid this question by removing one of the two types from Carbon. Naturally, this could take one of two forms:
()
, and require tuples to have at least one element. I see this as roughly analogous to working in a number system that lacks zero, and I expect it to be about as unpleasant. To name just one consequence, this would require us to invent a novel syntax for defining and calling functions that take no parameters (perhapsf(Void)
?).Void
. There are probably drawbacks to this option, but I'm honestly struggling to come up with any.The text was updated successfully, but these errors were encountered: