> If subclass foo can call super.bar() and the superclass bar calls this.foo(), 
> what happens? Java without final before the method is like C++ with virtual 
> before the method. The subclass foo() will be called.
> 
> Often, especially if you buy Anders' arguments, you want what Peter Michaux 
> has called a sideways call from the superclass bar, to lexical foo(). You can 
> do that and prevent overrides from subclasses. This is not always the right 
> thing, but it seems like the right default.

It probably makes sense to distinguish between preventing overriding and static 
dispatch:
- AFAIK, Java always does dynamic dispatch and has virtual instance methods. 
final “merely” prevents overriding. But that does indeed reduce the hooks that 
Hejlsberg talks about.
- With static dispatch, you can override which also might lead to unintended 
effects.

The problem seems to be that a public method plays two roles: It is an 
interface to the clients of a class, but also an interface to the methods of 
the class itself. In Java, when I want a method to exclusively play the latter 
role then I make it private. Maybe a method should never call sibling public 
methods, only private ones.

I’ve done overriding to contribute to an API, but also to patch something (to 
avoid copy-pasting code – a hack, but still needed). The former is part of the 
design, the latter is necessary for use cases that cannot be predicted. I’m 
less paranoid about the wrong method being overridden than about a method that 
one wants to be overridden not being called from the overriding method. That 
is, I’m usually paranoid about clients not adhering to the protocol of my API. 
Thus, I like anything that helps me with expressing the protocol and ensuring 
that no mistakes are made. I only want to enforce something if it helps the 
previous two goals. In this vein, “private by naming convention” is enough for 
me. Obviously, different rules apply when security is a concern.

How about a marker saying “this method can be overridden” (enable, don’t 
prevent)? If a method does not have this marker it could still be overridden, 
but one would have to expend extra effort to prove that one knows what one is 
doing (similar to suppressing generics-related type warnings in Java).

I’m not sure how much of the above applies to JavaScript, though, because you 
need dynamic dispatch to make shared methods work. And things being so simple 
and flexible is part of JavaScript’s charm.


> I asked Jeremy Ashkenaz about CoffeeScript's super()-only restriction, 
> modeled on Ruby. He wrote back:
> 
> "The rationale [is] that if you're overriding an implementation of a method, 
> you're responsible for preserving the proper API at that point. By reaching 
> behind the back of an overridden function, and calling its parent 
> implementation without going through it, you're saying that the override was 
> done wrong, or doesn't preserve the API you need.
> 
> This is basically the difference between Java super and Ruby super.
> 
> I'd be very curious to see an example of an inheritance pattern that relies 
> on being able to call super() against "other" methods."

A very good point. AFAIK, Common Lisp only has next-method calls and no generic 
super calls. [As an aside, from what I have seen of Common Lisp, it is a great 
mix of dynamic language features and static language features.]

-- 
Dr. Axel Rauschmayer

[email protected]
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



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

Reply via email to