-
Notifications
You must be signed in to change notification settings - Fork 62
defaulted type parameters #3469
Comments
[@gavinking] Note that the absolutely best thing about this feature is that it can be completely implemented by me fucking with the typechecker. It does not require anything new in the backend at all. :-) |
[@RossTate] I can't see any problems with this provided we don't require constraints on type parameters to hold for a type to be valid (only required when one allocates or extends a type), otherwise you'll need the defaults to fit with the variance to prevent confusing situations. |
[@gavinking] > otherwise you'll need the defaults to fit with the variance to prevent confusing situations. I don't understand this. Example? |
[@RossTate] Actually, I thought of an example of a slightly different problem. It's off the type of my head, so it's by no means a practical example, but hopefully it'll illustrate the concern.
Now As for the original problem, say I had this weird class:
There are no explicit constraints on |
[@gavinking] > Nothing unsound here; it's just weird. Yeah, a little strange, but to be honest I'm not very bothered by it.
Apparent subtype, you mean? Well, again I guess I'm not bothered by this. |
[@RossTate] Cool with me. Just figured I should let you know, heheh. |
[@gavinking] > Cool with me. Just figured I should let you know, heheh. Yes, nice to not be caught by surprise by these things later on ;-) |
[@gavinking] So I just realized that this problem can pretty much already be solved using type aliases, without introducing new syntax. We could define:
The question is: is this the only place where we're really going to want to do stuff like this, or are default type arguments sufficiently generally-useful that we should have 'em anyway (they're easy enough to add). P.S. This exposes an irregularity in the language. Type aliases let me partially apply a type constructor to a type argument. But I can't do the same with value-level functions. I can't write:
Of course I can write:
But that's somehow not quite the same thing... (i.e. we have ML's syntax at the type level, and C's at the value level.) |
[@gavinking] So if we wanted to resolve this irregularity in a truly consistent way, I would take the fashionable route of languages like coffeescript and use a fat arrow here:
And at the type level:
i.e. Not sure how you guys are going to react to the idea. |
[@RossTate] I'm not sure what irregularity you're talking about here. Partial application surely isn't the difference, since an alias can do anything. For example, |
[@gavinking] @RossTate the irregularity is that a type expression
is a type error. To be consistent with the syntax for type aliases, it should be acceptable and FTR, this irregularity in the semantics of |
[@RossTate] Got it. I wouldn't use lazy evaluation to explain it then. |
[@gavinking] Of course, the other path to resolve the irregularity is to disallow the following, which I personally like:
Instead giving you the choice of:
This is the path that languages like ML go down, and is also the traditional syntax in mathematics. I don't think it's quite as nice in Ceylon where you have named arguments, defaulted parameters, and sequenced parameters, but it's worth reconsidering in light of the discussion about the syntax for type aliases. |
[@gavinking] Oh and an especial problem with the ML-style syntax is forward declaration/named arguments. The following doesn't look remotely right:
Nor does this:
Going down that path, you would have to write:
and:
It's not nice that you wind up declaring the parameters twice here. I think that's the real reason I originally decided to go down the path we went down. With our syntax we have the convenience of being able to write:
And:
OTOH, we can't write this:
We have to write either:
or:
A |
[@RossTate] I wouldn't call that ML-style syntax. I'm also not sure why the declarations are separated from the definitions. |
[@gavinking] > I wouldn't call that ML-style syntax. What is ML-style is that the parameters of the function are in scope on the RHS of
That's something you quite commonly do in Java-like languages.
|
[@gavinking] FTR, I just remembered that Dart went down the path of fat arrow |
[@gavinking] Hrm, this runs into the same problem that prevents us from using inferred type arguments in The typechecker needs to assign all static types that occur in a "LHS-like" location in a single phase. (Or arbitrary phases would be required.) So if I'm not mistaken, we can't have defaulted type parameters... |
No, that's nonsense (it was late). It can surely be implemented by substituting default arguments "lazily". |
[@gavinking] Wow, this one is a lot harder than it looks. I got quite far in implementing it here: ceylon/ceylon-spec@sequential...defaulttypeargs Unfortunately to complete this implementation, I would have to completely rework how union/intersection type canonicalization works (it would have to happen lazily). I'll take a look at this when I get a chance, but if it's not "easy", I'll leave this issue for 1.1. |
[@gavinking] OK, so now that #3566 is resolved, this one is back in play! Indeed, it seems that I've now got it working, in just a few minutes work. |
[@gavinking] So in order to cleanly fix #3638, I need to clean up the mess of |
[@gavinking] This is implemented in the branch and seems to be working. (I guess it could still use some further testing though.) |
[@gavinking] In #4995, @ikasiuk proposes to introduce defaulted type parameters as a great way of eliminating
ContainerWithFirstElement
. In the past this is something I've suggested in conversations with @RossTate as a kind of alternative to virtual types. I think we should do it.The syntax is clear:
There is a little redundancy here, in that the default arg is likely to almost always be the upper bound on the type parameter. But we don't want to get into the stuff Java has with implicitly inferring the upper bound from the constraint (that has decidability problems).
An open question is: are the default type arguments allowed to refer to previous type parameters in the list, for example:
To me that seems reasonable, but we probably don't need it for now.
[Migrated from ceylon/ceylon-spec#363]
[Closed at 2013-01-10 18:30:26]
The text was updated successfully, but these errors were encountered: