Please some small improvements

John J Barton johnjbarton at johnjbarton.com
Tue Mar 20 17:19:42 PDT 2012


On Tue, Mar 20, 2012 at 4:34 PM, Allen Wirfs-Brock
<allen at wirfs-brock.com> wrote:
>
> On Mar 20, 2012, at 3:57 PM, John J Barton wrote:
>
>> On Tue, Mar 20, 2012 at 2:53 PM, Allen Wirfs-Brock
>> <allen at wirfs-brock.com> wrote:
>>>
>>> On Mar 20, 2012, at 2:10 PM, John J Barton wrote:
>>>
> ...
>>>
>>> In ES.next, based upon current proposals, the equivalent can be directly
>>> expressed  using <| without any additional function calls:
>>>
>>>  LoadCodeUnit.prototype = CodeUnit.prototype <| {
>>>    allowLoad: true,
>>>
>>>    get moduleSymbol() {
>>>      return this.project.getModuleForUrl(this.url)
>>>    },
>>>
>>>    ...
>>>
>>> In other words, <| is the operator forms of the function you are requesting
>>> for the object literal use case.
>>
>> I agree that the <| would be a good match to the use shown in the Traceur code.
>>
>> However, the example shows a significant pitfall waiting for the
>> unsuspecting: data properties on the prototype. The allowLoad
>> properties does appear to be intended as a 'static' or class value. In
>> projects that never use object literals for data properties, then this
>> ok. But many devs will use object literals for both functions and
>> data. Soon or later we get burnt.
>
> Whether such a data property is good or bad, really depends upon the context.

Of course, but the design question is: Are the bad cases really bad
and the good cases rare with simple alternatives? I say yes.

> Maybe allowLoad:true is simply a default that is over-ridable on a per instance basis.  In that case, what is wrong with putting it on the prototype?  Would you be happier if it was defined as:
>  get allowLoad() {return true}
> ?

That would be ok or setting the value in the constructor or
  LoadCodeUnit.prototype.allowLoad = true;
Lots of good alternatives rather than playing with confusion and fire.

>
> If that is the same it makes it harder to over-ride for individual instances because they need to do a Object.defineProperty to install the over-ride rather than a simple assignment.

Even this is ok by me. Make simple things simple; its ok if hard
things are hard.

>
>>
>> I suppose the <| operator has the advantage that linters can probably
>> report data properties in the RHS at edit time.  Making this a compile
>> error should be considered.
>
> But there are plenty of other uses of <| in conjunction with object literal data properties.
>
> For example, you can use <| as an alternative to the new operator.  Assume that you have the definition I quoted from Tracer then to create a LoadCodeUnit instance you might say:
>
>    let aCU = Load.CodeUnit <| {allowLoad: false, loader: myLoader, url: "foo.js", state: NOT_STARTED};
>
> to create one that doesn't allow loading.
>
>
> As another example, you can use prototype inheritance to buildup data records with shared parts.  For example:
>
> let wb = {lastName: "Wirfs-Brock"};
> let wbOR = wb <| {state: "Oregon"};
> let allenwb = wbOR <| {firstName: "Allen"};
> let rjw = wbOR <| {firstName: "Rebecca"};

All cool examples.

>
> If you play nanny based upon only one usage pattern you preclude other uses.

Sure but this very point is one that separates <| from 'class'. That
is, Java et al preclude virtual data.

> It's probably better to make such rules part of a project specific linter.

Or perhaps the check can be on the assignment to .prototype,  the
argument to Object.create(), or the RHS of <|.

jjb


More information about the es-discuss mailing list