[+DanHHIngalls] On Fri, May 28, 2010 at 10:20 AM, Brendan Eich <[email protected]> wrote:
> On May 27, 2010, at 10:43 PM, Mark S. Miller wrote: > > *Given* that we have added egal as a separate reliable non-overloadable > operator, I would then have less objection to allowing === to be overloaded. > But should we add egal? > > I see this as much like the function vs lambda question. I long for a true > lambda, as a clean alternative to function. I long for egal, as a clean > alternative to ===. However, the argument against lambda is at least as > valid as an argument against egal: The functionality represented by lambda > or egal is already closely approximated by an existing construct in the > language. Adding another similar but subtly different construct to the > language adds more confusion and complexity than utility. Imagine how much > harder it would be to teach beginning programmers not just about function vs > constructors vs methods, but also about these vs lambda. Likewise, imagine > teaching beginning programmer not just about === vs ==, but about both of > these vs egal. > > > I agree. We can consider egal on its own, but it did come up last fall when > we were discussing value types, in particular whether === is overloadable, > even stipulating immutable value types. And something like an identity test > would seem to be necessary (as a patch to a mitigate a mistake) if we were > to allow === to be overloaded for mutable structs-as-values. > > Problem solved by requiring shallowly frozen value types. Which means they > cannot be the "structs" we've talked about this week as the array-of-structs > alternative to typed array views on a byte buffer. This is the bone of > contention Sam and I were gnawing on. > > > The downside of egal by this argument is just as bad as the downside of > lambda. The upside of lambda is much greater than the upside of egal, since > === is a much less broken egal than function is a broken lambda. > > > We've also talked about reforming function, a process begun by ES5 strict > mode, which won't culminate in function reaching the TCP nirvana of lambda. > But some of us believe that TCP, especially return in a lambda contained by > a function returning from the function (or throwing, if the lambda escaped > and outlived the function's activation) is a net loss, not a gain. > > Digression (bear with me, I hope it is worthwhile): > > I wager lambda is attractive to Smalltalk block fans, but Smalltalk does > not have first-class methods-as-funargs you can extract and pass > around. Alan Kay quote: > > "I could hardly believe how beautiful and wonderful the idea of LISP was. I > say it this way because LISP had not only been around enough to get some > honest barnacles, but worse, there were deep flaws in its logical > foundations. By this, I mean that the pure language was supposed to be based > on functions, but its most important components -- such as *lambda > *expressions, > *quotes*, and *conds *-- were not functions at all, and instead were > called special forms. *Landin *and others had been able to get quotes and > cons in terms of lambda by tricks that were variously clever and useful, but > the flaw remained in the jewel. In the practical language things were > better. There were not just EXPRs (which evaluated their arguments), but > FEXPRs (which did not). My next questions was, why on Earth call it a > functional language? Why not just base everything on FEXPRs and force > evaluation on the receiving side when needed? > > I could never get a good answer, but the question was very helpful when it > came time to invent Smalltalk, because this started a line of thought that > said 'take the hardest and most profound thing you need to do, make it > great, an then build every easier thing out of it." > [end quote] > > This criticism of LISP seems a bit off, insofar as "special form" means > only what you can't write as a macro; it does not mean "non-function". > LISP lambda as I understand it is based on one definition of "function" ( > http://en.wikipedia.org/wiki/Lambda_calculus, > http://en.wikipedia.org/wiki/Function_%28mathematics%29 -- more learned > students of programming languages and foundations of mathematics should jump > in if I'm wrong). > > What's more, what Kay said about Smalltalk does not seem accurate either: > FEXPR^H^H^H^HSmalltalk blocks are not the most profoundly primitive building > block (ahem) on which the rest of Smalltalk is built. Messaging and classes > are more primitive. Classes with (non-extractable) methods cannot be built > on blocks. (Again I hope others more expert than I am will correct me if I'm > mistaken.) > > Blocks in Smalltalk are brilliant, don't get me wrong. They're just not the > most profoundly primitive piece of the language, out of which everything > else was built. > > I may be misreading Kay -- if he means FEXPRs imply messaging and classes, > and sending a message (possibly bearing quoted code as an actual parameter) > to a class instance is the most primitive building block, then I agree. But > I don't see how FEXPRs imply classes and messaging in full (setting aside > blocks for the moment). > Brendan pointed me at < http://www.smalltalk.org/smalltalk/TheEarlyHistoryOfSmalltalk_II.html> as the source of this quote. Given that context, I do not believe Kay was speaking about what we now think of as Smalltalk blocks. Rather, I think Kay was referring to Smalltalk-72's use of dynamic scoping, inspired by Lisp 1.5, and (like Lisps of the day) the combination of dynamic scoping and delayed evaluation to support call-by-name-like functionality, in turn supporting control abstraction. Like Lisp 1.5, Smalltalk-72 suffered from the name-capture issues that result from dynamic scoping. But I don't know that people worried too much about this at the time -- especially given their focus on children programming in the small. Smalltalk-72's delayed evaluation was actually built on its delayed parsing, going even farther than Lisp in what, in retrospect, we may now judge to be the wrong direction. Fortunately, Smalltalk-72 helped inspire Actors, which combined lexical scoping and objects, which inspired Scheme, which kept the lexical scoping but lost the objects. Smalltalk-76 put lexical scoping and objects back together again, introduced the modern Smalltalk block syntax and semantics, and got rid of the delayed parsing and evaluation. I don't know whether the scoping reforms in Smalltalk-76 were directly influenced by Actors, or were indirectly influenced via Scheme. On these issues, Smalltalk-80 is essentially identical to Smalltalk-76. Smalltalk-76's blocks even had a scoping bug under block recursion that remains unfixed AFAIK in the main Squeak distribution. I am cc'ing Dan Ingalls who lived through all of this and was responsible for much of it. Dan, how far off am I? > Taking all this together, including the loveliness of blocks as message > selector arguments for building control structures, it seems to me that > lambdas aren't needed in JS, even if you don't find return in a lambda > either unwinding an outer function or failing to be confusing and likely to > be misused by non-experts. JS has first class functions, which can be used > to build classes and many other patterns, at some cost in verbosity and > (currently, mitigated by Object.freeze) loss of integrity. > > And TCP is not the highest good, or even an unmixed good in a language that > did not start out following it, and stick to it the whole way through its > evolution. > > As Allen has noted, what we miss most about Smalltalk blocks, which seemed > attractive at first in the lambda proposal, is the very concise block > syntax. This conciseness may yet be achieved, or approximated at any rate, > purely via shorthand syntax ( > http://wiki.ecmascript.org/doku.php?id=strawman:shorter_function_syntax). > If we get concise syntax, but not TCP, then lambda is even less attractive. > > End of digression. I agree that if given function (with incremental reform > under way), JS doesn't need lambda. Given ===, perhaps JS doesn't need egal. > > We should talk about egal separately -- it keeps coming up when we turn to > value types. It came up when decimal was being proposed for ES3.1 -- > remember Object.eq? > > > That said, I'm not sure I understand why this should gate anything in this > thread. Value types should be frozen (shallowly immutable) regardless, or > other things break, e.g., they could no longer be transparently passed by > copy. C# got this wrong, and paid a semantic complexity price we must avoid. > Non-frozen structs should not be value types. Frozen structs could be value > types, or could be wrapped in value types or something. > > > Agreed. Sam? > > > Given these constraints on mutability and value types, I don't see that it > matters whether the reliable comparison is named === or egal. > > > Quite agreed. > > I brought up egal, based on our value types discussion from last fall, to > buttress the case against mutable structs as value types. By assuming > mutable structs as value types and then showing how they require a true > identity relation operator, I hoped to shoot down mutable structs as value > types. On second thought, this was not the best way to take on the problems > inherent in mutable structs as value types :-P. > > C# is an Ecma and ISO standard, but that doesn't mean we should follow it > in this regard. In its defense, C#, like C++, is a static language and so > can take steps that JS cannot to preserve or recover transparency for > features such as pass by value and operator overloading. It is not a good > precedent for JS in this regard. > > > Btw, please no one suggest that egal be spelled "====". Thanks. > > > Amen! > > /be > -- Cheers, --MarkM
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

