language icon indicating copy to clipboard operation
language copied to clipboard

Function.apply unspecified

Open eernstg opened this issue 7 years ago • 9 comments

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).

eernstg avatar Feb 28 '18 13:02 eernstg

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).

lrhn avatar Feb 28 '18 13:02 lrhn

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.

kmillikin avatar Feb 28 '18 14:02 kmillikin

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.

lrhn avatar Feb 28 '18 14:02 lrhn

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.

eernstg avatar Feb 28 '18 15:02 eernstg

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.

leafpetersen avatar Feb 28 '18 20:02 leafpetersen

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.

lrhn avatar Mar 01 '18 09:03 lrhn

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. ;-)

eernstg avatar Mar 05 '18 09:03 eernstg

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.

leafpetersen avatar Mar 06 '18 00:03 leafpetersen

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.

eernstg avatar Mar 07 '18 15:03 eernstg