W3C home > Mailing lists > Public > public-script-coord@w3.org > July to September 2011

Re: Non-constructible constructors and Arrays

From: Alex Russell <slightlyoff@google.com>
Date: Fri, 29 Jul 2011 15:40:46 -0700
Message-ID: <CANr5HFXgaFLYZy9NcuK2v5VJy0Vq_6j-GgDXf8t93w6hAfKSkg@mail.gmail.com>
To: David Flanagan <dflanagan@mozilla.com>
Cc: Cameron McCormack <cam@mcc.id.au>, public-script-coord@w3.org, Brendan Eich <brendan@mozilla.com>
On Thu, Jul 28, 2011 at 3:42 PM, David Flanagan <dflanagan@mozilla.com> wrote:
> On 7/28/11 2:18 PM, Alex Russell wrote:
>>
>> On Thu, Jul 28, 2011 at 12:11 PM, David Flanagan<dflanagan@mozilla.com>
>>  wrote:
>>>
>>> On 7/28/11 11:35 AM, Alex Russell wrote:
>>>>
>>>> On Wed, Jul 27, 2011 at 11:07 PM, Cameron McCormack<cam@mcc.id.au>
>>>>  wrote:
>>>>
>>>>> So this would eliminate the need for [Constructor], since all interface
>>>>> objects would be constructable?
>>>>
>>>> Yep!
>>>
>>> Don't you still need [Constructor] for declaring constructors that take
>>> arguments?  Image has multiple constructors, for example (though it uses
>>> NamedConstructor to declare them since the interface name is
>>> HTMLImageElement).
>>
>> My only proposal here is that in the absence of [Constructor], one is
>> provided for you, it's not meant to preclude allowing more and more
>> expressive constructors with better argument handling.
>
> When Cameron wrote "eliminate... [Constructor]" I thought he meant to
> eliminate it from WebIDL.  Now I think I understand: your proposal would
> simply eliminate the need for a bare [Constructor] declaration on the
> interfaces that currently use it because they could leave it out and get it
> by default.   With that clear, all of my points about constructors with
> arguments don't make any sense, since they could still be declared with
> [Constructor(...)] as they are now.
>
>>> And what about interfaces for which a no-arg constructor is not wanted?
>>
>> It's JS. Passing no args is the special case of passing args.
>>
>>>  If
>>> you're going to create Text nodes with a constructor instead of
>>> document.createTextNode(), for example, you want a constructor that takes
>>> a
>>> string argument.  You don't want to have to use a no-arg constructor and
>>> then set the data property of the resulting object.
>>
>> Right, but it shouldn't blow up. These should be equivalent:
>>
>>   var blank        = new Text("");
>>   var alsoBlank = new Text();
>
> I brought up the Text example because I thought your proposal would not
> allow a Text constructor with an argument to be declared.  Now I see that
> this is just a DOMCore issue.  You'd like that spec to declare the Text
> interface with [Constructor(optional DOMString)], and then the specification
> text for that constructor to say what to do if the argument was omitted...
>  I think WebIDL already provides everything needed here.
>
>>>  So if you make creating
>>> a no-arg constructor the default, then I think you also need to add a
>>> [NoDefaultConstructor] attribute to WebIDL
>>>
>>> Also: What would happen for interfaces declared [NoInterfaceObject] and
>>> [Callback]?  Both of those would imply [NoDefaultConstructor], right?
>>
>> I'm pretty sure that there's no need for [NoDefaultConstructor]. We
>> just need to explain the JS-side results if passing no args to the
>> ctor when you specify ctors that would otherwise take them.
>
> But there must be *some* interfaces for which no constructors (with or
> without arguments) are desired...  Perhaps the set of interfaces that do not
> want constructors is identical to the set that is currently declared
> [NoInterfaceObject] or [Callback]
>
>>>> It also opens the door for overdue fixes, like defining the arguments
>>>> these constructors should take, the document object that owns them,
>>>> and starting the discussion about how to give them shorter names = )
>>>
>>> WebIDL already allows constructor arguments to be defined.
>>
>> My point was only that we need to do the work of defining what good,
>> useful args for Node and Element ctors should be. Yes, that's work for
>> DOM to do, but WebIDL lays the groundwork here.
>
> Ah.  Sorry; I thought you were talking about WebIDL rather than DOM Core...
>
>>> Setting the ownerDocument correctly seems like a serious problem for
>>> default
>>> constructors for nodes.
>>
>> Nah. Image muddles through just fine. In any case, we can provide ways
>> to accomodate it, either through de-reference (getter-style):
>>
>>    new d = new otherdoc.Div(...);
>
> Are you actually proposing to define DOM constructors on the document
> object?

I'd prefer that they be ambiently available in the window object and,
perhaps if needed, also be mapped there. The option I outlined below
feels better.

> I kind of like that idea, but I assume you meant otherwin rather
> than otherdoc in the above...  Of course that doesn't work for documents
> created by document.implementation.createHTMLDocument(), since they don't
> have windows.
>
>> or by allowing the document to be passed into the args:
>>
>>    var d = new Div({ ownerDocument: otherdoc });
>
> Right, and if you take this approach, then the DOM Core and HTML
> specifications will have to explicitly define [Constructor] attributes that
> specify the arguments.

Yep, and that's over due. This change would just make it plain how
busted current state (createElement? really?) actually is...not that
you can actually remove any of it, so in the interim you can have
no-arg default ctors and createElement() as two half-answers...but at
least the door is open for specing args to the DOM ctors later.
createElement() probably can't be repaired in any meaningful way.

> So none of the Node subtypes (including all of the
> HTML*Element interfaces) would benefit from your create a default no-arg
> constructor if none is explicitly specified proposal.

Why not? You'd at least get to avoid saying "createElement()" unless
you wanted to do it from a *different* document.

> I am not a spec writer, but it seems to me that since spec writers will have
> to write paragraphs of prose describing what each constructor does, it would
> actually be nicer to have those constructors explicitly declared in the IDL.

IDL is a bug. The ctor lifecycle and behavior should probably be
described as idiomatic JS and then, if needed, mapped back to IDL.

>  Then, for example, the constructor declaration can be hyperlinked to the
> prose that defines what it does.  With constructors created by default, spec
> authors will just have to remember to define the behavior of this important
> function that has no IDL representation.
>
> Adding constructors to all the DOM interfaces will be a non-trivial amount
> of work for the spec authors.  It doesn't seem to me that modifying WebIDL
> to define constructors even without a [Constructor] declaration reduces that
> amount of work required in any substantial way.

That's OK. Exposing no-arg ctors as a first step does no harm, is no
worse than current state, and opens the door to exactly this over due
chunk of spec work.

>> I don't know what you mean about shorter names.  WebIDL already gives spec
>> authors the ability to use NamedConstructor to define shorthand factory
>> names like Image() and Audio().
>> Again, not WebIDL's problem per sae, but "HTMLDivElement" sucks vs.
>> "Div". Image and Audio are good precedents for Doing It Right (TM).
>
> For web compatibility, you're not going to be able to do away with
> HTMLDivElement, are you?

Probably not, but we can create aliases 'till our heart's content.

> How about just leaving it alone as a
> non-constructor and adding a Div() constructor?   (Though it seems like
> adding one constructor to the Window object per HTML tag is going to break
> existing code...)

How about making them both work -- and work the same -- and then just do:

  window.Div = window.HTMLDivElement;

?

> And given that WebIDL already has [NamedConstructor], this is basically a
> job for DOMCore and HTML, right?

Yep!

> One WebIDL issue that might be worth changing is to require named
> constructors to have the same prototype object as the current interface
> object.  For example, WebIDL should probably require that:
>
>      Image.prototype === HTMLImageElement.prototype
>
> Currently this comparison is false in both FF and Chrome.

It'd be interesting to know if changing this breaks things. I'm having
a hard time thinking up situations where it would, but the web is vast
and unpredictable.

Regards
Received on Friday, 29 July 2011 22:41:51 UTC

This archive was generated by hypermail 2.3.1 : Wednesday, 8 May 2013 19:30:04 UTC