motivating <| as structure representation, not operator

# Claus Reinke (12 years ago)

I've been in two minds about <| . On one hand, it seems useful and concise, on the other hand, it has odd properties for an operator, such as "literal rhs only", "modify rhs".

Both oddities could be addressed if TC39 would be willing to tackle object cloning. Then, <| could produce a clone of its rhs. But cloning with hidden and private state is tricky and might create new oddities while solving old ones. I'm not sure about this (see PS).

Meanwhile, perhaps we can find another route for <|. When I first looked at it, I thought: isn't that just a way to avoid naming that [[prototype]] field?

If we could name it, we could write

{ [[prototype]]: proto , .. }

instead of

proto <| {..}

Given the prototype chain, it makes sense to give this a special syntactic form, to distinguish the chain from other fields, but what if we just read the latter as sugar for the (unwritable) former?

Then, <| would no longer be an operator, but would be what other functional languages call a data constructor (it directly represents a data structure, with two substructures). It would not have to update the literal's implicit [[prototype]] field, because it would represent an explicit, unnamed [[prototype]] field [*2]. It would be part of writing the literal, not taking an object as rhs argument.

We could even use <| in "destructuring" [*1]:

function getProto( proto <| obj ) { return proto }

Ultimately, we might be able to talk about prototype chains in terms of <| only, without the need for [[prototype]] or proto (I'm thinking about blog posts here, which typically face the dilemma of talking about [[prototype]] vs 'prototype', to help readers in the long run while confusing them at first, or talking about proto, to be understood in the short run, with possible problems later).

This wouldn't account for the specified special behavior if the rhs is a function expression, but I'm not sure that is a bad thing:

Currently, "new" takes the new object's [[prototype]] from the function's 'prototype', which is always fun to explain (not), and the special casing in <| tries to account for that (if I understood that correctly, that is!-).

Instead of adding complexity to <| to account for existing complexity in "new", we might be able to use <| to clarify that whole dance:

function A(x) { this.x = x; return this }
function B(x) { return (proto <| {x:x}) }

new A(1) results in:  A.prototype <| {x:1} 
new B(1) results in:  proto <| {x:1} 

Caveats:

[*1] let (proto <| dict) = obj // is 'dict' the same as 'obj', without [[prototype]]? // would 'dict' be a dictionary? // would 'dict' be a shared part of 'obj', or a clone? // would this form of cloning be problematic?

[*2] for backwards-compatibility, an unwrapped { .. } would have to mean (Object.prototype <| { .. }). That context-sensitivity feels slightly awkward.

  • .. others? Any serious flaws?-)

Would this view of <| as part of the object representation be helpful? Could it be made to cover all use cases of the current proposal?

Claus clausreinke.github.com, clausreinke.github.com/js-tools

PS: I do think that TC39 should address object cloning, even if it is just a strawman listing the design options and problems, as recently summarized on this list. Then one can make design decisions based on "cloning would/would not solve this", not based on "cloning is/is not tricky".

Shallow clones are what libraries can implement, so that seems to be sufficient for many use cases. But then there are HTML5 structured cloning, or transferring JS objects between computation units not sharing a common heap. Or being able to serialize arbitrary JS objects for storage.

# Axel Rauschmayer (12 years ago)

If I may, two suggestions: For longer posts, an executive summary with the main points might make sense (not sure if I’m always doing this, but I should). And if you can, a greater “column width” for your hard line breaks would be nice, too. I checked in Emacs where I’m happy with the column width and it is indeed wider than what you are doing.

it has odd properties for an operator, such as "literal rhs only", "modify rhs". Both oddities could be addressed if TC39 would be willing to tackle object cloning. Then, <| could produce a clone of its rhs. But cloning with hidden and private state is tricky and might create new oddities while solving old ones. I'm not sure about this (see PS).

Cloning for prototype chains might be an easier problem to solve than general object cloning. Such cloning would be useful for composing prototype chains from existing objects.

Ultimately, we might be able to talk about prototype chains in terms of <| only, without the need for [[prototype]] or proto

I like <| as an inheritance operator. If we are to extend (“subclass”) function exemplars then an abstraction of the complicated under-the-hood wiring is a good thing. But having a property name for the prototype is handy, too. Perhaps a public name (as in name object) can be introduced for it?

(I'm thinking about blog posts here, which typically face the dilemma of talking about [[prototype]] vs 'prototype', to help readers in the long run while confusing them at first, or talking about proto, to be understood in the short run, with possible problems later).

Where human language usually fails me is when I initially explain prototypes in the proto (or Object.create() or Self-ish) manner and then get to constructors. Then I talk about the constructor’s prototype to avoid the longish “the value of the prototype property of the constructor”. But that’s confusing! It’ll get worse should constructors become prototypes of each other in the future.

# Quildreen Motta (12 years ago)

On 19/11/11 13:42, Axel Rauschmayer wrote:

(I'm thinking about blog posts here, which typically face the dilemma of talking about [[prototype]] vs 'prototype', to help readers in the long run while confusing them at first, or talking about proto, to be understood in the short run, with possible problems later).

Where human language usually fails me is when I initially explain prototypes in the proto (or Object.create() or Self-ish) manner and then get to constructors. Then I talk about the constructor’s prototype to avoid the longish “the value of the prototype property of the constructor”. But that’s confusing! It’ll get worse should constructors become prototypes of each other in the future.

Constructors are really the only confusing thing in JavaScript's prototypical implementation. The way I usually explain it is by first talking about `[[Prototype]]' and the under-the-hood semantics using objects alone, then explaining how constructors mess all that up :3

The special-casing of `new' has been my "favourite" topic so far.

That said, I find it interesting to think about <| in terms of structural notation rather than yet another complex layer on top of constructors. In fact, I'd rather give up on constructors entirely, but I don't think that's an option now =/

# Axel Rauschmayer (12 years ago)

Constructors are really the only confusing thing in JavaScript's prototypical implementation. The way I usually explain it is by first talking about `[[Prototype]]' and the under-the-hood semantics using objects alone, then explaining how constructors mess all that up :3

Exactly! I find it sad that people think that prototypal inheritance is complicated, but it is actually constructors that are complicated (as they are used in ES5).

The special-casing of `new' has been my "favourite" topic so far.

That said, I find it interesting to think about <| in terms of structural notation rather than yet another complex layer on top of constructors. In fact, I'd rather give up on constructors entirely, but I don't think that's an option now =/

I understand the aversion to introducing a new approach to inheritance. However, Python has managed well when it introduced new-style classes (I don’t recall any public outrage, Python 3 is much more controversial): www.python.org/download/releases/2.2.3/descrintro

Probably less radical than going from function exemplars to object exemplars, but there are many similarities. I haven’t found a “lessons learned” document, though.

I can even imagine class declarations being used as syntactic sugar for object exemplars.

# Claus Reinke (12 years ago)

If I may, two suggestions: For longer posts, an executive summary with the main points might make sense (not sure if I’m always doing this, but I should). And if you can, a greater “column width” for your hard line breaks would be nice, too. I checked in Emacs where I’m happy with the column width and it is indeed wider than what you are doing.

I'm always happy to reply to on-content comments:-P

Executive summaries are good, and I use them on occasion, but they are not the only way to save time.

That message was tuned for speed-reading (in the most primitive form of this technique, you could read the first sentence of each paragraph and would reach the core paragraphs before you could say "executive summary"). I usually indent/highlight the core paragraphs for emphasis - missed that this time, sorry.

Line lengths also have at least two mutually opposed communities: emacs-type users tend to ignore lines as a means of formatting, focusing on paragraphs and characters; vim-style users tend to use all of characters, lines, and paragraphs.

In the case of email, that conflict is resolved by RFC-5322:

http://tools.ietf.org/html/rfc5322#page-7

2.1.1.  Line Length Limits

There are two limits that this specification places on the number of characters in a line. Each line of characters MUST be no more than 998 characters, and SHOULD be no more than 78 characters, excluding the CRLF.

.. explanation of agent limitations ..

So you are free to use longer lines, but you should be aware that some agents might mess them up. If I restrict myself to shorter lines, compliant agents must not mess them up.

I don't mind your suggestions, as others have probably been thinking the same, but it helps to be aware that the styles each of us is most familiar with are not the only ones in use. For instance, I can quickly scan short-paragraph sequences, while overlong lines slow me down.

There are always multiple backgrounds, so I have to put up with all those folks who don't know what a line break is for!-)

Since the interaction of paragraph-break and line-break agents tends to lead to mis-formatted quotes in reply chains, I often try to reformat quotes, but I can't keep paragraph-break agents from messing them up anyway.

Having answered your concerns, might I add one of my own, not addressed to anyone in particular? I can deal with misformatting, overquoting, quotes not separated from inline replies (that one is hard, though). But I do sometimes wish that people would spend as much time reading and thinking as I spend on trying to present my thoughts.

Hair-trigger and off-topic replies not only derail email threads, they water down content/noise density. I'd rather spend a few minutes reading a well-thought-out message than wading through a thread of half a dozen bite-sized quick reactions and retractions. In my mind, that is email's killer advantage over twitter, after all.

But I realize that my opinion is just one among many;-)

Claus

# Axel Rauschmayer (12 years ago)

Having answered your concerns, might I add one of my own, not addressed to anyone in particular? I can deal with misformatting, overquoting, quotes not separated from inline replies (that one is hard, though). But I do sometimes wish that people would spend as much time reading and thinking as I spend on trying to present my thoughts.

Hair-trigger and off-topic replies not only derail email threads, they water down content/noise density. I'd rather spend a few minutes reading a well-thought-out message than wading through a thread of half a dozen bite-sized quick reactions and retractions. In my mind, that is email's killer advantage over twitter, after all.

I agree. But judging from how badly my own attention span has eroded over the years, I understand why it happens. If something is beyond a certain length, people (and I don’t exclude myself from that category ;-) simply won’t read it. Or only if they are deeply interested (which one can’t always expect them to be).