Look Ma, no "this" (was: ECMAScript Harmony)

Peter Michaux petermichaux at gmail.com
Sun Aug 24 20:40:07 PDT 2008


[order restored]

On Sun, Aug 24, 2008 at 7:41 PM, Brendan Eich <brendan at mozilla.org> wrote:
>
> On Aug 24, 2008, at 7:36 PM, Peter Michaux wrote:
>
>> On Sun, Aug 24, 2008 at 6:05 PM, Brendan Eich <brendan at mozilla.org> wrote:
>>>
>>> On Aug 24, 2008, at 4:09 PM, Mark S. Miller wrote:
>>
>> [snip]
>>
>>> Others on this list should comment on class-private vs. instance-
>>> private.
>>
>> If this is just a poll then I'm all for instance-private.
>
> Polls are not so good, compared to reasons. Could you give your rationale
> and talk about the trade-offs, in your experience?

You summed it up nicely with the hat trick:

"It's a nice hat trick: privacy, higher integrity, and semantic reuse
all in one."

I'm not sure there will be anyone who can explain that any one OOP
system is right and the others are less right. That is what I imagine
will make consensus on this topic very difficult.. Every OOP language
has a different set of OOP features so there doesn't appear to be an
objective (ha!) winner after decades of programmers exploring OOP. The
fact that this is really a subjective issue is why your initial
request for comments seemed somewhat appropriate for a poll. It is a
"what do you like" question.

Some folks like all the bells and whistles for easy code reuse (e.g.
inheritance and template pattern) and controlling various levels of
privacy (e.g. public, protected, private, friends, enemies).

I always seem to end up on the side of keeping things simple (which
perhaps aligns well with security issues appropriate to the web and
the initial ease of use JavaScript was designed to have.) To me
instance-private and zero inheritance are simple. It is easy to read
code written this way. Instance-private and zero inheritance makes it
easy to reason about how instance state can be changed. There is no
hunting up and down the inheritance tree to figure out which ancestor
is changing which property of some desendent class instance. That is a
real pain. There is no wondering if another instance of the same class
is bypassing a setter method it should be using because of
class-private variables.

I've been using the closure-based OOP style with zero inheritance the
last while (~4 or so months) and it has been a large sigh of relief
compared with trying to make prototype-based inheritance have private
variables and "super". This style is approximately what seems to have
been discussed as the desugared version of classes. I haven't
encountered any downsides that are problematic to me or that I'm not
willing to pay in the set of trade-offs. I haven't needed
class-private perhaps because I just don't think that way or it isn't
very useful. I have used languages where class-private is available
and didn't use it there either.

While I'm at it the keyboard typing, one thing I really like about the
closure-based OOP is it is not based on message passing (at least I
would say it isn't the traditional style of message passing because
there doesn't *need* to be a receiver). The constructor returns an
object which is a hash of closures, none of which use "this". Each of
these closures can be assigned to another variable or another object
and that other object cannot access the private variables of the first
object. This is good in a language where it *is* possible to "borrow"
any function from any object and still not have to worry about "this".
An elegant example is the observer pattern. Here is a bit of silly but
small example off the top of my head but shows the idea and benefit.

var makeSubject = function() {
  var listeners = [];
  return {
    subscribe: function(){},
    unsubscribe:function(){},
    fire: function(){}
  };
};

var makeDailyEvent = function() {
  var s = makeSubject();
  setInterval(s.fire(), 24*60*60*1000);
  return {
    subscribe: s.subscribe,
    unsubscribe: s.unsubscribe
  };
};

Because the closures of a Subject object can be borrowed directly
there is no need to write the trivial but possibly many wrapper
methods for manual delegation in a Java class where "has a" (as
opposed to "is a") has been used. So the zero-inheritance issue is not
as big an issue in JavaScript. The fact that the "listeners"
instance-private array does not become instance-private to the
DailyEvent object when the Subject methods are borrowed means I know
the "listeners" array is very private.

I've talked about both privacy and inheritance when you only requested
about privacy but the two issues are closely related.

Peter


More information about the Es-discuss mailing list