Argument matching
In strict code ("use strict") the number of passed arguments must match the number of expected arguments. This has been agreed upon.
I would expect that if too few arguments are passed to a function with a typed interface then you get a type error unless the missing parameter has a type that includes "undefined" (ie no conversion takes place). Signalling an error "because the function has a typed interface" is a variant, I guess, but it seems like an orthogonal concern.
I would expect excess arguments to typed functions to be ignored silently, as they can be picked up by 'arguments' inside the function.
Lars Hansen wrote:
I would expect excess arguments to typed functions to be ignored silently, as they can be picked up by 'arguments' inside the function.
Is there any possibility of making whether a function takes extra arguments part of its type? It seems kind of unfortunate not to be able to report an error when too many args are given, which is a pretty common mistake and usually indicates a bug.
There is a problem with that.
If it is an error to provide too many actual parameters to a function
with typed formal parameters, then you either must supply the correct
number of args or not type the args.
A use case that demonstrates the problem is the Array.some callback.
Usually it is supplied with only one argument -- the element. So if a
user declares this callback with type annotations, the call will fail
as the iterator must supply 3 arguments.
So you can't have a callback with just one typed argument for the
callback. You must either have one untyped arg or 3 typed arguments.
Michael
Comments below: On May 9, 2008, at 10:43 AM, Lars Hansen wrote:
In strict code ("use strict") the number of passed arguments must
match the number of expected arguments. This has been agreed upon.
I presume that is at execution time?
I would expect that if too few arguments are passed to a function with a typed interface then you get a type error unless the missing
parameter has a type that includes "undefined" (ie no conversion takes place).
See comment in following email about Array.some callbacks.
Signalling an error "because the function has a typed interface" is a variant, I guess, but it seems like an orthogonal concern.
I would expect excess arguments to typed functions to be ignored silently, as they can be picked up by 'arguments' inside the function.
I think this is the only approach that will work for standard mode code.
So for Array.some in strict mode, the user must supply 3 typed
arguments for the callback.
But in standard mode, they can either do that, or supply one untyped
arg.
I can't think of a better solution (yet).
Michael
The tests below in the RI were in standard mode. So that is an RI bug.
Michael
There are optional and rest arguments in ES4.
Regarding error reporting, strict mode is what gives you sane error checking (generally at run-time). Standard mode is for all you cowboys out there.
-----Original Message----- From: Michael O'Brien [mailto:mob at mbedthis.com] Sent: 9. mai 2008 11:09 To: Lars Hansen Cc: es4-discuss Discuss Subject: Re: Argument matching
Comments below: On May 9, 2008, at 10:43 AM, Lars Hansen wrote:
In strict code ("use strict") the number of passed arguments must match the number of expected arguments. This has been agreed upon.
I presume that is at execution time?
It is.
So for Array.some in strict mode, the user must supply 3 typed
arguments
for the callback. But in standard mode, they can either do that, or
supply
one untyped arg.
static function some(object:!Object, checker:Callable, thisObj:Object=null): boolean { for (let i=0, limit=object.length; i < limit ; i++) if (i in object) if (checker.call(thisObj, object[i], i, object)) return true; return false; }
The type of 'checker' used to be Checker:
type Checker = function (*, double, Object):boolean;
but that is painful in practice. The intrinsic instance method still requires a Checker, though.
Presumably what you're getting at is that if 'checker' is strict then it must accept three arguments even if we only care about one. This is so. The easiest way to write down a function like that is to use the rest parameter without a parameter name:
function f(obj, ...) { /* code here */ }
Presumably what you're getting at is that if 'checker' is strict
then it must accept three arguments even if we only care about one. This is
so. The easiest way to write down a function like that is to use the rest parameter without a parameter name:function f(obj, ...) { /* code here */ }
Agree, but that may have a performance penalty as the extra args must
be converted to an array. One case where strict mode may be faster
than standard ;-)
So that I can write up a bug for the RI, my take on the rules is:
-
In strict mode, the number and types of args must agree. If not, an
error is generated. -
In standard mode, you can supply too many actual parameters, they
will be ignored. If you supply too few, undefined will be
automatically supplied for the missing args.
The RI exhibits strict behavior in this regard in standard mode.
Michael
-----Original Message----- From: Michael O'Brien [mailto:mob at mbedthis.com] Sent: 9. mai 2008 11:49 To: Lars Hansen Cc: es4-discuss Discuss Subject: Re: Argument matching
Presumably what you're getting at is that if 'checker' is strict then it must accept three arguments even if we only care about one. This is so. The easiest way to write down a function like that is to use the rest parameter without a parameter name:
function f(obj, ...) { /* code here */ }
Agree, but that may have a performance penalty as the extra args must be converted to an array.
Why would they have to be converted to an array, if that array can't be referenced? :)
One case where strict mode may be faster than standard ;-)
So that I can write up a bug for the RI, my take on the rules is:
In strict mode, the number and types of args must agree. If not, an error is generated.
In standard mode, you can supply too many actual parameters, they will be ignored. If you supply too few, undefined will be automatically supplied for the missing args.
In my opinion, yes. But this has not been discussed extensively, and not for a long time, so others may have different understanding.
Types must agree in standard mode too, of course (at run-time).
I've only used named rest arguments
function f(obj, ...items)
I forgot you could do:
function f(obj, ...)
you're right - no overhead.
Another RI bug - that form won't work when you invoke it:
ERROR MachError: defining out-of-bounds temporary (near a.as: 5:4-5.3)
Michael
[+es3.x-discuss]
On Fri, May 9, 2008 at 10:43 AM, Lars Hansen <lhansen at adobe.com> wrote:
In strict code ("use strict") the number of passed arguments must match the number of expected arguments. This has been agreed upon.
Hi Lars, much as it pains me to raise this again, it has not been agreed upon. In order for ES3.1 strict mode to be a fail-stop subset of ES4 strict mode, I don't see how we could possibly agree on this. Please include es3.x-discuss on further discussion of this topic.
ES3.1 must define a language that depends only on features that will parse successfully on 3/4 of the current major browsers. Therefore, it cannot adopt ES4's notations for either optional or rest arguments. Instead, I have proposed that in ES3.1 strict mode, and therefore in ES4 strict mode as well:
-
If a function is invoked with fewer arguments than its declared parameters, the remaining parameters are bound to undefined. If an ES4 strict function wishes to reject calls with too few arguments, then it should declare undefined-rejecting types on these remaining parameters.
-
If a function is invoked with more arguments than its declared parameters, and if the function either mentions the magic name 'arguments' freely in its body or (ES4 only) declares rest parameters, then it is considered an unbounded arity function. Otherwise it is considered a bounded arity function.
-
If a strict bounded arity function is called with too many arguments, the call is rejected with a throw.
I would expect that if too few arguments are passed to a function with a typed interface then you get a type error unless the missing parameter has a type that includes "undefined" (ie no conversion takes place).
This should be the case for a strict function as well.
Signalling an error "because the function has a typed interface" is a variant, I guess, but it seems like an orthogonal concern.
Since ES3.1 has no typed interface, I will stay out of debates about the semantics of typed interfaces.
I would expect excess arguments to typed functions to be ignored silently, as they can be picked up by 'arguments' inside the function.
In loose mode, yes. It strict mode, only of 'arguments' is mentioned freely in the body of the function, or (ES4 only) if the function declares rest parameters.
On Fri, May 9, 2008 at 11:21 AM, Lars Hansen <lhansen at adobe.com> wrote:
There are optional and rest arguments in ES4.
Regarding error reporting, strict mode is what gives you sane error checking (generally at run-time). Standard mode is for all you cowboys out there.
As a separate matter, that has been raised by others as well:
Since both modes are to be specified by upcoming standards documents, can we adopt some term other than "standard" for the mode we'd like to discourage? I propose "loose".
Since both modes are to be specified by upcoming standards documents, can we adopt some term other than "standard" for the mode we'd like to discourage? I propose "loose".
I agree. But I think "lenient" sounds better.
Peter
or relaxed
On Mon, May 12, 2008 at 8:14 AM, Michael O'Brien <mob at mbedthis.com> wrote:
or relaxed
On May 12, 2008, at 8:10 AM, Peter Hall wrote:
I agree. But I think "lenient" sounds better.
I'm happy with either. I slightly prefer "relaxed". Both are better than "loose".
What should ES4 do when there are too many or too few arguments?
Seems that the RI will apply different behavior depending on whether
the function arguments are typed or not. This is not necessarily
unexpected. I just want to nail down the rules as the RI and AS3
behave differently in this regard.
Consider:
function fun(a, b) { print(a); print(b); }
Calling this with:
fun(1) prints 1 undefined
fun(1,2,3,4) prints 1 2
fun(1,undefined) 1 0
both work without error.
But if either arg is typed:
function fun(a: int, b) { print(a); print(b); }
In this case, the following all get TypeErrors
fun(1) fun(1, undefined) fun(1,2,3,4)
Interestingly, ASC will coerce "undefined" to 0 if supplied with the
correct number of arguments and they are typed as ints.
What are the rules for ES4?
correct number and type of actual parameters
too many arguments
Michael