Re: Handling too few arguments in method calls

2009-06-26 Thread Jonas Sicking
On Thu, Jun 25, 2009 at 6:13 PM, Cameron McCormackc...@mcc.id.au wrote:
 Darin Adler:
 What about too many arguments, and ignoring extra ones? Is that
 settled?

 It seems consistent with current implementations to ignore extra
 arguments.  That approach might go against the desire to maximise the
 freedom API designers have to add additional overloaded operations
 later, though.

Yeah, ideally I would want to treat too many arguments the same as too few.

However I'm more concerned about breaking existing content here if all
commonly used UAs consistently ignore them.

I would be willing to give it a try though, or at least once I've
checked with the appropriate people that that is easily testable in
gecko.

/ Jonas



Re: Handling too few arguments in method calls

2009-06-26 Thread Cameron McCormack
Jonas Sicking:
 Yeah, ideally I would want to treat too many arguments the same as too few.
 
 However I'm more concerned about breaking existing content here if all
 commonly used UAs consistently ignore them.
 
 I would be willing to give it a try though, or at least once I've
 checked with the appropriate people that that is easily testable in
 gecko.

That’d be great.  I’d much rather make an informed decision here than
just guess.

-- 
Cameron McCormack ≝ http://mcc.id.au/



Re: Handling too few arguments in method calls

2009-06-25 Thread Cameron McCormack
Cameron McCormack:
  From some very brief testing, it seems that Firefox and Opera tend
  to throw an exception when calling a method with too few arguments,
  while IE, Safari and Chrome will assume that the missing arguments
  were the undefined value.

Simon Pieters:
 Hmm. What did you use as test case?

I did calls like:

  HTMLCollection.item()
  HTMLCollection.namedItem()
  HTMLDocument.getElementsByName()
  HTMLDocument.getElementsByClassName()
  Document.getElementById()
  Document.createTextNode()

making sure I could distinguish between that behviour and the behaviour
I’d get if calling with (undefined).

 I think I prefer option 2. It's easier for authors to find their mistake. 
 If a spec author wants the behavior of option 1, then that's possible 
 with [Optional].

I tend to prefer option 2, as well, for those reasons, plus it might
help us if we introduce new overloadeded operations later.  For example,
if we had

  interface A {
/* f1 */ void f();
/* f2 */ void f(in boolean x, in boolean y, in boolean z);
  };

and authors were calling A.f(something) and getting f2, then it might
make it harder for us to introduce

  void f(in boolean w);

or even

  void f(in DOMString w);

later on.

-- 
Cameron McCormack ≝ http://mcc.id.au/



Re: Handling too few arguments in method calls

2009-06-25 Thread Darin Adler

What about too many arguments, and ignoring extra ones? Is that settled?

-- Darin




Re: Handling too few arguments in method calls

2009-06-25 Thread Cameron McCormack
Aaron Boodman:
 But there is also an issue of legacy code. I brought this issue up in
 a webkit bug awhile ago, and one concern from the webkit developers
 was that introducing an exception would almost certainly break
 sites. My opinion is that those sites are almost certainly already
 broken.

I would worry about that, too.  The amount of brokenness it experiences
because of a change to using exceptions could be far greater than it is
currently.

 As a simple example, consider the setAttribute() method. Both
 arguments are required, but in WebKit, if you don't pass either value
 it is coerced to string. So if we take a simple attribute like
 title:
 
 someElement.setAttribute(title);  // throws in Firefox, sets title
 to undefined' in WebKit
 
 Philosophically, I want to say that pages that are passing too few
 arguments to DOM APIs are already broken, just in less obvious ways.
 Breaking in more obvious ways would be better.

So we could change this to be:

  interface Element {
void setAttribute(in DOMString name, [Optional] in DOMString value);
…
  };

to keep setAttribute(title) working, but I think making the
optionalness of the argument to other language bindings in this case
isn’t a good idea.  Also in this particular case it doesn’t seem like it
would be needed for web compatibility, if Firefox and Opera can get away
with throwing here.

If there’s a real need to allow some arguments on particular operations
in ECMAScript to be optional, and coerced from an undefined value, then
we can introduce an ECMAScript-specific extended attribute that permits
this.  But in general I agree that it would be better if we could remain
strict.

-- 
Cameron McCormack ≝ http://mcc.id.au/



Re: Handling too few arguments in method calls

2009-06-25 Thread Cameron McCormack
Darin Adler:
 What about too many arguments, and ignoring extra ones? Is that
 settled?

It seems consistent with current implementations to ignore extra
arguments.  That approach might go against the desire to maximise the
freedom API designers have to add additional overloaded operations
later, though.  If we had

  interface A {
void f();
  };

and for whatever reason authors sometimes called it with an argument,
then it might make it harder to update the interface to

  interface A {
void f();
void f(in float x);
  };

later on.  I have no idea how common it is for authors to pass too many
arguments to web APIs.

-- 
Cameron McCormack ≝ http://mcc.id.au/



Re: Handling too few arguments in method calls

2009-06-25 Thread Cameron McCormack
Oliver Hunt:
 There's also overloaded functions like (for example)  
 CanvasRenderingContext2d.drawImage
 void drawImage(in HTMLImageElement image, in float dx, in float dy,  
 [Optional] in float dw, in float dh)

 if I do drawImage(image, x, y, foo) is this under-provision for  
 drawImage(image,x,y,foo,undefined) or over provision for  
 drawImage(image,x,y) or is it an error?

Currently, passing a number of arguments (4) in between the allowed
numbers (3  5) gives a TypeError.  I’d be inclined to consider these
cases as under-provision.

 Do we need an annotation to say something like
 void drawImage(in HTMLImageElement image, in float dx, in float dy,  
 [Optional 2] in float dw, in float dh)
 (or something) that would say the next 2 arguments are optional, but  
 both must be provided?

Well, maybe.  [Optional] actually means the argument it appears on and
all following, as a group, can be omitted.  I think this is a little
confusing, though, so I’m thinking about allowing [Optional] only if it
is the last argument, or if all following arguments are [Optional]
(or [Variadic]).  For other cases, like drawImage() here, you can use
explicit overloading:

  void drawImage(in HTMLImageElement image, in float dx, in float dy);
  void drawImage(in HTMLImageElement image, in float dx, in float dy,
 in float dw, in float dh);

-- 
Cameron McCormack ≝ http://mcc.id.au/



Re: Handling too few arguments in method calls

2009-06-23 Thread Robin Berjon

On Jun 23, 2009, at 02:29 , Jonas Sicking wrote:

If we went with option 1, what is the effect of the [optional] flag?
I.e. what is the difference between 1 and putting [optional] on all
arguments?

I'd prefer to go with option 2, but use [optional] in more specs.


+1 from me

--
Robin Berjon - http://berjon.com/
Feel like hiring me? Go to http://robineko.com/




Re: Handling too few arguments in method calls

2009-06-22 Thread Simon Pieters
On Mon, 22 Jun 2009 02:53:22 +0200, Cameron McCormack c...@mcc.id.au  
wrote:



From some very brief testing, it seems that Firefox and Opera tend
to throw an exception when calling a method with too few arguments,
while IE, Safari and Chrome will assume that the missing arguments were
the undefined value.


Hmm. What did you use as test case?



Extra arguments tend to be ignored.

Does anyone have an opinion on which way this should be specified in Web
IDL?  Assuming this interface:

  interface A {
/* f1 */ void f(in DOMString a);
/* f2 */ void f(in DOMString a, in float b);
/* f3 */ void f(in DOMString a, in float b, in float c, in float d);
  };

option 1 would be to have:

  a.f() be like calling f1 with (undefined)
  a.f('a') be like calling f1 with ('a')
  a.f('a', 1) be like calling f2 with ('a', 1)
  a.f('a', 2, 3) be like calling f3 with ('a', 2, 3, undefined)
  a.f('a', 2, 3, 4, 5) be like calling f3 with ('a', 2, 3, 4)

and option 2 would be to have:

  a.f() throw an exception
  a.f('a') be like calling f1 with ('a')
  a.f('a', 1) be like calling f2 with ('a', 1)
  a.f('a', 2, 3) throw an exception
  a.f('a', 2, 3, 4, 5) be like calling f3 with ('a', 2, 3, 4)

Web IDL currently says to throw on any incorrect number of arguments,
so it seems that it should change to be one of the above two options.


I think I prefer option 2. It's easier for authors to find their mistake.  
If a spec author wants the behavior of option 1, then that's possible with  
[Optional].


--
Simon Pieters
Opera Software



Re: Handling too few arguments in method calls

2009-06-22 Thread Darin Adler

On Jun 22, 2009, at 12:05 AM, Simon Pieters wrote:

On Mon, 22 Jun 2009 02:53:22 +0200, Cameron McCormack  
c...@mcc.id.au wrote:


Does anyone have an opinion on which way this should be specified  
in Web

IDL?  Assuming this interface:

 interface A {
   /* f1 */ void f(in DOMString a);
   /* f2 */ void f(in DOMString a, in float b);
   /* f3 */ void f(in DOMString a, in float b, in float c, in float  
d);

 };

option 1 would be to have:

 a.f() be like calling f1 with (undefined)
 a.f('a') be like calling f1 with ('a')
 a.f('a', 1) be like calling f2 with ('a', 1)
 a.f('a', 2, 3) be like calling f3 with ('a', 2, 3, undefined)
 a.f('a', 2, 3, 4, 5) be like calling f3 with ('a', 2, 3, 4)

and option 2 would be to have:

 a.f() throw an exception
 a.f('a') be like calling f1 with ('a')
 a.f('a', 1) be like calling f2 with ('a', 1)
 a.f('a', 2, 3) throw an exception
 a.f('a', 2, 3, 4, 5) be like calling f3 with ('a', 2, 3, 4)

Web IDL currently says to throw on any incorrect number of arguments,
so it seems that it should change to be one of the above two options.


I think I prefer option 2. It's easier for authors to find their  
mistake. If a spec author wants the behavior of option 1, then  
that's possible with [Optional].


I prefer option 1 because it is closer to the behavior of the built-in  
functions in the JavaScript language.


-- Darin




Re: Handling too few arguments in method calls

2009-06-22 Thread Jonas Sicking
On Sun, Jun 21, 2009 at 5:53 PM, Cameron McCormackc...@mcc.id.au wrote:
 From some very brief testing, it seems that Firefox and Opera tend
 to throw an exception when calling a method with too few arguments,
 while IE, Safari and Chrome will assume that the missing arguments were
 the undefined value.  Extra arguments tend to be ignored.

 Does anyone have an opinion on which way this should be specified in Web
 IDL?  Assuming this interface:

  interface A {
    /* f1 */ void f(in DOMString a);
    /* f2 */ void f(in DOMString a, in float b);
    /* f3 */ void f(in DOMString a, in float b, in float c, in float d);
  };

 option 1 would be to have:

  a.f() be like calling f1 with (undefined)
  a.f('a') be like calling f1 with ('a')
  a.f('a', 1) be like calling f2 with ('a', 1)
  a.f('a', 2, 3) be like calling f3 with ('a', 2, 3, undefined)
  a.f('a', 2, 3, 4, 5) be like calling f3 with ('a', 2, 3, 4)

 and option 2 would be to have:

  a.f() throw an exception
  a.f('a') be like calling f1 with ('a')
  a.f('a', 1) be like calling f2 with ('a', 1)
  a.f('a', 2, 3) throw an exception
  a.f('a', 2, 3, 4, 5) be like calling f3 with ('a', 2, 3, 4)

 Web IDL currently says to throw on any incorrect number of arguments,
 so it seems that it should change to be one of the above two options.

If we went with option 1, what is the effect of the [optional] flag?
I.e. what is the difference between 1 and putting [optional] on all
arguments?

I'd prefer to go with option 2, but use [optional] in more specs. This
way we can in places where it really does not make sense to leave out
an argument (such as for Node.appendChild) make that throw, while in
cases where leaving arguments out can be dealt with using [optional].

While it's true that in javascript calling a function with too few
arguments doesn't throw, however a proper implementation will then
check any required attributes and manually throw if they are missing
(or simply trying to access properties on a passed in argument will
throw if the argument is undefined).

By using IDL to mark up which arguments are required, we don't have to
do that using prose in the specification.

An alternative way would be to go with option 2, but introduce a
[required] keyword.

/ Jonas



Re: Handling too few arguments in method calls

2009-06-22 Thread Aaron Boodman
This is an issue dear to my heart. I hate bad error reporting.

Whether passing the wrong number of arguments is an error conceptually
is a philosophical issue that I don't think we'll be able to agree on.
In my opinion surfacing obvious errors to developers is a good thing
that we should do. I understand this is not what JavaScript does, but
I think that breaking with JavaScript here is a Good Thing.

For those that agree that this is an error, that leaves us the
question of how to report it.

Exceptions would be best because that is how most other errors are
already reported today, so it would be least surprising. It also has
the benefit that there is already knowledge and code that looks for
exceptions.

But there is also an issue of legacy code. I brought this issue up in
a webkit bug awhile ago, and one concern from the webkit developers
was that introducing an exception would almost certainly break
sites. My opinion is that those sites are almost certainly already
broken. As a simple example, consider the setAttribute() method. Both
arguments are required, but in WebKit, if you don't pass either value
it is coerced to string. So if we take a simple attribute like
title:

someElement.setAttribute(title);  // throws in Firefox, sets title
to undefined' in WebKit

Philosophically, I want to say that pages that are passing too few
arguments to DOM APIs are already broken, just in less obvious ways.
Breaking in more obvious ways would be better.

But if there is a concern about throwing, there is a third option: We
could report the incorrect API usage to the console. This falls
outside WebIDL's scope, but it would address the majority of my
concern.


- a