Skip to content
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

Allow constructors with a dotted name to omit the class name #4144

Open
eernstg opened this issue Oct 29, 2024 · 5 comments
Open

Allow constructors with a dotted name to omit the class name #4144

eernstg opened this issue Oct 29, 2024 · 5 comments
Labels
brevity A feature whose purpose is to enable concise syntax, typically expressible already in a longer form enhanced-syntax Used with proposals about improvements of the Dart grammar small-feature A small feature which is relatively cheap to implement.

Comments

@eernstg
Copy link
Member

eernstg commented Oct 29, 2024

For brevity, we could allow constructor declarations whose name has two parts separated by a period (as in C.named) to omit the first part, that is, the class name.

For example:

class A1 {
  A1.named(); // Today.
}

class A2
  .named(); // Possible with this feature; means `A2.named();`.
}

This allows for slightly more concise constructor declarations, especially when the class name is long. Note that we can use this feature also with constructors whose name doesn't (necessarily) have two parts:

class B1 {
  B1(); // Today.
}

class B2 {
  .new(); // Possible with this feature; means `B2.new();` and `B2();` (same thing).
}

Here is a longer example, inspired by #4135:

abstract class EdgeInsetsGeometry {
  const .new();

  // Forward to EdgeInsets:
  const factory .fromLTRB(
    double left,
    double top,
    double right,
    double bottom,
  ) = EdgeInsets.fromLTRB;

  const factory .all(double value) = EdgeInsets.all;

  const factory .only({
    double left,
    double top,
    double right,
    double bottom,
  }) = EdgeInsets.only;

  const factory .symmetric({
    double vertical,
    double horizontal,
  }) = EdgeInsets.symmetric;

  static const zero = EdgeInsets.only();

  // Forward to EdgeInsetsDirectional:
  const factory .fromSTEB(
    double start,
    double top,
    double end,
    double bottom,
  ) = EdgeInsetsDirectional.fromSTEB;

  const factory .onlyDirectional({
    double start,
    double top,
    double end,
    double bottom,
  }) = EdgeInsetsDirectional.only;

  const factory .symmetricDirectional({
    required double horizontal,
    required double vertical,
  }) = EdgeInsetsDirectional.symmetric;

  const factory .allDirectional(double value) =
      EdgeInsetsDirectional.all;

  static const zeroDirectional = EdgeInsetsDirectional.only();
}

If we combine this proposal with #4135 then we get the following:

abstract class EdgeInsetsGeometry {
  const .new();

  // Forward to EdgeInsets:
  const factory .fromLTRB = EdgeInsets.fromLTRB;
  const factory .all = EdgeInsets.all;
  const factory .only = EdgeInsets.only;
  const factory .symmetric = EdgeInsets.symmetric;

  static const zero = EdgeInsets.only();

  // Forward to EdgeInsetsDirectional:
  const factory .fromSTEB = EdgeInsetsDirectional.fromSTEB;
  const factory .onlyDirectional = EdgeInsetsDirectional.only;
  const factory .symmetricDirectional = EdgeInsetsDirectional.symmetric;
  const factory .allDirectional = EdgeInsetsDirectional.all;

  static const zeroDirectional = EdgeInsetsDirectional.only();
}
@eernstg eernstg added small-feature A small feature which is relatively cheap to implement. enhanced-syntax Used with proposals about improvements of the Dart grammar brevity A feature whose purpose is to enable concise syntax, typically expressible already in a longer form labels Oct 29, 2024
@hydro63
Copy link

hydro63 commented Oct 29, 2024

Seems like duplicate / very similar to #3788.

@mateusfccp
Copy link
Contributor

Not a duplicate, both try to solve the same "problem" but with different approaches.

@tenhobi
Copy link

tenhobi commented Oct 29, 2024

I am thinking whether discussed syntax from #357 (lets say padding: .(top: 3) vs padding: .new(top: 3)) would also work here, aka ommiting new like this:

class B3 {
  .() {
    // code here...
  }
}

@hydro63
Copy link

hydro63 commented Oct 29, 2024

Not a duplicate, both try to solve the same "problem" but with different approaches.

I wouldn't really say they use different approaches, they only slightly differ in their syntax.
Here is the comparison of proposed syntax (1st is #3788, 2nd is this issue).

const(this.x);
const .new(this.x);

const.name(this.x);
const .name(this.x);

new(this.x);
.new(this.x);

new.name(this.x);
.name(this.x);

factory.new(int x);
factory .new(int x);

factory.name(int x);
factory .name(int x);

const factory(int x);
const factory .new(int x);

const factory.name(int x);
const factory .name(int x);

I would be happy with either syntax, as long as i don't have to constantly write the class name.

I am thinking whether discussed syntax from #357 (lets say padding: .(top: 3) vs padding: .new(top: 3)) would also work here, aka ommiting new like this.

I'm not sure about that, imo it is a bit too short and difficult to spot. I don't find the benefit of using .() instead of .new(), when it's only 3 characters. In fact i actually like that i can easily notice and understand .new() without ever seeing it before.

@eernstg
Copy link
Member Author

eernstg commented Oct 30, 2024

@hydro63 wrote:

Seems like duplicate / very similar to #3788.

It is true that these two proposals have very similar outcomes in many situations. The main difference is that the proposal in this issue is an extremely simple change: Just allow the class name to be omitted from constructor declarations with a two-part name. #3788 is more like a complete reconstruction of the constructor declaration syntax.

#3788 does allow for an even more concise form in some cases (like const(); where this proposal has const .new();).

So you might say that #3788 is the highly optimized version, and this proposal is the easy way to get to very nearly the same level of conciseness.

It could be argued that both of these proposals fail to provide a clear signal saying "this is a constructor". For example, neither const.name(); nor const .name(); contains any single syntactic element that clearly sends this signal. In contrast, a keyword like constructor (right, it's too long ;-) or even new could send this signal, and today's syntax uses the class name to send this signal (at least, I'm convinced that I'm using this reading technique all the time: "Oh, that's the class name, so this is a constructor").

However, both proposals could rely on the . as the definite signal saying "this is a constructor". This is a very small visual signal, and something we'd have to learn in order to make it work immediately and automatically. But I'm sure we can get used to that. It does make sense, based on the fact that the following was always true: The name of a member declaration is an <identifier>, except that constructors can have a name of the form <identifier> '.' <identifier>.

This could be taken as an argument in favor of making the . very visible. Also, a frequent occurrence of .new(...) could help reinforcing the connection between constructors and the leading (prominent) period.

In contrast, it could be claimed that const.name(); simply looks "more normal" than const .name(); because we're already very familiar with terms of the form <identifier> '.' <identifier>, written without spaces. However, I just don't think const.name is a semantically well motivated construct. We aren't declaring anything named const.name here, we're applying the const modifier to the entire declaration. Similarly for const factory.name etc.

All in all, I do think this proposal has some useful properties, in spite of the fact that #3788 is more concise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
brevity A feature whose purpose is to enable concise syntax, typically expressible already in a longer form enhanced-syntax Used with proposals about improvements of the Dart grammar small-feature A small feature which is relatively cheap to implement.
Projects
None yet
Development

No branches or pull requests

4 participants