Open munificent opened 1 year ago
It should be class D<T>.named(int x);
!
I feel current specification reasonable. because,
class D(int x);
, D
is the name of constructor, but not that of the class.class D.named(int x);
, D
is a part of the name of the constructor, as well.
- In case of
class D(int x);
,D
is the name of constructor, but not that of the class.
It's the name of the class, at least according to how the spec reasons about this. The constructor doesn't have a name in this case. (If it were the name of the constructor, then D
would be a constructor tear-off, but it isn't. It's a type literal for the class D
.)
- Type parameters of functions should be just after the name, but not in the middle of the parts of that.
But the type parameters are not on the function, they are on the class.
- Constructors doesn't have type parameters separated from those of the class.
Not currently, but this a long-running feature request: #647.
- Unnamed primary constructor couldn't have type parameters separated from those of the class, anyway.
They can. We anticipated that when adding constructor tear-offs by letting you write .new
for the unnamed constructor. So if you wanted to have a generic unnamed constructor, you could define it like:
class C {
C.new<T>() { ... }
}
This was a dilemma.
As proposed, the constructor name is shown (so it's readable and searchable). If the class is generic then the type parameter list needs to go somewhere, and I put it after the complete constructor name. Of course, this conflicts with the constructor invocation syntax, but it is arguably similar to the current constructor declaration syntax (for those, there is no type parameter list, so we never have anything between the class name and the other half of the name of a named constructor).
We could also simply make it a syntax error to have both a type parameter list and a named primary constructor at the same time.
This means that the primary constructor will also have to be the "nameless" one in a generic class. In return, we won't ever have this funny configuration where the constructor name has a (perhaps long) type parameter list in the middle.
Another possibility is to say that the type parameter list goes in the same position as in the constructor invocations, and we don't care that a constructor named C.name
is shown as C<Lots, Of, Stuff>.name
in the declaration.
I don't have a strong opinion here.
Another possibility is to say that the type parameter list goes in the same position as in the constructor invocations, and we don't care that a constructor named
C.name
is shown asC<Lots, Of, Stuff>.name
in the declaration.
This is what I prefer, definitely. Users are always apparently entirely comfortable reading code like List<SomeLongType>.filled(value)
, so I don't think there's anything wrong with the class declaration syntax being similar.
Ok, now I agree with @munificent ,
I'm strongly for Name<TypeArgs>.identifier(args)
, and strongly against Name.identifier<TypeArgs>(args)
.
There are pragmatic reasons too, like being prepared for generic constructors, but mainly the latter just looks like a mistake.
It doesn't match anything in the language, except the time we mistakenly allowed you to write List.filled<int>(...)
as well as List<int>.filled(...)
. That was a parser bug, and we fixed it.
NUXI
Cool, let's do Name<TypeArgs>.identifier(args)
!
The proposed syntax for a generic class with a named primary constructor (#3023) is:
It feels to me like it should be:
The type parameters are a property of the class itself, not the constructor. The syntax for invoking a named constructor on a generic class is:
Also, if we ever want to support generic constructors, we may find ourselves wanting to allow: