language
language copied to clipboard
Function.apply unspecified
The static function Function.apply
is mentioned here and here in the language specification, but Function.apply
itself is never specified. We might want to specify it in a manner which is similar to the one given on the documentation page for Function.apply
, such that the language specification is self-contained in this respect.
(Note that Function.apply
needs to accept type arguments for the invocation as well as value arguments, and the documentation mentioned above is too old to include that).
We should not specify library methods in the specification. That leads to issues like identical
actually working differently depending on whether the arguments are compile-time constants or not.
We also do not specify int.+
or int.toString
in the language specification. They might seem obvious, but they aren't (q.v., Type.toString
).
I have a different view: we should specify this behavior (currently Function.apply
) in the spec. That allows implementations to reason about it and optimize it other than just calling a random library function. And it allows programmers to understand it at a deeper level, too.
Then the API docs for Function.apply
should refer to the behavior in the spec, rather than the other way around.
Specifying "function application" in the language specification should ... probably already be there. If we just refer to that directly, instead of mentioning Function.apply
in the specification at all, that's perfectly good. The Function.apply
can refer to the specification or not when it is defined.
It doesn't change that implementors must recognize Function.apply
in the platform libraries as something that requires platform support, it can't be written in Dart in either case. And since they do that, they can also already reason about and optimize the specified calls to avoid actually calling Function.apply
in he cases that you refer to, as long as the end result is the same (we do not specify the contents of stack traces, so omitting apply
from it is not an error).
Deeper understanding is good, though.
I think it makes sense to insist that the language specification be self-contained in this respect, but as Lasse mentioned this can be done without referring to Function.apply
. The specification just needs to have a specific concept for invocation that the rest of the language specification as well as the documentation of Function.apply
can use.
The phrase 'function invocation' is currently used to denote syntactic constructs as well as the semantic action, so it's not quite as precise as I'd prefer. But it shouldn't be so hard to get there.
Hmm. My general take is that anything which cannot be implemented in the language, is part of the language, and hence needs to be specified as part of it.
My general take is that anything which cannot be implemented in the language, is part of the language, and hence needs to be specified as part of it.
That would include the entire dart:mirrors
and dart:html
libraries, so the distinction probably needs to be less clear-cut than that.
To me, there is a platform (or more than one), and the language is part of the platform, not the other way around. So are the libraries, and the tools.
The platform chose to have a Function.apply
method, like it chose to have HTML and mirrors, it wasn't a "language" choice. And now the "dart4web" platform have chosen to not have mirrors.
Some parts of the language is defined in terms of the libraries or the platform, as requirements on the existence and meaning of types or methods. That's why we can say that an error throws a CastError
or NoSuchMethodError
(types that must exist, we don't actually say what they do). For classes extending Error
we even say that there must be a way for throw
to set the stack trace. For int
, we expect there to be a +
operator. We expect int.toString
and String.toString
to do something useful—it's not defined in the language specification, but it's hinted by the use of print
in examples.
The constants section is full of assumptions about what String
and num
operations do (at least we assume they don't have visible side-effects, so we can't tell when they are actually evaluated).
I would agree that the language defining its semantics in terms of Function.apply
is unnecessary, and we should fix it for that reason. The language is actually also defined in terms of the mirrors library (private symbols) and we need to fix that to make dart4web a valid platform.
There are necessary dependencies between language and libraries, in both directions, but we should avoid unnecessary ones.
I think the divergence has been reduced to a very small edit at this point: I'll write a CL on dartLangSpec.tex that introduces a semantic notion of function invocation, and that concept will be used in the two locations where the spec used to refer to Function.apply
. This takes Function.apply
out of the spec entirely.
If we then want to specify Function.apply
in the spec (because it can't be written in Dart, and it is concerned only with concepts that are in the language, as opposed to 'dart:html' which refers to external functionality) then we just need to add a single sentence somewhere. That new sentence would use the new semantic function invocation concept to specify what Function.apply
does. I can add or delete that sentence as many times as needed. ;-)
I'm not too hung up on this. Agreed that there is a fuzzy line in there - any time you have a foreign code interface you can step outside of the scope of what's otherwise implementable. I still feel like there's a very real distinction though between adding a library whose functionality requires an external implementation and adding static methods to a primitive type in the language. Function
is primitive to the language (you can't define subtyping without talking about it), and as such, it's odd to me that we delegate the method set and the semantics thereof to the libraries.
Future
is the same way to me - it's clearly part of the language, even if we want to pretend it's part of the libraries. :)
As I said, not too hung up on how this gets specified though.
I like the criterion that anything which (1) cannot be written in Dart, and (2) is "part of the language" should be specified.
Being "part of the language" is a little bit more tricky, but it could still be associated with the concepts that the language specification is already talking about (so function invocation is part of the language, but X Windows and browser DOMs are not).
But I think that's still compatible with an approach where semantic function invocation is specified explicitly, and the documentation for Function.apply
just refers to semantic invocation.