-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[sdk] class called "Function" does not conform to the spec. #52594
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
I'd say that this is all specified and working as intended. Checking the programs in #45703, every attempt made in those programs to declare a type named It is not a problem that there is a declaration in a platform library that introduces a type named Platform libraries break rules in many other cases. For instance, the number classes
This is also not a problem: Any tool can re-categorize a syntax error to be a compile-time error that isn't a syntax error, which might be done in practice because that turns out to be a useful implementation. This typically occurs because it is easier to get good error recovery from a parser which is broader than the specified grammar indicates (so we're reporting fewer things as syntax errors, thus accepting more programs), as long as the texts (that is, wannabe-programs) that are syntax errors according to the grammar will then be rejected with some other compile-time error. So it's OK for the analyzer parser to parse
|
Note: The issue description contains an incorrect link to the Function interface. The link refers to a Function "patch" the actual interface that users are exposed to is here function.dart.
The SDK appears to try very hard to hide this fact from users via its "patch" mechanism. The Function declaration is not hidden from users in any way. If they "go to implementation" they are exposed to a declaration that is not valid Dart syntax and according to the spec, extending syntax is not allowed. Do you consider the declarations (including any interfaces) in dart:core (before any patches have been applied) to be platform libraries and so they can deviate from the spec?
The grammar snippets in the spec contain the following productions:
and they can be used to derive "external const factory ..." Furthermore, the spec says:
and In what way is
I've also noticed that
Thank you, I agree. It would be nice if the analyzer could report issues like that as syntax errors, but of course, it doesn't have to. |
Certainly, yes. That's also consistent with the use of the term 'system library' that the language specification uses (we have used 'platform library' in many discussions, but the correct term according to the spec is 'system library', so I should have said 'system library' whenever I said 'platform library'). In any case, a system library does not exist in order to demonstrate spec compliant code, it exists in order to support the implementation of a set of Dart processing tools. Dart the language has a number of atomic elements (entities that cannot be expressed in Dart and hence are pre-defined), and they need to be provided by an implementation of Dart. If that's convenient to do by having a declaration like It is simply not useful to insist that system libraries cannot contain code which is given exceptional treatment by the tools (in particular, the code can be a compile-time error according to the specification, or the code could behave in a completely different way according to the specification). The reason why such code exists is exactly that some elements of Dart cannot be written in Dart (as is true for every language except the untyped lambda calculus).
That is true, but you can also derive The external const factory is actually an interesting example, because the mechanism whereby an external declaration is bound to an actual foreign function is implementation specific. (Haha, caught myself on the wrong foot there! ;-) However, the support for the That said, I doubt that any tool will support
The syntax that introduces the identifier This is so because the analyzer/compiler/... are treating the So we're violating the rules of Dart when compiling/analyzing 'dart:async' just because that declaration of |
The spec refers to the documentation of the 'built-in class In short, you can read the actual source code in system libraries, but it doesn't tell you anything because any tool could presumably give any part of it an exceptional treatment, as long as they implement Dart in a conforming way. |
Thank you for the clarification and taking the time to provide a detailed explanation. I agree with your reasoning here and this seems to be working as intended, so I'm going to close this issue. |
Another symptom of this hack can be found in the following program: @Function.id()library; Which is parsed by the analyzer without any errors, but rejected by DSP as a syntax error.
I think it would be nice to try to keep the analyzer and DSP in-sync with respect to syntax errors to make it easier to maintain consistency across different artifacts. |
In general, it's not a problem that a tool uses an approach to parsing which is somewhat different from the specified grammar, as long as it accepts the same programs. For example, it may be useful to parse some constructs differently because it allows for better recovery or more informative error messages. This means, for example, that the analyzer and other tools can parse a syntactically bigger language and then report the failure as a non-syntax error in a later phase, even though it is specified to be a syntax error. A term like However, The analyzer makes the choice to parse a language which is a bit bigger than the specified one, and report a compile-time error later on for It's a matter of handling opposing forces: The language specification specifies a grammar whose rules are intended to be concise and comprehensible, and the tools implement a parser plus some non-syntax errors to accept the specified language precisely, while allowing for good feedback to developers. In this balancing act it is not considered a problem that some errors are syntax errors according to the specification, but they are reported as non-syntax errors by a tool. Consistency is good, but I'm not convinced that it would be a better trade-off to have a much more verbose specification (because it specifies a bunch of "syntax" errors in natural language along with the regular grammar rules), nor that it would be a better trade-off to insist that the tools cannot use this technique of "using a more permissive grammar, then filtering out 'syntax' errors using non-syntax error messages". |
@eernstg First of all, my goal is to prevent us from having to observe accidents like the following: I would like to see the language team be the ultimate authority on what is valid Dart syntax because they should know best how to prevent Dart from having undesirable properties. I'm currently observing the following:
Libraries that ship with the SDK are expected to adhere to Erik, I want to be clear that I do not think that the spec should start dealing with error recovery. Consider the following example which is a program where no error recovery is needed, e.g.: void main() {
Function.apply(() => 0, []);
} Any implementation (or IDE, or static analyzer, or any other tool that attempts to resolve Dart programs) needs to be able to parse In practice, any desirable language properties that the language team is able to guarantee for So I guess what I'd like to see is have Are there perhaps any issues that I'm not anticipating with having system libraries be required not to extend the syntax specified by the spec? |
I'd very much like to avoid that, too. However, we have a history, and the desire to obtain a syntactic universe that is smoothly expressed as the language derived by a context free grammar (or any other simple and beautiful mathematical object) must be balanced against the need to include earlier versions of the same language (that is, the need to avoid breaking changes). Another force that matters is the desire to have specific forms for specific constructs, e.g., using So we're not going to have the luxury of defining anything (including the grammar) from scratch, and we'll have to live with a certain amount of exceptions to the beautiful and simple rules that we would otherwise be able to have. That's basically the reason why Dart as a language has a number of rules that seem to be inconsistent or less mathematically beautiful than we'd prefer. Next, I don't think it's useful to think about Dart as a multi-version language ( In particular, for a declaration like This declaration has very special properties (e.g., every function type is a subtype of Another special exception for the declaration of Rather than saying that the system libraries are written in a different language, we should say that the system libraries are implemented in some way that may or may not involve a certain amount of Dart source code, but that Dart source code, if any, may be given a non-standard semantics anywhere and in any way that suits the implementors because the tools and the core libraries are delivered as a whole (so that the compiler etc. can "know" about the special properties of (Alternatively, everything which isn't expressible in Dart source code could be written in some other language, e.g., assembly.) This means that you can almost read the Dart source code in the SDK as Dart libraries, but the tools are free to make exceptions for anything anywhere, as long as this provides a system that makes user libraries written in Dart behave as specified. I think this situation is unavoidable for a practical language: They all need primitive features (things that we can't write in the language itself, but which are provided by "system libraries" of some sort). and they probably all want to use the target language to express the standard libraries because almost everything has the standard semantics. It's simply convenient to write the Dart SDK in Dart (with exceptions). I'd recommend that you just stop worrying about exceptions in the system libraries. They are there, they are needed, but they don't generalize meaningfully to a separate language. |
I may have been a little ambiguous about the perspective that I am looking at this from. @eernstg You have rightfully assumed a broader view than I intended. My statements were only meant to comment on the fact that system libraries are free to make syntactic exceptions. I don't worry about any differences or exceptions related to, e.g., resolution, type inference or type checking. It seems to me that what I'm proposing, a unified grammar for user libraries and system libraries, is not something that is incompatible with the constraints that you've provided, or any other constraint that I can think of. I can't quite pinpoint the exact cause of our disagreement here, so how about a more concrete proposal for the changes that I would like to see:
Should the need for custom syntax in system libraries come up, then that syntax would have to become part of the spec, and be reviewed by the language team. What do you think? |
While we try to make platform libraries be written in Dart, nothing requires them to be. It's just convenient, because we have way to execute Dart code already, and a way to gather documentation from Dart code, and most of the time the source code is a good representation of what the library feature actually does. There are exceptions. Not many, but not zero.
Those are the major places where source declaration does not (necessarily) match what is actually being exported. |
About:
Saying that is useless. If a file contains something that is not allowed by the Dart specification, it is by definition not a Dart file. A language specification defines a set of valid Dart programs. Anything outside of that is just not Dart, and therefore not something the Dart specification has any mandate over. |
@lrhn, I think the topic here is slightly different: The question is whether or not it's OK to have a declaration like class Function ... {...} in the SDK, given that My response is that there is no obligation for a system library to satisfy all the rules of Dart. In fact, every tool in the tool chain associated with this SDK can give an exceptional (that is, rule breaking) treatment for any single declaration in the SDK, if needed. In fact, nobody promises us that there even is any Dart source code that is used to provide the services expected from the system by any Dart library. For example, nobody promises us that The implication is that no tools can immediately be expected to work on Dart system libraries, just because they are working on all non-system Dart libraries: they may need to give a bunch of system library declarations special treatment. That special treatment isn't specified in any language specification documents, because they are concerned with the meaning of non-system libraries. However, the language specification documents do specify how entities like the classes @modulovalue, if you think I've misrepresented the discussion then please add in your perspective as needed! |
I'll close this issue: We do not plan to require every library in the SDK to conform to the rules of the Dart language. Those libraries contain specific declarations whose semantics cannot be written in Dart, and hence they must at times violate the rules that every user-written library must satisfy. The fact that the class Similarly, the declaration of the class This does not mean that the rules of the language are fuzzy in any user-written libraries, they must still follow all the rules. |
The Dart SDK introduces new syntax in its core library by shipping a class called "Function". "Function" is not a valid type identifier and so, according to the specification, a class can't be named "Function". The conformance section in the spec explicitly disallows new syntax.
Furthermore, the analyzer parses classes with a "Function" name without syntax errors, while the ANTLR-based spec, as expected, emits an error for the following program:
It seems to me that this "hack" exists for UX-related reasons (to e.g. allow the "Go to implementation" feature in IDEs to resolve to an actual "thing" instead of making "Function" act like a keyword-like construct).
I think that this is helpful, but I also think that conforming to the spec without such "hacks" would also be good.
(This "hack" seems intentional and there's probably nothing surprising here. I just couldn't find an issue that captures this exact observation.)
Cf. #45703 which seems to have dealt with disallowing users from defining custom classes called "Function" (but the SDK still ships new syntax that doesn't conform to the spec).
The text was updated successfully, but these errors were encountered: