On Mar 20, 2012, at 10:32 PM, Mark S. Miller wrote:

> I have always been suspicious of static method inheritance. Smalltalk-76 did 
> not have it. Smalltalk-80 did. Although I only ever had hands on with 
> Smalltalk-80, I always felt that Smalltalk-76 had this one right. I know 
> other smalltalkers disagree.

First off, it is wrong to call these "static methods".  There is nothing static 
about them.  We are simply talking about regular dynamic properties of a 
function object.  By using the term "static" you are making an association with 
a different concept that comes statically typed languages where "classes" are 
not first class objects.  JavaScript is not that kind of language and it is 
wrong to draw inferences from them.  I suggest that we call these "class 
properties" or "function properties".

Rather than using Java/C++ for a model and  terminology  for classes we should 
be looking at successful class-based dynamic OO languages.

Smalltalk-80 added them because they discovered that having a single set of 
behaviors for all class objects was too constraining. 
Ruby also supports class methods with inheritance.  [1] seems like a reasonable 
tutorial on using class methos in Ruby. 

[1] http://www.rubyfleebie.com/understanding-class-methods-in-ruby/ 


> 
> I think in a de-novo language like Dart or Smalltalk at the time, they are at 
> least plausible. So I find it interesting that Dart chose to avoid them. For 
> JS, I think they are disastrous because of "this" confusions. Normally, when 
> a JS method is "static", what we implicitly mean is that it is to be found on 
> a constructor function, and that the method does not depend on its 
> this-binding. For static method inheritance to make sense, many static 
> methods would instead be written to be this-sensitive. This will cause common 
> usage patterns to break.

There is no reason for this confusion.  It think you must be coming from 
thinking about class methods as "static".  Classes (functions) are just objects 
and object have properties some of which have function values.  We call such 
properties methods.  When a method is invoked on an object (eg, foo.method())  
the this minding is the target object of the invocation (eg, foo).  That is 
true regardless of whether foo is an "instance", or a function, or a class.  It 
is simply how object-oriented invocation works. 

I don't know where you got the "and that method does not depend on its 
this-binding" from.  It certainly isn't a given and it isn't the convention in 
dynamic class based languages.

If you define 

    Array.from = function(collection) {
          ...
          this
          ...
    }

and call it 
      Array.from(someCollection) 

withi the activation of that function the value of |this| is going to be Array. 
 There is no way around it. There are plenty of good reasons to use this.  
Consider a naive implementation of this function

    Array.from = function(collection) {
          let a = new Array;
          for (let v of collection) a.push(v);
          return a;
    }

I say this is naive because it has a significant problem.  Array methods are 
generally "generic" so what if we just assume that the from method is also 
generic and installed in on some other "class":

   MyArrayLike = Array.from;
   MyArrayLike.prototype = Array.prototype.push;  //push really is generic and 
will work as a method on any object

What do we get if we then say:

    MyArrayLIke.from(myCollection) instanceof MyCollection     //expect true, 
but get false

This wouldn't be the case if we had properly coded from using this:

    Array.from = function(collection) {
          let a = new this;   // <=============  this, not Array
          for (let v of collection) a.push(v);
          return a;
    }

This same idea applies if instead of copying a reference to the from function 
we had inherited it directly from Array:

    class SpecializedArray extends Array { ...};

We should be able to say:

     let s = SpecializedArray.from([1,2,3,4,5]);

an get an instance of SpecializedArray.  Referencing this in class methods is 
the key to making this all work.

> 
> For JS, because of its this-binding rules and the programming patterns that 
> have adapted to these rules,

JS this binding rules are absolutely no different from Smalltalk, Ruby, or most 
any other OO language.  The only thing that is different about JS is that it 
makes it (too) easy to  extract a method as a function without an object 
association and then to invoke that function with an arbitrary (or default) 
this value (as if, the function was installed as a method on the this value 
object).  I don't see how that latter fact has any relevance to this 
discussion.   If you extract methods you need to know what requirements they 
impose upon their this value.  This applies whether the method was defined as 
an instance method, a class method, or just as a naked function.

> I believe it is too late for static inheritance. But even if it weren't, I 
> suspect it's a bad idea anyway.

I'm quite certain that class-side inheritance is a good idea for dynamic class 
based OO languages with inheritance.   It has proven utility.  There may be 
things about that kind of language that an individual might not like.  They 
might object to dynamic, or class-based, or OO, or inheritance.  But if you 
have that combination, inheritable class methods make a lot of sense.

Allen

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to