I noted some open issues on "Classes with Trait Composition"

Mark S. Miller erights at google.com
Mon May 23 10:54:36 PDT 2011

On Mon, May 23, 2011 at 10:42 AM, Mark S. Miller <erights at google.com> wrote:

> On Mon, May 23, 2011 at 2:16 PM, Andreas Rossberg <rossberg at google.com>wrote:
>> On 20 May 2011 18:00, David Herman <dherman at mozilla.com> wrote:
>> > I think "modules are a construct that evaluates to an object" is the
>> wrong way to think about them. Syntactic modules are a second-class
>> construct that is not an expression. You can reflect on modules at runtime,
>> and that reflection is provided as an object, but that's because almost all
>> compound data structures in JS are objects. But I would advise against
>> describing modules as a kind of object.
>> >
>> > And I think an important aspect of classes is that they are providing a
>> declarative convenience for doing things that people *already* do with
>> objects in JS today.
>> I see what you are saying, and yes, they are intended to serve a
>> different purpose. But they still share a lot of semantic overlap. And
>> I foresee that the overlap will increase overtime, as the language
>> evolves.
>> Take just one specific example: there already is the proposal for
>> extending modules with "module functions"
>> (http://wiki.ecmascript.org/doku.php?id=strawman:simple_module_functions)
>> -- which makes a lot of sense, is straightforward, and I'm sure that
>> people will demand something along these lines sooner or later. But
>> for better or worse, modules now actually have become classes!
>> Compare:
>>  class Point {
>>    private x, y
>>    constructor(x0, y0) { x = x0; y = y0 }
>>    public function move(dx, dy) { x += dx; y += dy }
>>     public function abs() { return Math.sqrt(x*x, y*y) }
>>  }
>>   let p = new Point(3, 4)
>>  p.abs()
>> with:
>>  module Point(x0, y0) {
>>    let x = x0, y = y0
>>    export function move(dx, dy) { x += dx; y += dy }
>>    export function abs() { return Math.sqrt(x*x, y*y) }
>>  }
>>  let p = Point(3, 4)  // assuming module functions are reflected into
>> functions
>>  p.abs()
>> Almost the same effect, even though the underlying semantics differs
>> somewhat.
> Regarding the scoping of private instance variables, the version with
> generative module functions is actually much better[1]. In fact, it's the
> same as the objects-as-closures pattern, or the earlier <
> http://wiki.ecmascript.org/doku.php?id=strawman:classes_with_trait_composition&rev=1299750065>
> classes strawman, which is essentially a codification of
> objects-as-closures. Personally, I still like that earlier strawman better.
> But I gave up on it based on the difficulty of convincing implementors to
> implement it efficiently. Your's seems to have the same efficiency issue.
> Since you are now involved in JS implementation, let me ask regarding your
> efforts:
> In the above example, do you anticipate an allocation per method per
> instance? Specifically, does each call to Point allocate a new instance of
> the point module (fine) exporting newly allocated move and abs closures
> (bad). Some codification of objects-as-closures only becomes a viable
> alternative to the current manual class pattern if it can avoid these extra
> allocations.
> Putting methods on a shared prototype essentially treats the prototype as a
> vtable. This implementation path is messy, but is well trodden in current JS
> implementations. Avoiding extra allocations for objects-as-closures, whether
> sugared by your generative module pattern on my earlier classes strawman,

Should be

... your generative module pattern *or* my earlier classes strawman ...

> would seem to require a new vtable mechanism not directly mapped onto
> prototype inheritance. Perhaps the "hidden classes" optimization already
> provides a context in which we can reuse implementation machinery between
> these two vtable-like mechanisms?
> [1] The semantics of the "x" reference in your move and abs methods differs
> so violently from a lexical variable reference <
> https://mail.mozilla.org/pipermail/es-discuss/2011-May/014516.html> that
> we must not make it appear to be a lexical variable reference. Starting with
> ES5, we have finally rescued lexical scoping from JavaScript's messy past.
> Let's not lose the ground we gained. Brevity is important, but scoping
> clarity is way more important than brevity.
>> You can even express simple inheritance with import and
>> export, depending on how general they will be in the end.
>> Obviously, there are aspects that you still cannot express with
>> modules but can with classes, and vice versa. But my point is that at
>> their core, they end up being pretty similar things. And their
>> differences might eventually start looking rather accidental. I would
>> feel better if we thought a bit harder about ways to utilize the
>> commonalities before we grow the size of the language too quickly.
> Today is the day before the May meeting. If generative module functions
> could be grown to meet the needs of classes, I think I would prefer the
> outcome as compared to the current classes strawman. However, the open
> issues that would need to be explored to determine this vastly exceeds the
> time between now and then.
> The May meeting is the close of the "additive phase" of designing ES-next.
> Following that, we hope for some consolidation and subtraction, among other
> activities (prototype implementations, web testing, spec writing,
> etc). Modules are already in. If classes get accepted in May, then I would
> consider it in bounds after May to grow modules slightly in order to remove
> classes completely. This would seem to be an excellent tradeoff. As I
> recall, you were planning to be at the July meeting? I think this would be a
> good focus topic for July.
>> /Andreas
> --
>     Cheers,
>     --MarkM

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110523/d88327f6/attachment-0001.html>

More information about the es-discuss mailing list