On Mar 4, 2015, at 4:21 AM, Jason Orendorff wrote:
> Oops, accidentally sent this only to Allen.
>
and I replied as follows:
On Mar 3, 2015, at 9:34 AM, Jason Orendorff wrote:
> On Mon, Mar 2, 2015 at 5:54 PM, Allen Wirfs-Brock <[email protected]>
> wrote:
>> Pretty much everyone I've seen discover the function binding equivalent (or
>> have it explained to them for the first time) was shocked. What! 'function
>> fact(n) {return n>1? n*fact(n-1):1}' doesn't necessarily recur on the same
>> function? that's crazy! is the typical reaction.
>
> Perhaps this is a little overstated? In Scheme, Python, Lua, Ruby, and
> Smalltalk, code in a function/class/method that refer to it by name
> refer to the external binding. That binding is mutable in all those
> languages except Ruby and Smalltalk (and even in those, I think you
> *can* mutate it, but the language discourages it).
indeed:
Smalltalk at:#className put: whatever.
but it would typically be frowned upon.
>
> So basically every language in this space has the same behavior. JS
> differs only in that it has a named-function-expression syntax, which
> I think the others lack.
I agree that strictly from a binding perspective it's not particularly crazy,
but it is surprising as most programmers don't think about function and class
declarationa primarily as binding forms. The focus is on defining the entity
that is the initial value (and typically only value) of the binding rather than
on the binding itself.
The real anomaly is that the exact same function definition text (eg: `function
x() {x()}` ) in some context's creates a local binding for 'x' and in others
does not.
We can avoid that anomaly for class definitions by always providing a local
binding if an identifier follows the 'class'. If we do that, then a class
declaration like:
class x {};
can be understood and even implemented as desugaring into:
let x = class x{};
That's essentially what the ES6 spec. describes.
This gives a single internal naming semantics for all class definition which is
how most people think about it most of the time. In the rarer situations where
developer really want to manipulate the bindings, it is good that they make
that intention clear by using:
let x = class {};
>
> I can't think of a language where two bindings are created and they
> can then diverge. This is novel weirdness.
In C++/Java/C# etc. you don't see it because the corresponding declarations
create immutable bindings. I agree that it would have been nice of we could
have done that. From that perspective having an immutable class name binding
that is visible from the class body isn't novel at all. The two bindings is
simply an specification level hack to provide that without using an immutable
binding.
>
>> Similarly, it would be crazy if:
>> class Foo {
>> static makeFoo() {return new Foo}
>> }
>>
>> didn't give you a factory method that created instances of Foo.
>
> Well, you're calling every existing dynamic language with classes
> crazy. I don't think that's very useful.
Oh, it would be interesting to talk about how central (or not) the role of
binding mechanisms is in various languages, but it probably isn't going to help
us reach agreement right now.
I will add that I don't find your class wrapping use case very compelling. I
think it is much more applicable for simple functions than for classes.
Creating a high fidelity class wrapper is challenging when you factor in
things like the 'new' operator, 'instanceof', and downstream subclassing of the
now wrapped function. I don't think we're going to see nearly as often as we
see self referential class bodies.
Allen_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss