Re: three small proposals: the bikeshed cometh!
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=enlr=q=%22prototype+%3D+[]%3B%22+lang%3Ajavascriptsbtn=Search http://www.google.com/codesearch?hl=enlr=q=%22prototype+%3D+new+Array%3B%22+lang%3Ajavascriptsbtn=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
Re: Syntax Proposal: Allow Java-like Object Literals after constructor calls to set properties on created objects.
Just out of curiosity, what's wrong with the idiomatic Javascript way of passing an object literal as your last constructor argument? So your example becomes: var stopButton = new ImageButton(this, { image: getImage('stop.png'), size: buttonSize, toolTip: 'Stop Running Scripts', onClick: stopAll }); Granted, you wind up with an extra comma... On 30 Jun, 2010, at 10:05 AM, Jürg Lehni wrote: I am still interested in hearing more feedback on this. Maybe my examples were not so clear? As more real world example, taken from a UI library that I am working with, would look like this: var stopButton = new ImageButton(this) { image: getImage('stop.png'), size: buttonSize, toolTip: 'Stop Running Scripts', onClick: stopAll }; Again, all the properties from the object literal immediately following the constructor call would then be set on the created object. Rhino allows me to use this already and it has been proven to be very useful in many occasions, leading to cleaner and more readable code. Jürg On 8 Jun 2010, at 20:57, Mike Samuel wrote: A lot of people put opening semicolons on a new line, including the Rhino authors. How would semicolon insertion in this proposal interact with that formatting convention? var runnable = new java.lang.Runnable() { run: function () { } }; 2010/6/8 Jürg Lehni li...@scratchdisk.com: This simple proposal is inspired by an extension of Rhino that currently allows to implement its syntax for anonymous Java interface implementation. Here an example that creates an anonymous class implementing the Runnable interface and defining the run method in an anonymous object literal that (mimicking a Java code block) immediately following the constructor call: var runnable = new java.lang.Runnable() { run: function() { } }; When looking deeper into how Rhino achieves this syntax, I found out that it simply appends the following anonymous object literal to the list of arguments of whatever constructor came before. So the following code works in Rhino and prints the content of the hello string to the console: function Test(obj) { print(obj.hello); } new Test() { hello: 'Greetings, I am an anonymous object literal' }; For the Illustrator scripting plugin http://scriptographer.org I came up with the convention to (ab)use this non-standard feature to allow setting of properties on freshly created objects, by extending the underlying Java proxy objects to automatically detect such a passed object literal, iterate through its properties and set them on the newly created object (In Scriptographer it is then also removed from the argument list). Soon it became apparent that this is very useful and also leads to cleaner code. I therefore started to wonder if this would make sense as an syntax extension in ES5. Here another example. function MyConstructor(param) { print(param); // Should not print the object literal } var obj = new MyConstructor() { property: 'This will be automatically set on the created object' }; print(obj.property); // 'This will...created object' So far I cannot see any syntax conflicts. I am wondering what you all think of this proposal and look forward to your thoughts. Jürg ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: standardize watch feature
On 27 Dec, 2009, at 6:12 AM, memo...@googlemail.com wrote: https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference:Global_Objects:Object:watch I really do need it for my Modell-View-Controller application. If didn't had it, I had to use That's funny, I didn't need it when I wrote the Coherent MVC library. There's no explicit call to update the UI, it's all achieved through the magic available in ES3. ES3! Not the goodness of ES5. (After all, it still has to work in IE.) modell.doSth(); modell.x++; modell.save(); where modell.save() will call the controller to reload all properties into view. With the watch feature I'm saving the last line. Property changings on the modell affects the view instantly. Now, you'll only be able to detect changes to raw properties on ES5 browsers, because IE doesn't support getters and setters, yet. But if you're willing to recraft your code to look like the following: model.doStuff(); model.setX(model.getX()+1); You'll be just fine on ES3 browsers. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: onchange event
Garrett, I gave a specific use case for why I'd like to be able to specify the name on an anonymous function: wrapping an existing function with pre- or post-call behaviour. I don't think the desire to trigger a function on change of a value is at all ludicrous. I think we should cut Memolus some slack for not being at his most articulate. On 8 Mar, 2009, at 6:51 PM, Garrett Smith wrote: Memolus does not say what he needs this for, but it sounds even more ludicrous than the recent discussion to allow [[Writable]] name to anonymous function objects created in a certain way because the Objective-J folks wanted it (what was that use case?) ___ Es-discuss mailing list Es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: name property for built-in functions??
Can I suggest that allowing writing to name may be helpful when creating transparent wrapper functions? We do a lot of this: function wrapWithChangeNotification(key, fn) { return function() { this.willChangeValueForKey(key); var result= fn.apply(this, arguments); this.didChangeValueForKey(key); return result; } } I'd love it if I could set the name on the new function to match the original function. On 4 Mar, 2009, at 1:17 PM, Brendan Eich wrote: Why in the world is name writable? js function f(){} js f.name f js f.name = 'g' g js f.name f ___ Es-discuss mailing list Es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: obsoleting the new keyword
Peter, our library makes extensive use of constructors without new as a declarative way to build a class. Consider the example: apple.EngravingGalleryController= Class.create(coherent.ViewController, { tabs: coherent.ListView('div.tabs ul', { selectedIndexBinding: 'selectedTab', animated: 'true' }), ... }); Of course, you could also use coherent.ListView as a constructor to create an explicit instance. Under the covers, the OOP mechanism dispatches to a factory function which is used to ultimately create the member. This is a lot like the Python meta-programming stuff, except I don't have an addToClass hook to use. On 14 Jan, 2009, at 9:19 AM, Peter Michaux wrote: The requirement that JavaScript needed to look like Java has long been lamented. One of the key looks was the new keyword. Many people don't like the use of the new keyword. Although new is here to stay, could we obsolete it when using a class sugar? Peter ___ Es-discuss mailing list Es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ Es-discuss mailing list Es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Allen's lambda syntax proposal
On 1 Dec, 2008, at 10:18 PM, Peter Michaux wrote: One problem is if the argument list needs to take two lambdas, then where would the second lambda go? One inside the arguments list and one after? Why is one lambda more important or deserving of a special place compared with the other lambda? I've been writing JS a long time and I don't frequently find myself wanting to pass more than one function/lambda to another function. On the (very) rare occasion when I do, I suspect I'm not calling a control-structure-like function. Then I'd be comfortable passing two lambdas as arguments. Since the goal seems to be allowing control structures like Smalltalk (yay!), how about specifying that one lambda that follows a function invocation is passed as the final argument to the invocation. You can write the invocation: withNode(node, {|n| ... }) and I'll write it as: withNode(node) { |n| ... } Some API designers won't like the trailing lambda syntax and some will. Then we end up with inconsistent APIs. I think if lambdas can be specified outside the parameter list, API designers will feel pressure from those who use their APIs to adopt the trailing lambda style. This would only be a significant issue when the API is expecting a single lambda. And regarding using the full term lambda in the syntax, I think I'm not alone that I'd have a hard time adopting lambdas over functions without a significant improvement in syntax -- and changing the name from function to lambda isn't significant. Especially considering that the initial implementations of lambdas might not hold a significant performance improvement over functions. Of course, it would also be super cool if I could write something like: { |n| hide: function() { n.style.display='none'; }, show: function() { n.style.display=''; }, etc... } Of course if I didn't have to pay the cost of instantiating a new function for every object instance, that would make something like this worthwhile. Jeff ___ Es-discuss mailing list Es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss