Skip to content

Can an external constructor have an initializing formal? #3516

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

Closed
eernstg opened this issue Dec 15, 2023 · 4 comments
Closed

Can an external constructor have an initializing formal? #3516

eernstg opened this issue Dec 15, 2023 · 4 comments
Labels
question Further information is requested

Comments

@eernstg
Copy link
Member

eernstg commented Dec 15, 2023

Thanks to @sgrekhov for bringing this up. Consider the following library:

class C {
  num x;
  external C(this.x);
}

This declaration is rejected by the common front end, based on the claim that external constructors cannot declare initializing formals. It is accepted by the analyzer. The specification does not provide any information about this specific situation.

In other words, it is not a breaking change to say that it is a compile-time error for an external constructor to have an initializing formal parameter. Also, it is not at all clear (to me) what the dynamic semantics would be.

In any case, there might be a useful and meaningful way to define what it would do, in which case we might want to specify that it is allowed.

@dart-lang/language-team, WDYT? I tend to think we should just specify that it is an error.

@lrhn
Copy link
Member

lrhn commented Dec 15, 2023

It should be an error.
It should also not be allowed to have super parameters

An external declaration is like an abstract declaration in that it doesn't specify implementation, only signature.

Unlike abstract declarations, it's not restricted to instance members, so it's not surprising that constructors is a case that has to be addressed directly, that's the only kind of declaration which doesn't exist as an instance member.

But its parameters should probably be just as restricted as a forwarding factory constructor.

@eernstg
Copy link
Member Author

eernstg commented Dec 15, 2023

Not even default values?

@lrhn
Copy link
Member

lrhn commented Dec 15, 2023

Not even default values.

Unless we allow those for external methods, then we should be consistent. Which we do.
(Or we should fix that too.)

So I guess we can allow default values as a legacy feature, but that default value has no effect. It's purely documentation.
It doesn't constrain the actual implementation to use the same default value, or any default value (an external natively implemented function can likely be made to detect whether an argument was passed or not, and not need a default value).

It would be more honest to not allow it.

Example, can run in DartPad:

import "package:js/js.dart";
@JS("console.log")
external int foo([int x = 2]);
void main() {
  foo(42); // Logs 42
  foo(); // Logs nothing, because `undefined` is ignore.
}

@eernstg
Copy link
Member Author

eernstg commented Jan 2, 2024

Closing:

The specification was updated in #3517. It is now an error for an external constructor to declare a formal parameter which is initializing (that is, a formal parameter declaration derived from <fieldFormalParameter>).

An implementation has been requested in dart-lang/sdk#54485.

@eernstg eernstg closed this as completed Jan 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants