- From: Boris Zbarsky <bzbarsky@mit.edu>
- Date: Thu, 12 Jan 2017 15:18:58 -0500
- To: Domenic Denicola <d@domenic.me>
- Cc: public-script-coord <public-script-coord@w3.org>
On 1/12/17 2:23 PM, Domenic Denicola wrote: > And if we end up wanting to capture the by-reference vs. by-copy semantics in the type system Right, at that point we're sort of off into multiple orthogonal annotations: copy/reference semantics and allow/disallow sharing... > One of the big things your message drove home is how extended attributes apply to syntactic productions like dictionary members, attributes, methods, interfaces, etc. and not to types. Hmm. That's a good point. In particular, the obvious corollary is that we can't just redefine Type, syntactically, to include extended attributes, because then this: void foo([SomeAttr] int arg); would be syntactically ambiguous. But what we could do is have a TypeWithAttributes which is defined as "ExtendedAttributeList Type" We could use TypeWithAttributes in almost all places where an ES-to-IDL conversion would be involved, except where a grammar production that can be preceded by ExtendedAttributeList can start with Type. Looking through the grammar really quickly, the things that involve ES-to-IDL conversions and can start with Type would be OptionalOrRequiredArgument and DictionaryMember. For those we could specify that certain extended attributes specified on the argument or dictionary member get propagated to its type instead. In other places we'd use TypeWithAttributes instead of Type. Note that in looking through this stuff just now I found two places that would need "threading through" that I had missed initially: setlike<V> and maplike<K,V> where you want to specify whether V can be a shared/clamped/whatever thing or not... Anyway, there would need to be a bit of careful handling of cases like this: typedef [Clamp] long ClampedLong; void foo([EnforceRange] ClampedLong arg); which should error out, because fundamentally both the [Clamp] and the [EnforceRange] are being stuck on the "long", right? There will be this weird inconsistency where you write: dictionary Dict { [Clamp] required long member; }; and interface Iface { void foo([Clamp] optional long arg); }; vs interface Iface { attribute [Clamp] long attr; }; but maybe we can rejigger dictionary required member grammar and operation optional arg grammar so the case when the keyword ("required" or "optional") is present is more separate (and followed by TypeWithAttributes) and the case when the keyword is absent starts with Type and propagates extended attrs. Then this: interface Iface { void foo([Clamp] long arg); }; would quack very similarly to this: interface Iface { void foo(optional [Clamp] long arg); }; even if the under-the-hood reasons it worked were different. > I think it would be nice to introduce this concept into the spec, and retrofit it onto those extended attributes, but I'm not sure it's worth the trouble for implementers. I think the ability to apply the existing extended attrs to things like union members, maplike/setlike values, etc, is worth a certain amount of trouble. I don't think it will be _that_ much trouble in practice if we do it this way. Definitely less trouble than threading things through conversion code. > It also comes with questions like---should we invent a new concept and syntax, separate from extended attributes? Or should we say that certain extended attributes apply exclusively to types, just like certain of them apply to attributes/interfaces/etc. I guess that latter option would introduce a dependency from the parser to the semantics; to interpret `void f([X] long foo)` you'd be unsure whether [X] is associated with the parameter or the type until you knew if X was one of the type-only extended attributes. In terms of the parser it would have to be associated with the argument, of course. But the argument could propagate it through to its type per above suggestion. > (Unless we banned extended attributes on parameters entirely? Are only these type-applicable extended attributes currently used on parameters?) The extended attributes that currently apply to operation arguments are: [Clamp], [EnforceRange], [TreatNullAs]. The first two of those also apply to dictionary members, but [TreatNullAs] does not (though there's no obvious reason it can't). > Thoughts? Mainly on the "is it worth it" question, I suppose. I suspect it probably is... -Boris
Received on Thursday, 12 January 2017 20:19:33 UTC