Web IDL syntax

Hello WG.

I’m thinking about removing some of the extended attributes in Web IDL
and replacing them with non-extension syntax in the language.
Originally, I had a goal of keeping compatibility with OMG IDL, which is
why many features currently require extended attributes.  Upon
reflection, I don’t think compatibility with OMG IDL syntax is a useful
goal, especially when it gets in the way of neatly specifying particular
requirements.

So if we are happy to extend the IDL syntax, I think any extended
attribute that is intended to have some effect across all language
bindings should be moved to the syntax proper.  Following are my half
baked proposals.  I haven’t them through much; comments very much
welcome.

Thanks,

Cameron


Changes to extended attributes
------------------------------

[Callable]

Callable objects would be specified using an operation-like syntax.

  interface NumberQuadrupler {
    callable float compute(in float x);
  };

Would mean that in languages where objects can be callable,
NumberQuadruplers would be callable, but wouldn’t have a method called
“compute”.  Languages that do not support callable objects would have
the “compute” method.

You would also be able to specify a separate callable:

  interface NumberQuadrupler {
    callable float (in float x);
  };

where for langauges that don’t support callable objects, there wouldn’t
be any method on NumberQuadrupler objects.


[Constructor]

I’d say to keep this as an extended attribute, but make it be
ECMAScript-specific.  If factory methods are required across language
bindings, then explicit factory interfaces should be written.


[ExceptionConsts]

This should be dropped, and instead the IDL syntax would allow constants
to be specified on exceptions directly.

  module fileio {
    exception FileIOException {
      const unsigned short FILE_NOT_FOUND = 1;
      const unsigned short READ_ERROR = 2;
      const unsigned short WRITE_ERROR = 3;
      unsigned short code;
    };
  };


[ImplementedOn]

I’d like to take up Ian’s suggestion
http://lists.w3.org/Archives/Public/public-webapps/2009JanMar/0362.html
of syntax to specify when objects implementing interface A always
implement interface B.

Instead of having:

  [ImplementedOn=Node]
  interface EventTarget {
    …
  };

you would have:

  interface EventTarget {
    …
  };

  Node implements EventTarget;

and for the reverse case, where Anne requested an [Implements] extended
attribute
http://lists.w3.org/Archives/Public/public-webapps/2009JanMar/0360.html
you would have:

  interface XMLHttpRequestUpload {
    …
  };

  XMLHttpRequestUpload implements EventTarget;

Note that using interface inheritance is slightly different from this
“implements” syntax, since the former makes particular requirements of
the prototype chain in ECMAScript and the actual inheritance hierarchy
in Java.


[{Index,Name}{Creator,Deleter,Getter,Setter}]

As with the “callable” keyword, indexing operations would be specified
with operation-like syntax.

  interface OrderedMap {
    readonly attribute unsigned size;

    getter any getByIndex(in unsigned long index);
    setter void setByIndex(in unsigned long index, in any value);
    deleter void removeByIndex(in unsigned long index);

    getter any get(in DOMString name);
    creator setter void set(in DOMString name, in any value);
    deleter void remove(in DOMString name);
  };

As with “callable”, the “getter”, “creator”, “setter” and “deleter”
modifiers on an operation indicate that if the language binding supports
object indexing like this, the methods won’t exist.  To have a getter
that exists in ECMAScript while also keeping the method, you’d do:

  interface HTMLCollection {
    …
    Element item(in unsigned long index);
    getter Element (in unsigned long index);
    …
  };


An alternative would be to reverse the omission of methods, so that
“getter” on an operation would always have both the getter.  Then if you
wanted to omit the method if getters are supported you could do
something like:

  interface DOMStringMap {
    omittable getter DOMString get(in DOMString name);
    omittable setter void set(in DOMString name, in DOMString value);
    …
  };

and getters/setters defined with no operation name would be implicitly
omittable.


Not sure which of the above two ways is better, at the moment.


[NoIndexingOperations]

This wouldn’t be needed, since the above changes to specifying getters
and setter would allow you to specify whether the methods get included
or not.


[Null]

This would become an ECMAScript-specific extended attribute.


[Optional]

Optional arguments would be able to be specified using an “optional”
keyword, like so:

  interface ColorCreator {
    Object createColor(in float v1,
                       in optional float v2,
                       in float v3,
                       in optional flat alpha);
  };

“optional” would still mean “this and all following arguments can be
omitted”.


[Prefix]

This was really just a hack for avoiding multiple nested modules to get
appropriate Java package names.  You should be able to use multiple
levels in module declarations, like:

  module a::b::c {
  };

I’m inclined to keep the default mapping of a one level module X to the
Java package org.w3c.X, but to change [Prefix] to be a Java-specific
extended attribute (and rename it to [JavaPackage] or so) to allow
changing this behaviour.


[PutForwards]

This should become an ECMAScript-specific extended attribute.


[Stringifies]

As with “callable”, that an object has stringification behaviour would
be specified with a keyword:

  interface Student {
    attribute unsigned long id;
    attribute DOMString name;

    stringifier DOMString ();
    /* or
    stringifier DOMString toString();
    */
  };

Whatever would be decided for the getters/setters in terms of omitting
methods would also apply to “stringifier”.  You could put “stringifier”
on an attribute too, just like [Stringifies] currently can take an
argument:

  interface Student {
    attribute unsigned long id;
    stringifier attribute DOMString name;
  };

(I don’t much like the name “stringifier”, though.)


[Variadic]

I propose to use Java-like syntax for variadic operations instead, like:

  interface IntegerSet {
    readonly unsigned long attribute cardinality;

    void union(in long ints...);
    void intersection(in long ints...);
  };


Other possible syntax changes
-----------------------------

I don’t think we really need to keep the requirement of typedefing
sequences and valuetypes just to be able to use them (assuming that the
sequence<T> syntax is what ends up being kept to handle sequences).

Maybe boxed valuetypes should use some more obvious syntax anyway, like
“nullable T” instead of “valuetype<T>”.

I think the “Object”, “TRUE” and “FALSE” keywords should be made
lowercase.

If we are breaking syntax, then it seems more compelling to make
“DOMString” be “string”.

Maybe we could drop the “in” keyword.  Seems better to stick with plain
“in” arguments, for compatibility across language bindings, than to also
allow “out” and “inout” ones.

Any other vestiages from the past in the IDL that seems ripe for change?

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

Received on Friday, 19 June 2009 04:55:40 UTC