three small proposals: the bikeshed cometh!
Jürg Lehni
lists at scratchdisk.com
Thu Jul 8 12:33:36 PDT 2010
That's exactly why I pointed it out, apologies for not making that clearer.
On 8 Jul 2010, at 18:17, Jeff Watkins wrote:
> I would think we'd use the ghastly syntax of Java as a cautionary tale rather than something from which to draw inspiration...
>
> On 7 Jul, 2010, at 11:26 AM, Jürg Lehni wrote:
>
>> To pick up the lambda discussion again, it is maybe of interest to have an eye on the recent developments around the introductions of Lambda in Java:
>>
>> http://www.infoq.com/news/2010/06/lambda-syntax-debate
>> http://stronglytypedblog.blogspot.com/2010/06/so-you-find-java-7-closure-syntax-nasty.html
>>
>> Jürg
>>
>> On 29 Apr 2010, at 18:03, Brendan Eich wrote:
>>
>>> On Apr 29, 2010, at 12:25 AM, Alex Russell wrote:
>>>
>>>> Some small, pre-colored panels for the shed. Given that these are mostly matters of syntax and not semantics, please believe me when I suggest that the warts discussed herein present sharp edges that should be rounded off by the committee -- not because they're interesting in any way but because the primary users of the language are shipping (bad) fixes around the network billions of times a day. Such rank inefficiency needs sunset date.
>>>
>>> This is not just about syntax. Let's ignore the threat of being accused of bikeshedding and evaluate holistically.
>>>
>>>
>>>> Summary of proposals:
>>>> ---------------------
>>>>
>>>> // 1.) Really generic generics
>>>>
>>>> ArrSubtype = function() { };
>>>> ArrSubtype.prototype = Object.create(Array.prototype);
>>>>
>>>> var nas = new ArrSubtype();
>>>> nas.push("howdy", "pardner");
>>>>
>>>> nas.slice(0) instanceof Array; // currently true
>>>> nas.slice(0) instanceof ArrSubtype; // will be true after fix
>>>
>>> An incompatible change, but would it break much code? Hard to say without trying it at scale. Here are some codesearch results:
>>>
>>> http://www.google.com/codesearch?hl=en&lr=&q=%22prototype+%3D+[]%3B%22+lang%3Ajavascript&sbtn=Search
>>> http://www.google.com/codesearch?hl=en&lr=&q=%22prototype+%3D+new+Array%3B%22+lang%3Ajavascript&sbtn=Search
>>>
>>> How would it work exactly? More below on "subtyping".
>>>
>>>> // 2.) Shorthand for "function", aka the "not lambda"
>>>>
>>>> node.addEventListener("click", #(e){ e.preventDefault(); });
>>>> node.removeEventListener("click" obj!#(e){ ... }); // see #3
>>>
>>> The hash or number sign is not obviously all about functions. I've tried out the other alternatives in recent talks. No one is really enthusiastic about any of
>>>
>>> λ foo() (bar + baz)
>>> ƒ foo() (bar + baz)
>>> \foo() (bar + baz)
>>>
>>> (the foo name is optional but should be expressible).
>>>
>>> The Greek lowercase lambda is actually an incompatible change from ES3 (perfectly legal identifier there). It's also hard to type on most keyboards.
>>>
>>> The florin is easier (alt-f on my Mac) but maybe a bit visually light and hard to scan for quickly, and it's arguably harder for newcomers to divine its meaning.
>>>
>>> The \ does not make much sense, but it was proposed first among all of these on es-discuss, IIRC.
>>>
>>> One wag replied after I had people vote on these "what about voting on function"? Many hands then went up, more than for any of the above. This set the cat among the shorthand-promoting pigeons.
>>>
>>>
>>>> // 3.) Shorthand for Function.prototype.bind
>>>>
>>>> var boundMethod = obj!method;
>>>> node.addEventListener("click", obj!method);
>>>> node.removeEventListener("click", obj!method);
>>>
>>> There's some precedent for ! as non-blocking send, returning a promise.
>>>
>>>
>>>> NodeList.prototype.parents = function() {
>>>> // should return a NodeList
>>>> return this.map(function(n) { return n.parentNode; });
>>>> }
>>>
>>> IIRC a NodeList is a "live array", sort of a query-as-array or cursor that is continuously updated when the DOM mutates. It's really not an Array.
>>>
>>>
>>>> * Kill code in libraries that exists only to wrap built-in methods thanks to existing mis-specification of generics
>>>> * Sub-types of Array suffer many warts, but making Array.prototype methods return instances of subtypes will allow DOM-side changes to make subtyping much more natural in real-world systems
>>>
>>> "Subtype" is not well-defined in JS. Prototype-based delegation is not the <: relation from type theory, because of mutation, both of the prototype object and of the future binding of f in a scope and f.prototype in user-defined function f.
>>>
>>> This isn't just a pedantic point. If we don't have a well-defined relation, how can we evaluate proposals that want to improve support for that relation, whatever it is?
>>>
>>> In this case it seems to me you might want the result of Array generics to be created by calling (new this.constructor). For nas.slice(0), the generic slice code would then put elements got from |this| into the result of (new this.constructor). Is this the spec you want?
>>>
>>> If so, it seems like an improvement, but again constructor has low integrity (none for user-defined constructor functions) without freeze, so there's no subtype relation in the formal <: sense. Still, it seems to me an improvement, ignoring the incompatibility.
>>>
>>>
>>>> // equivalent:
>>>> function(){ return 10; }
>>>> #(){ return 10; }
>>>> #{ return 10; } // no args, optionally elide ()
>>>
>>> This does several things at once, and we have discussed one of them: turning the completion value of the body into the return value.
>>>
>>> The objection to this, voiced clearly by Waldemar, is the unintended completion value in tail position leaking out as a return value. This is hard to see and test for, and it requires ugly void operator usage, or a dummy final value, to control.
>>>
>>> Dave Herman has recently proposed http://wiki.ecmascript.org/doku.php?id=strawman:let_expressions, which include an explicit "completion value here" prefix: => 10; in tail position would result in 10, and without => the result would be the undefined value.
>>>
>>>
>>>> * equivalent semantics to the function(){} syntax
>>>
>>> No, not equivalent because tail position completion values are not return values with functions. Again semantics matter, not just syntax.
>>>
>>>
>>>> 3.) Syntax for bound function de-reference
>>>> [snip] So why does this suck? Two reasons: it's long-ish to type, and it doesn't do what the dot operator does -- i.e., return the same function object every time.
>>>
>>> The lack of memoization is a good point. I've written at length about the challenges for implementations to "join" function objects as an optimization:
>>>
>>> https://mail.mozilla.org/pipermail/es-discuss/2010-February/010830.html
>>> https://mail.mozilla.org/pipermail/es-discuss/2010-February/010832.html
>>>
>>>
>>>> What to do? We propose the bang operator -- ! -- as a new form of binding de-reference of function objects. It's one character and even includes a dot. It has the following additional properties:
>>>>
>>>> 1.) all de-references via bang from an object/function pair return the *same* function object (modulo #4).
>>>> 4.) bang-bound functions are weakly referenced. If GC would otherwise remove a function object from memory, having previously bang-bound a function should not keep the function object alive
>>>
>>> This is a tricky area. We have experience with such ephemeral objects. Problem is, sometimes users decorate them with ad-hoc properties ("expandos"), which by your proposed rules will not keep them alive. The GC runs, and the decorator is surprised to see the ad-hoc properties gone.
>>>
>>> Apart from the ! as promise-send and weak-vs.-expando issues, the big objection here is that you make each reference specify bound-ness and require memoization on the fly. An alternative would be to bind at method definition point. Then you could only extract the bound method, no matter how used, and via the conventional . operator. See
>>>
>>> http://wiki.ecmascript.org/doku.php?id=strawman:obj_initialiser_methods
>>>
>>> i'm against "invoke-only" methods, but bound method definition syntax is easier for users and implementors to swallow, and preserves dot as the one operator needed for extraction. It would also make the method reference strong, which would avoid the too-weak loss of expando problem.
>>>
>>> Glad to see this proposed for discussion -- good suggestions, directionally and in some details.
>>>
>>> /be
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>
More information about the es-discuss
mailing list