prototype for operator proposal for review

# Allen Wirfs-Brock (13 years ago)

We had so much fun with feedback on my Unicode proposal I just have open another one up for list feed back:

An updated version of the "prototype for" (formerly proto) operator proposal is at strawman:proto_operator

# Luke Hoban (13 years ago)

If there were a more usable library variant of Object.create instead, it seems the new syntax here would not be as necessary.

Instead of: var o = myProto <| { a: 0, b: function () {} }

You could do: var o = Object.make(myProto, { a: 0, b: function () {} })

A few more characters, but still addresses the major issue preventing wider Object.create usage (the use of property descriptors). A library solution also keeps the benefit of not needing new syntax, and being available to text/javascript. As noted in the strawman, similar functions on Array and Function could support the other scenarios described in the proposal.

It seems the syntax is perhaps aiming to avoid needing to allocate an intermediate object - but I imagine engines could potentially do that for Object.make and friends as well if it was important for performance?

Luke

From: es-discuss-bounces at mozilla.org [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Allen Wirfs-Brock Sent: Tuesday, May 17, 2011 7:50 PM To: es-discuss at mozilla.org Subject: prototype for operator proposal for review

We had so much fun with feedback on my Unicode proposal I just have open another one up for list feed back:

An updated version of the "prototype for" (formerly proto) operator proposal is at strawman:proto_operator

# Jeff Walden (13 years ago)

On 05/17/2011 09:49 PM, Luke Hoban wrote:

It seems the syntax is perhaps aiming to avoid needing to allocate an intermediate object – but I imagine engines could potentially do that for Object.make and friends as well if it was important for performance?

It's probably possible to do that. But such hacks are rather fragile. I suspect this would take roughly the form of the way SpiderMonkey optimizes Function.prototype.apply, which is roughly to look for calls of properties named "apply" and do special-case behavior with a PIC in the case that that property is actually |Function.prototype.apply|. It takes some pretty gnarly code, duplicated two places (possibly a third, but that might not be necessary), to make it all happen. That sort of pattern certainly can be repeated if push comes to shove. But I believe doing so is far inferior to dedicated, first-class syntactical support to make the semantics absolutely unambiguous and un-confusable with anything else.

In this particular case, I suspect implementing a PIC that way would be even gnarlier, because it wouldn't just be a PIC on the identity of the |Object.make| property, it'd have to also apply to computation of the arguments provided in the function "call" (or a not-call if you're using a PIC this way). That too can probably be done. But it'd be pretty tricky (thinking of things like the PIC only being applicable if the argument is an object literal, and of it being mostly inapplicable if it's anything else). And if you wanted to extend that to apply to more functions than just a single Object.make function, the hacks will be even more complex, possibly not even by a constant increment.

And of course this would also make it harder for IDEs and such to give good first-class syntax highlighting here, because the syntax for this would be ambiguous with user-created stuff.

Anyway, food for thought. And I know others here are more familiar with this than I am, so please chime in with more if you have it, or corrections if you have them.

# Allen Wirfs-Brock (13 years ago)

On May 17, 2011, at 9:49 PM, Luke Hoban wrote:

If there were a more usable library variant of Object.create instead, it seems the new syntax here would not be as necessary.

Instead of: var o = myProto <| { a: 0, b: function () {} }

You could do: var o = Object.make(myProto, { a: 0, b: function () {} })

A few more characters, but still addresses the major issue preventing wider Object.create usage (the use of property descriptors). A library solution also keeps the benefit of not needing new syntax, and being available to text/javascript. As noted in the strawman, similar functions on Array and Function could support the other scenarios described in the proposal.

That isn't really what this proposal is about, but it is what the strawman:concise_object_literal_extensions proposal addresses.

The primary scenario is what some people call "subclassing" the various built-in classes of objects that have special internal state and behavior. The most important of these "classes" are Array, Function, and RegExp. Programmer want to be able to create instances of these whose direct [[Prototype]] is different from the default. (in most cases the desired prototype will inherit from the default)

Specifying the prototype for an object literal is also a scenario but I wouldn't necessarily say it is more important than the other.

It seems the syntax is perhaps aiming to avoid needing to allocate an intermediate object – but I imagine engines could potentially do that for Object.make and friends as well if it was important for performance?

An implementation might try to optimize such functions as you describe, but because both the global binding to the base object and the property binding of the method are mutable you at least have to have a dynamic guard on any fast path and still have to generate the code to create the arguments and do a regular call if the guard fails. I made the same argument for Object.create and I'm not aware of implementation that have yet to optimize it in this manner.

Another difference from the function approach is that the function can assume it is being passed a new object or even any object of the kind it is expect. The <| ooperator is syntactically required in the current proposal to have a literal form as its right operand so both implementations and human code readers can determine by examination what [[Class]] of object is being created.

# Luke Hoban (13 years ago)

The primary scenario is what some people call "subclassing" the various built-in classes of objects that have special internal state and behavior. The most important of these "classes" are Array, Function, and RegExp.  Programmer want to be able to create instances of these whose direct [[Prototype]] is different from the default. (in most cases the desired prototype will inherit from the default)

I was assuming that similar library functions such as Array.make, Function.make and RegExp.make would address these cases in the same way as Object.make. Beyond the intermediate object allocation issue, is there anything else those cannot accomplish? Either way, exposing the library function alternatives as well seems useful to provide the capability to subclass these objects in 'text/javascript'.

An implementation might try to optimize such functions as you describe, but because both the global binding to the base object and the property binding of the method are mutable you at least have to have a dynamic guard on any fast path and still have to generate the code to create the arguments and do a regular call if the guard fails. I made the same argument for Object.create and I'm not aware of implementation that have yet to optimize it in this manner.

Fair enough. I'll check on whether we have considered any similar optimizations in IE.

# Luke Hoban (13 years ago)

That sort of pattern certainly can be repeated if push comes to shove. But I believe doing so is far inferior to dedicated, first-class syntactical support to make the semantics absolutely unambiguous and un-confusable with anything else.

This makes sense. I just want to make sure that the fundamental capability to subclass built-in objects is available via libraries for text/javascript, with the new syntax offering the more performant option for text/harmony.

And of course this would also make it harder for IDEs and such to give good first-class syntax highlighting here, because the syntax for this would be ambiguous with user-created stuff.

What kind of syntax highlighting would you want to offer? Distinguishing normal arrays from arrays with non-standard prototypes would be more difficult, but this doesn't seem like a common syntax highlighting need.

# Dmitry A. Soshnikov (13 years ago)

On 18.05.2011 6:50, Allen Wirfs-Brock wrote:

We had so much fun with feedback on my Unicode proposal I just have open another one up for list feed back:

An updated version of the "prototype for" (formerly proto) operator proposal is at strawman:proto_operator

Just a small note on:

"There are many other possible special character alternates to |<||. For example, ||>|, |^^|, |>|*, |&>|, |^||, |<|-|, etc. It

isn't clear that any of these is more meaningful or mnemonic than |<||."

Perhaps just "less than" would be enough? Why we need two symbols? It's by the way, a real implementation of subclassing in Ruby:

class Foo def alert p "Called from Foo class" end end

class Bar < Foo def alert super end end

bar = Bar.new bar.alert # "Called from Foo class"

It sounds quite logical -- "by hierarchy Bar is less than Foo".

And also: what's happened to meta-properties in initialisers? It seems to me that having them we get also the ability not only to specify the proto, but also other control attributes for properties and to the object. And since #-symbol has changed its semantics, and instead ->-functions (or probably Ruby's blocks) are on agenda instead, maybe we

may use # exactly for meta properties?

let foo = {x: 10};

let bar = {

#proto: foo, #closed

y: 20, // etc.

};

Dmitry.

# Dmitry A. Soshnikov (13 years ago)

Besides. The same inheriting keyword can be used for both -- classes inheriting and just classless (or chaotic, prototypal) reuse:

foo < bar

class Foo < Bar

or

foo extends bar { y: 20 }

class Foo extends Bar

Since both implements the same pattern -- linear vertical "tower" of code reuse (in simple words -- just single inheritance), then the same keyword seems also logical.

Dmitry.

# Kyle Simpson (13 years ago)

I'm definitely in favor of this <| proposal, btw.

That sort of pattern certainly can be repeated if push comes to shove. But I believe doing so is far inferior to dedicated, first-class syntactical support to make the semantics absolutely unambiguous and un-confusable with anything else.

This makes sense. I just want to make sure that the fundamental capability to subclass built-in objects is available via libraries for text/javascript, with the new syntax offering the more performant option for text/harmony.

I'm pretty sure current text/javascript can sub-class safely, as FuseBox (from @fusejs) does with sandboxing natives. It's hacky, and relies on the non-standard proto in most browsers (iframe in others), but it IS possible. Perhaps we should still formalize it, if we think text/javascript is gonna be around for a long time in parallel with ES.Next that has something like <|.

# Sam Tobin-Hochstadt (13 years ago)

On Wed, May 18, 2011 at 2:59 AM, Luke Hoban <lukeh at microsoft.com> wrote:

That sort of pattern certainly can be repeated if push comes to shove.  But I believe doing so is far inferior to dedicated, first-class syntactical support to make the semantics absolutely unambiguous and un-confusable with anything else.

This makes sense.  I just want to make sure that the fundamental capability to subclass built-in objects is available via libraries for text/javascript, with the new syntax offering the more performant option for text/harmony.

Perhaps I'm missing something, but <| seems like something that could be provided to 'text/javascript' just as easily as 'text/the-next-javascript'. Unlike using |module| as a keyword, or changing the scope rules or |typeof null|, no working 'text/javascript' program uses <| at the moment.

# Brendan Eich (13 years ago)

On May 18, 2011, at 6:46 AM, Sam Tobin-Hochstadt wrote:

On Wed, May 18, 2011 at 2:59 AM, Luke Hoban <lukeh at microsoft.com> wrote:

That sort of pattern certainly can be repeated if push comes to shove. But I believe doing so is far inferior to dedicated, first-class syntactical support to make the semantics absolutely unambiguous and un-confusable with anything else.

This makes sense. I just want to make sure that the fundamental capability to subclass built-in objects is available via libraries for text/javascript, with the new syntax offering the more performant option for text/harmony.

Perhaps I'm missing something, but <| seems like something that could be provided to 'text/javascript' just as easily as 'text/the-next-javascript'. Unlike using |module| as a keyword, or changing the scope rules or |typeof null|, no working 'text/javascript' program uses <| at the moment.

Couple of small points, one I already laid on Luke in a private reply:

  1. text/javascript is unregistered HTML4 noise. RFC4329 has application/javascript and application/ecmascript with version parameter reserved.

  2. Developers want new syntax not to choke old browsers. I've been there in 1996-2001 with ES2 and ES3. So using a new type or version value hides the new syntax from old browsers. You have to do something for the old browsers, of course, either server-side or client-side. See

strawman:versioning

and its links. I'm going to improve this page shortly.

# Allen Wirfs-Brock (13 years ago)

On May 17, 2011, at 11:59 PM, Luke Hoban wrote:

And of course this would also make it harder for IDEs and such to give good first-class syntax highlighting here, because the syntax for this would be ambiguous with user-created stuff.

What kind of syntax highlighting would you want to offer? Distinguishing normal arrays from arrays with non-standard prototypes would be more difficult, but this doesn't seem like a common syntax highlighting need.

In general declarative constructs are easier for tools to analyze than imperative processes built out of function calls. All the complications that were brought up for optimizing the imperative forms also apply to tools and tools don't have any dynamic context available to verify any inferences they may make. This applies to more than just syntax highlighters. Refactoring tools, reference engineering tools, and anything else that wants to statically source code generally will have an easer time with declarative constructs.

# Allen Wirfs-Brock (13 years ago)

On May 18, 2011, at 12:41 AM, Dmitry A. Soshnikov wrote:

On 18.05.2011 6:50, Allen Wirfs-Brock wrote:

We had so much fun with feedback on my Unicode proposal I just have open another one up for list feed back:

An updated version of the "prototype for" (formerly proto) operator proposal is at strawman:proto_operator

Just a small note on:

"There are many other possible special character alternates to <|. For example, |>, ^^, *>, &>, ^|, <|-, etc. It isn’t clear that any of these is more meaningful or mnemonic than <|."

Perhaps just "less than" would be enough? Why we need two symbols? It's by the way, a real implementation of subclassing in Ruby:

< already has a meaning for operands that are arbitrary objects. It applies valueOf and/or toString to the operands and then compares the results.

And also: what's happened to meta-properties in initialisers? It seems to me that having them we get also the ability not only to specify the proto, but also other control attributes for properties and to the object. And since #-symbol has changed its semantics, and instead ->-functions (or probably Ruby's blocks) are on agenda instead, maybe we may use # exactly for meta properties?

The most common use case for meta properties was to set [[Prototype]]. That solution worked for object literals and array literal but didn't extend to functions, regexps, or other literal forms. <| does. The other uses of meta properties sealed, frozen, closed would probably be used infrequently enough that the Object functions are good enough:

  let bar = Object.preventExtensions(foo <| {y:20});

Also there were some concerns about possible syntactic conflicts between the proposed meta-property syntax and E4X features (I know...but some people care)...

Overall, <| seems like a simpler solution that is more general for the most important use case.

# Brendan Eich (13 years ago)

On May 18, 2011, at 9:10 AM, Allen Wirfs-Brock wrote:

On May 18, 2011, at 12:41 AM, Dmitry A. Soshnikov wrote:

On 18.05.2011 6:50, Allen Wirfs-Brock wrote:

We had so much fun with feedback on my Unicode proposal I just have open another one up for list feed back:

An updated version of the "prototype for" (formerly proto) operator proposal is at strawman:proto_operator

Just a small note on:

"There are many other possible special character alternates to <|. For example, |>, ^^, *>, &>, ^|, <|-, etc. It isn’t clear that any of these is more meaningful or mnemonic than <|."

Perhaps just "less than" would be enough? Why we need two symbols? It's by the way, a real implementation of subclassing in Ruby:

< already has a meaning for operands that are arbitrary objects. It applies valueOf and/or toString to the operands and then compares the results.

Indeed :-P -- see tobeytailor/def.js/blob/master//def.js and read the source.

Overall, <| seems like a simpler solution that is more general for the most important use case.

I like it, it's more general and it doesn't require guessing games by readers and optimizers about the meaning of "Object", "Object.make", etc.

The only thing that nags is the proto being on the left of the "triangle-arrow". Other languages and type theory use < or <: to put the extension or more-derived thing on the left, but here the extension (value not type, but still) is on the right.

Maybe I'll get over this, though. The use-case with an object literal as the extension really must be on the right, I quite agree. Does |> work any better?

# Dean Landolt (13 years ago)

On Wed, May 18, 2011 at 11:53 AM, Allen Wirfs-Brock <allen at wirfs-brock.com>wrote:

On May 17, 2011, at 11:59 PM, Luke Hoban wrote:

And of course this would also make it harder for IDEs and such to give good first-class syntax highlighting here, because the syntax for this would be ambiguous with user-created stuff.

What kind of syntax highlighting would you want to offer? Distinguishing normal arrays from arrays with non-standard prototypes would be more difficult, but this doesn't seem like a common syntax highlighting need.

In general declarative constructs are easier for tools to analyze than imperative processes built out of function calls. All the complications that were brought up for optimizing the imperative forms also apply to tools and tools don't have any dynamic context available to verify any inferences they may make. This applies to more than just syntax highlighters. Refactoring tools, reference engineering tools, and anything else that wants to statically source code generally will have an easer time with declarative constructs.

I think the argument for ease of static analysis applies just as well to human analysis (after all, our wetware makes for a poor interpreter). But I think the counter-argument is more compelling -- this is yet another construct our tooling would have to understand, and every new construct substantially ups the ante for fluency (ISTM the tax for each new syntax is approximately combinatorial for inexperienced developers).

The imperative alternative, on the other hand, only requires learning the semantics of a new API, not whole new constructs and how they compose (regardless of how nicely they compose). I personally believe this matters a great deal, and not just for newcomers. As I've heard /be suggest, some of javascript's success can be owed to its lack of syntactical novelty. I'm not saying all new syntax is bad syntax, but at the very least the committee should be optimizing for humans first.

# Brendan Eich (13 years ago)

On May 18, 2011, at 9:25 AM, Dean Landolt wrote:

I think the argument for ease of static analysis applies just as well to human analysis (after all, our wetware makes for a poor interpreter). But I think the counter-argument is more compelling -- this is yet another construct our tooling would have to understand, and every new construct substantially ups the ante for fluency (ISTM the tax for each new syntax is approximately combinatorial for inexperienced developers).

I hear this sometimes, but not about languages with established syntactic complexity (e.g. Ruby). Indeed people learn Ruby and other languages by learning subsets. They learn via tutorials. They learn inductively until idioms need to be learned.

Meanwhile, syntax as better user interface, for usability ("developer ergonomics" applies to programming languages too), must matter. Not just keystrokes and chording for code production. That hurts (some of my RSI afflicted talented-programmer friends testify) but for maintenance.

And readability, which ultimately trumps writability but not in any zero-sum-game sense, can be aided by new syntax, compared to using library methods and functions.

The imperative alternative, on the other hand, only requires learning the semantics of a new API, not whole new constructs and how they compose (regardless of how nicely they compose). I personally believe this matters a great deal, and not just for newcomers.

I don't see why you assume newcomers learn all the syntax, all at once. I did not when I learned a great many languages.

As I've heard /be suggest, some of javascript's success can be owed to its lack of syntactical novelty. I'm not saying all new syntax is bad syntax, but at the very least the committee should be optimizing for humans first.

JS mainly had first-mover and it "did not suck" so badly that it lost to a second mover -- it stuck. We are not removing old syntax. So people can learn the old syntax if they like.

Then the objection moves from pedagogy to maintenance: "I don't want to have to maintain paren-free code", e.g. But you always have choices. Refuse, parenthesize were allowed, negotiate. Syntax is partly social.

# Allen Wirfs-Brock (13 years ago)

On May 18, 2011, at 9:20 AM, Brendan Eich wrote:

The only thing that nags is the proto being on the left of the "triangle-arrow". Other languages and type theory use < or <: to put the extension or more-derived thing on the left, but here the extension (value not type, but still) is on the right.

Maybe I'll get over this, though. The use-case with an object literal as the extension really must be on the right, I quite agree. Does |> work any better?

We probably could make :> work (but, gag, typing this message on my Mac using Helvetica 12 the : is practically invisible next to >. <: doesn't seem to have quite the same problem for some reason).

I think I like <: about as much as <|. I'm not sure which is going to be more readable across a variety of fonts and sizes. <| does seem to be generally more visually distinct.

I suspect that to most JS programmers the UML open triangle generalization arrow head is at least as relevant a precedent as any type theory uses. In other words,the relevancy of either isn't very high.

One might argue that the prototype object is the more general and hence "smaller" object (the object on the right specializes the prototype by adding properties).

In the end, these are just symbols and JS programmer are just going to have to learn their meaning. Existing conventions, if they exist, and analogous do impact initial learnability but in the long run I don't know if it makes much a difference as long as they aren't prone to keyboarding hazards.

# Brendan Eich (13 years ago)

On May 18, 2011, at 9:47 AM, Allen Wirfs-Brock wrote:

I suspect that to most JS programmers the UML open triangle generalization arrow head is at least as relevant a precedent as any type theory uses.

I will take that bet. UML, ho ho! Maybe enterprise Java heads...

In other words,the relevancy of either isn't very high.

Perhaps not, but Ruby's < is relevant to a good-sized cohort.

One might argue that the prototype object is the more general and hence "smaller" object (the object on the right specializes the prototype by adding properties).

Yes, type narrowness is a dual of object population in JS, if you think of object with properties as an exemplar (prototype, even) of a latent structural type.

In the end, these are just symbols and JS programmer are just going to have to learn their meaning. Existing conventions, if they exist, and analogous do impact initial learnability but in the long run I don't know if it makes much a difference as long as they aren't prone to keyboarding hazards.

The precedents matter a bit, even if we try to create a new idiom. The problem is < not | (although doesn't that look too light in Helvetica on either side?).

# Brendan Eich (13 years ago)

On May 18, 2011, at 9:51 AM, Brendan Eich wrote:

On May 18, 2011, at 9:47 AM, Allen Wirfs-Brock wrote:

In the end, these are just symbols and JS programmer are just going to have to learn their meaning. Existing conventions, if they exist, and analogous do impact initial learnability but in the long run I don't know if it makes much a difference as long as they aren't prone to keyboarding hazards.

The precedents matter a bit, even if we try to create a new idiom. The problem is < not | (although doesn't that look too light in Helvetica on either side?).

I don't think :> works, as you say. It looks like crap, frankly, in too many fonts. However, does |> not work?

# Mark S. Miller (13 years ago)

On Wed, May 18, 2011 at 9:52 AM, Brendan Eich <brendan at mozilla.com> wrote:

On May 18, 2011, at 9:51 AM, Brendan Eich wrote:

On May 18, 2011, at 9:47 AM, Allen Wirfs-Brock wrote:

In the end, these are just symbols and JS programmer are just going to have to learn their meaning. Existing conventions, if they exist, and analogous do impact initial learnability but in the long run I don't know if it makes much a difference as long as they aren't prone to keyboarding hazards.

The precedents matter a bit, even if we try to create a new idiom. The problem is < not | (although doesn't that look too light in Helvetica on either side?).

I don't think :> works, as you say. It looks like crap, frankly, in too many fonts. However, does |> not work?

I made my peace with <| when Allen pointed out that the object on the left points at the object on the right. Flipping it around loses that mnemonic. This "points at" intuition should be independent of any prior exposure to UML.

# Brendan Eich (13 years ago)

On May 18, 2011, at 10:07 AM, Mark S. Miller wrote:

I made my peace with <| when Allen pointed out that the object on the left points at the object on the right. Flipping it around loses that mnemonic. This "points at" intuition should be independent of any prior exposure to UML.

Do you mean the object on the right points at the object on the left (via [[Prototype]])? That, I buy.

# Mark S. Miller (13 years ago)

On Wed, May 18, 2011 at 10:10 AM, Brendan Eich <brendan at mozilla.com> wrote:

On May 18, 2011, at 10:07 AM, Mark S. Miller wrote:

I made my peace with <| when Allen pointed out that the object on the left points at the object on the right. Flipping it around loses that mnemonic. This "points at" intuition should be independent of any prior exposure to UML.

Do you mean the object on the right points at the object on the left (via [[Prototype]])? That, I buy.

JEEZ! Yes, that's what I meant. Thanks for the quick correction.

# Allen Wirfs-Brock (13 years ago)

On May 18, 2011, at 9:51 AM, Brendan Eich wrote:

On May 18, 2011, at 9:47 AM, Allen Wirfs-Brock wrote:

I suspect that to most JS programmers the UML open triangle generalization arrow head is at least as relevant a precedent as any type theory uses.

I will take that bet. UML, ho ho! Maybe enterprise Java heads...

class hierarchy diagrams are only useful for understanding designs when you actually have complex hierarchies. This very conversation is about adding features to make it easy for JS programmers to build such hierarchies. Who knows, may e in a few years we will see a resurgence of UML for documenting JS designs in which case people may curse us if we choose today to make the triangle point the wrong direction ;-)

# Allen Wirfs-Brock (13 years ago)

On May 18, 2011, at 9:52 AM, Brendan Eich wrote:

On May 18, 2011, at 9:51 AM, Brendan Eich wrote:

On May 18, 2011, at 9:47 AM, Allen Wirfs-Brock wrote:

In the end, these are just symbols and JS programmer are just going to have to learn their meaning. Existing conventions, if they exist, and analogous do impact initial learnability but in the long run I don't know if it makes much a difference as long as they aren't prone to keyboarding hazards.

The precedents matter a bit, even if we try to create a new idiom. The problem is < not | (although doesn't that look too light in Helvetica on either side?).

I don't think :> works, as you say. It looks like crap, frankly, in too many fonts. However, does |> not work?

/be

|> could work but I think we agree that the object literal (or array or function for that matter) really needs to be on the right for readability. In that case |> seems to be point ingin the wrong direction from any of the perspectives: UML generalization, [[Prototype]] pointer direction, type specialization...

# Brendan Eich (13 years ago)

On May 18, 2011, at 10:30 AM, Allen Wirfs-Brock wrote:

On May 18, 2011, at 9:52 AM, Brendan Eich wrote:

On May 18, 2011, at 9:51 AM, Brendan Eich wrote:

On May 18, 2011, at 9:47 AM, Allen Wirfs-Brock wrote:

In the end, these are just symbols and JS programmer are just going to have to learn their meaning. Existing conventions, if they exist, and analogous do impact initial learnability but in the long run I don't know if it makes much a difference as long as they aren't prone to keyboarding hazards.

The precedents matter a bit, even if we try to create a new idiom. The problem is < not | (although doesn't that look too light in Helvetica on either side?).

I don't think :> works, as you say. It looks like crap, frankly, in too many fonts. However, does |> not work?

/be

|> could work but I think we agree that the object literal (or array or function for that matter) really needs to be on the right for readability. In that case |> seems to be point ingin the wrong direction from any of the perspectives: UML generalization, [[Prototype]] pointer direction, type specialization...

Gotcha, I'm sold. It's an idiom.

I will go play TMBG "Particle Man", the "Triangle Man" verse.

# Douglas Crockford (13 years ago)

On 11:59 AM, Allen Wirfs-Brock wrote:

class hierarchy diagrams are only useful for understanding designs when you actually have complex hierarchies. This very conversation is about adding features to make it easy for JS programmers to build such hierarchies. Who knows, may e in a few years we will see a resurgence of UML for documenting JS designs in which case people may curse us if we choose today to make the triangle point the wrong direction ;-)

You can't be too sure. They might have lots of other reason to curse.

# John J Barton (13 years ago)

An HTML attachment was scrubbed... URL: esdiscuss/attachments/20110518/5a96b32f/attachment-0001

# Bob Nystrom (13 years ago)

What about making the operator go in the other direction, like so:

{a:1,b:2} |> MyObject.prototype

[0,1,2,3,4,5] |> appBehavior

Array.create=function(proto,props) { return Object.defineProperties([ ] |> proto, props) };

let f = function () {} |> EnhancedFunctionPrototype

var p = /[a-m][3-7]/ |> newRegExpMethods

var o = { a:0, b: function () {} } |> myProto

The mnemonic is preserved, but I find this a little more natural to read. In particular:

  1. The data specific to this instance appears first.

  2. The "|>" can be read as "extends" instead of "is extended by".

  3. The objects are ordered from left-to-right in the order that properties on them are looked up. Given "foo |> bar" we'll look for a property on "foo"

then "bar".

Personally, I don't have a strong opinion since I don't think I'd use this much regardless of syntax, but I wanted to put this out there.

# Allen Wirfs-Brock (13 years ago)

On May 18, 2011, at 11:30 AM, Bob Nystrom wrote:

What about making the operator go in the other direction, like so:

My rationale for the ordering is explained in the third bullet of the "Commentary and rationales" section of the proposal strawman:proto_operator

# Brendan Eich (13 years ago)

The rationale for the arrow pointing the way the proto-link points was also in the very message Bob cited :-P.

"Triangle man, Triangle man Triangle man hates particle man They have a fight, Triangle wins Triangle man"

(Some think this is about world religions, others say physics. I say OOP.)

# David Herman (13 years ago)

I think I like <: about as much as <|. I'm not sure which is going to be more readable across a variety of fonts and sizes. <| does seem to be generally more visually distinct.

I just have to say that the pipe symbol in many fonts makes for a really hideous triangle. It doesn't line up at all with the top and bottom of the less-than/greater-than symbols.

I suspect that to most JS programmers the UML open triangle generalization arrow head is at least as relevant a precedent as any type theory uses. In other words,the relevancy of either isn't very high.

Yeah. In fact, the analogy to type theory would have us read the <: symbol as a binary predicate, which isn't what's going on here at all.

So... I don't find either of these lexemes very pleasant, but I don't have any beautiful alternatives to offer.

# Allen Wirfs-Brock (13 years ago)

On May 18, 2011, at 3:14 PM, David Herman wrote:

I think I like <: about as much as <|. I'm not sure which is going to be more readable across a variety of fonts and sizes. <| does seem to be generally more visually distinct.

I just have to say that the pipe symbol in many fonts makes for a really hideous triangle. It doesn't line up at all with the top and bottom of the less-than/greater-than symbols.

I suspect that to most JS programmers the UML open triangle generalization arrow head is at least as relevant a precedent as any type theory uses. In other words,the relevancy of either isn't very high.

Yeah. In fact, the analogy to type theory would have us read the <: symbol as a binary predicate, which isn't what's going on here at all.

So... I don't find either of these lexemes very pleasant, but I don't have any beautiful alternatives to offer.

Dave

It's highly variable, but on average they both generally look better in a mono-spaced fonts.

# David Herman (13 years ago)

It's okay in Courier New but not in lots of other popular monospaced fonts. See attached image.

# Sean Eagan (13 years ago)

To me, the lighter weight of ~ and : make them more contextually visually distinct than | next to object, array, and regexp literal brackets [ { /

<: kind of looks like a jet with two rocket engines on the back which might be memorable. It could be called the "jet operator" or "rocket operator".

<~ has the disadvantage that it looks somewhat similar to <- and thus ->

Here's a good visual test of the possible cases, in case it helps:

p <| [] p <: [] p <~ []

p <| {} p <: {} p <~ {}

p <| /\d+/ p <: /\d+/ p <~ /\d+/

p <| function f(){} p <: function f(){} p <~ function f(){}

p <| "" p <: "" p <~ ""

p <| 1 p <: 1 p <~ 1

p <| false p <: false p <~ false

Also, whichever one is picked, why not allow it to point in either direction, just always towards the [[Prototype]] ? Using the reverse direction for different semantics in the future would be confusing. The forward direction would be useful if you only wanted the [[Prototype]] to be used by one object:

{x: "x", y: "y"} ~> { foo: function(){...}, bar: function(){...} }

# Brendan Eich (13 years ago)

On May 20, 2011, at 2:32 PM, Sean Eagan wrote:

<: kind of looks like a jet with two rocket engines on the back which might be memorable. It could be called the "jet operator" or "rocket operator".

On some fonts it looks pretty bad, though.

<~ has the disadvantage that it looks somewhat similar to <- and thus ->

<~ and <- are not backward-compatible extensions, consider function test(a,b) { return a<-b; }.

Also, whichever one is picked, why not allow it to point in either direction, just always towards the [[Prototype]] ? Using the reverse direction for different semantics in the future would be confusing. The forward direction would be useful if you only wanted the [[Prototype]] to be used by one object:

{x: "x", y: "y"} ~> { foo: function(){...}, bar: function(){...} }

The prototype object is typically named and therefore referenced on the left of the "proto operator", with an object initialiser that's must longer declaring the new object that delegates to the prototype object. This does not work well with forward-arrow, because it makes for readability eyesores like this:

var derived = {big: ..., lumpy: ..., initialiser: ..., withMethods(...) {...}} ~> proto;

where the ~> proto is lost in the ragged-right noise. Sure, you can pull it out onto its own line, but you still have the fat, lumpy initialiser squatting on it. Not pretty!

# felix (13 years ago)

On Fri, May 20, 2011 at 14:46, Brendan Eich <brendan at mozilla.com> wrote:

<~ has the disadvantage that it looks somewhat similar to <- and thus ->

<~ and <- are not backward-compatible extensions, consider function test(a,b) { return a<-b; }.

how about the fish operator <><, easy to type.

it clashes with e4x syntax, but I think it's unambiguous in the same way / is.

# Allen Wirfs-Brock (13 years ago)

Here is another sequence that might not be too bad: :<

var x = proto :< {a:1, b:2};

or :<=

Courier proto :< {a:1, b:2}

Courier new proto :< {a:1, b:2}

Menlo proto :< {a:1, b:2}

Monaco proto :< {a:1, b:2}

Lucida console proto :< {a:1, b:2}

Comic Sans proto :< {a:1, b:2}

# Andreas Rossberg (13 years ago)

On 21 May 2011 01:16, felix <felix8a at gmail.com> wrote:

how about the fish operator <><, easy to type.

Whow, apparently, you are not cursed with a German keyboard. ;)

Seriously, "easy to type" is an argument that is highly subjective to i18n-related concerns. The majority of JS programmers does not have English keyboard layout. (I wish the guy who invented SGML syntax had also known this...)