Skip to content

Placement of type parameters in primary constructor syntax. #3082

Closed
@lrhn

Description

@lrhn

The (most recently) proposed syntax for primary constructors puts type parameters after the name of a named constructor:

// Allow `C.name` to occur together.
class C.name<X extends List<Y>, ... /*lots of stuff*/>(Y y) {...}

This has the advantage that C.name is easily findable and readable, and the constructor name is not split from the class name by a potentially large type parameter list.

However, it doesn't match the call site of the constructor, where type parameters go on the class name, and more worrisome to me, it would conflict with having generic constructors (#647) as primary constructors, where you would want to put a second type parameter list at that position.

I suggest putting the type parameters on the class name, same place they occur in non-primary-constructor classes, and place the named constructor identifier with the parameter list:

// Follow the constructor invocations.
class C<X extends List<Y>, ... /*lots of stuff*/>.name(Y y) {...}

That way the logic is that:

class Name<TypeParams> extends/implements... {
  fieldsForArgs;
  Name.foo(args);
  ...
}

can be rewritten as:

class Name<TypeParams>.foo(args) extends/implements... {
  //                  ^^^^^^^^^^  -- inserted part
  ...
}

which moves the part of the constructor after Name into the class declaration line, just before any extends or implements clause.

If we put the name before the type parameters, and the arguments after, it's instead:

class Name.foo<TypeParams>(args) extends/implements... {
  //      ^^^^            ^^^^^^  -- inserted parts
  ...
}

Not a big difference, but still slightly more complicated.

Both options have readability issues, because primary constructors stuff a lot of information into very little syntax, with some of it being used for more than one thing.
Some of those issue are avoided by plain constructors by not having type parameters in the declaration at all (but #1899 would allow that).

Metadata

Metadata

Assignees

No one assigned

    Labels

    brevityA feature whose purpose is to enable concise syntax, typically expressible already in a longer formprimary-constructors

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions