-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[patterns] Function pattern inconsistency between implementation and spec. #54246
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
Comments
Good catch! The implementations (the analyzer as well as the common front end) do already support a pattern of a form like I created a PR that introduces support for this construct into the grammar: dart-lang/language#3496, and a spec_parser update: https://dart-review.googlesource.com/340181. |
Not sure we should allow it, actually. We generally say that when Allowing I'd rather that we made it an error to write |
I don't think we've specified a rule of that nature. We did discuss the need to disambiguate, but I think we concluded that it wasn't needed, and I can't immediately find anything like a specified disambiguation mechanism. Also, Dart.g doesn't have any special treatment of Next, in an object pattern like So we may be able to say that |
I'd prefer Dart not to support constructs that essentially add no value. As Lasse said, such a Function objectPattern isn't useful, and I agree. The ability to extend In system libraries, the implementation already ignores the fact that classes can't be called |
I can follow that, but I'm not convinced that it is a good idea to create exceptions in order to avoid having support for certain things, just because they appear to add little value. We allow Note that we can always emulate typedef MyFunction = Function;
void main() {
Object? x = print;
switch (x) {
case MyFunction(): x('Hello again!');
case Enum(): print(x.index);
case var other: ...;
}
} |
That exception already exists for typedef MyVoid = void;
void main() {
switch (0) {
// Not supported
// case void(): print("print");
// Supported
case MyVoid(): print("foo");
}
} But I'd also argue that it's not really an exception. A Do we already have type patterns? Yes. dynamic is not a type identifier, but a type: void main() {
switch (0) {
case dynamic(: final isEven): print("${isEven}");
}
} So either way, I think we can't remove or not introduce any exceptions unless we remove support for dynamic patterns & Function patterns, or keep Function patterns and add void patterns. That is, either support all identifier-based types as patterns or only typeIdentifier-based patterns.(*)
That seems to be the case, but future language changes could introduce syntax that would make it difficult to parse in the future. * dynamic is a typeidentifier today, but identifiers and types can be simplified significantly by making dynamic a type and not a typeIdentifier. I plan to open an issue for that in the future |
It is true that
Well, I think a pattern like In contrast, SomeType foo(Object arg) => switch (arg) {
case Function(): ...; // Deal with functions.
case String(): ...; // Deal with strings.
... // Deal with other things.
}; This works today. I'm just saying that I don't think it's going to be an improvement for anyone if we turn that usage into a compile-time error. Granted, you would only encounter this kind of code in a "rather dynamically typed" library, because we won't know anything about which kind of function we're working with unless we proceed to test For me, this points in the direction of preserving the support for |
I agree that it makes sense to support enumerating all semantic-types (and not necessarily all syntactic-types) as patterns and that, in that sense, not supporting Function patterns would be a clear exception. I think that this kind of consistency is more valuable than the one I was going for. I agree with keeping Function patterns and adjusting the spec to add support for them. |
@modulovalue, that sounds good! @lrhn, do you still stand by this?:
|
I do. Whenever you see It's the design rule of "similar syntax means similar things".
If we managed to actually disallow it in patterns, and not allow it by accident, we should hold onto that. |
OK, so |
Hello, again 😃
Consider:
On DartPad, it prints
foo
and terminates successfully. However, it looks like the spec does not intend for that to be possible.Function
is not a typeIdentifier so objectPatterns do not describeFunction()
and there's no other pattern that explicitly introduces Function patterns.The text was updated successfully, but these errors were encountered: