simply super

D

dylan m. austin

Hello list. This is my first message and it's nothing needful but
rather playful. I'd just like to hear some thoughts on something I
consider to be a curiosity of javascript usage. I've seen a lot of
folks looking to implement some kind of super-like functionality in
javascript and it's usually baked into some larger effort of emulating
classes. However if you really need* that type of functionality why
not get it like so:

//assuming that foo has its own sayIt property and a sayIt property in
its prototype chain
var backup = foo.sayIt;
delete foo.sayIt;
foo.sayIt(); // now, delegates up the chain
foo.sayIt = backup;

So you can see that it's easy enough to make use of javascript's built-
in property delegation/lookup to emulate super-like functionality. And
if you wanted to make easier use of that pattern:

foo.supe = function( prop ){
var backup = this[prop];
delete this[prop];
if( typeof this[prop] == 'function' ){
var r = this[prop]();
}else{
var r = this[prop];
}
this[prop] = backup;
return r;
};

foo.supe('sayIt');

So there's an example of a general purpose super-like function. It
doesn't include argument passing even though that's entirely possible.
So is that not the simplest way of getting super-like functionality?
If anyone has some feedback I'd love to hear it. I hope I've been
clear.

You can also see a more complete working example of the code at:
http://highlight.tumblr.com/post/55510055/

* I haven't personally needed super-like functionality in my
javascript coding. Apparently, neither has Crockdolf as you can now
read at the bottom of his scroll of classical javascript teachings:
"I have been writing JavaScript for 8 years now, and I have never once
found need to use an uber function. The super idea is fairly important
in the classical pattern, but it appears to be unnecessary in the
prototypal and functional patterns. I now see my early attempts to
support the classical model in JavaScript as a mistake."
from: http://javascript.crockford.com/inheritance.html
 
D

David Mark

Hello list. This is my first message and it's nothing needful but
rather playful. I'd just like to hear some thoughts on something I
consider to be a curiosity of javascript usage. I've seen a lot of
folks looking to implement some kind of super-like functionality in
javascript and it's usually baked into some larger effort of emulating
classes. However if you really need* that type of functionality why
not get it like so:

The larger effort is largely a misguided attempt to make JavaScript
work like Java (or other languages with classical inheritance
patterns.)
//assuming that foo has its own sayIt property and a sayIt property in
its prototype chain
var backup = foo.sayIt;
delete foo.sayIt;
foo.sayIt(); // now, delegates up the chain
foo.sayIt = backup;
Yikes.

https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Global_Objects/Function/Call


So you can see that it's easy enough to make use of javascript's built-
in property delegation/lookup to emulate super-like functionality. And
if you wanted to make easier use of that pattern:

foo.supe = function( prop ){
  var backup = this[prop];
  delete this[prop];
  if( typeof this[prop] == 'function' ){
    var r = this[prop]();
  }else{
    var r = this[prop];
  }
  this[prop] = backup;
  return r;

};

foo.supe('sayIt');

So there's an example of a general purpose super-like function. It
doesn't include argument passing even though that's entirely possible.

Of course.
So is that not the simplest way of getting super-like functionality?
If anyone has some feedback I'd love to hear it. I hope I've been
clear.

It is easy enough to invoke a method of the "super" object. What is
trickier is doing it without mentioning the object by name.
You can also see a more complete working example of the code at:http://highlight.tumblr.com/post/55510055/

* I haven't personally needed super-like functionality in my
javascript coding. Apparently, neither has Crockdolf as you can now
read at the bottom of his scroll of classical javascript teachings:
"I have been writing JavaScript for 8 years now, and I have never once
found need to use an uber function. The super idea is fairly important
in the classical pattern, but it appears to be unnecessary in the
prototypal and functional patterns. I now see my early attempts to
support the classical model in JavaScript as a mistake."
from:http://javascript.crockford.com/inheritance.html

Too bad the Prototype crowd hasn't read this. Would you post a link
at the bottom of one of their blogs?
 
D

dylan m. austin

Yikes.

Sure, good ol' call. I'm glad you mention it but to use it you've got
to find your own way reference the function you want to call. As you
also said:
It is easy enough to invoke a method of the "super" object.  What is
trickier is doing it without mentioning the object by name.

So that's exactly what temporary removal of the local property
achieves, you don't have to reference the 'super' object.
Too bad the Prototype crowd hasn't read this. Would you post a link
at the bottom of one of their blogs?

The quote from Crockford's page? I can't be sure they haven't read it
and besides I'm not familiar with the crowd or their blogs.
 
D

David Mark

Sure, good ol' call. I'm glad you mention it but to use it you've got
to find your own way reference the function you want to call. As you


So that's exactly what temporary removal of the local property
achieves, you don't have to reference the 'super' object.

In a very clumsy way. I wouldn't recommend that method.
 
J

Jorge

In a very clumsy way.  

Crockford does mention exactly this in one of his videos, when while
explaining the prototype chain somebody asks "What happens if a
property is deleted from an instance ?"

I wouldn't recommend that method.

Which would you recommend ?
 
D

David Mark

Crockford does mention exactly this in one of his videos, when while
explaining the prototype chain somebody asks "What happens if a
property is deleted from an instance ?"



Which would you recommend ?

I agree with the Crockford quote. Trying to implement classical
inheritance patterns with an ECMAScript-based language is a waste of
time.
 
G

Gregor Kofler

Jorge meinte:
Crockford does mention exactly this in one of his videos, when while
explaining the prototype chain somebody asks "What happens if a
property is deleted from an instance ?"

But does he endorse it?

Gregor
 
P

Peter Michaux

* I haven't personally needed super-like functionality in my
javascript coding. Apparently, neither has Crockdolf as you can now
read at the bottom of his scroll of classical javascript teachings:
"I have been writing JavaScript for 8 years now, and I have never once
found need to use an uber function. The super idea is fairly important
in the classical pattern, but it appears to be unnecessary in the
prototypal and functional patterns. I now see my early attempts to
support the classical model in JavaScript as a mistake."
from:http://javascript.crockford.com/inheritance.html

I don't see how the prototypal-based or class-based systems have
anything to do with needing super-like functionality. These are
unrelated issues.

Peter
 
P

Peter Michaux

The larger effort is largely a misguided attempt to make JavaScript
work like Java (or other languages with classical inheritance
patterns.)

I disagree. Classes are a pattern. Prototypes are a pattern. Each is
useful in different situations. It just so happens that JavaScript has
some in-language support for the prototype style. JavaScript is very
capable of expressing the class style because JavaScript functions are
lambdas (more or less.) "Structure and Interpretation of Computer
Programs" has many elegant uses of the class style in Scheme and
Scheme doesn't have any particular language support for any OOP
programming style. Lambdas are all it takes. To throw away the option
of using the class style where it is appropriate just because
JavaScript doesn't have bits os syntax sugar for it would be a shame.

It looks like the next major revision of ECMAScript will have some
sort of class construct in it. The interesting thing about how the
committee seems to be designing it is that these classes are just
sugar for the prototype-based system.

Peter
 
D

David Mark

I disagree. Classes are a pattern. Prototypes are a pattern. Each is
useful in different situations. It just so happens that JavaScript has
some in-language support for the prototype style. JavaScript is very
capable of expressing the class style because JavaScript functions are
lambdas (more or less.) "Structure and Interpretation of Computer

Certainly it is.
Programs" has many elegant uses of the class style in Scheme and
Scheme doesn't have any particular language support for any OOP
programming style. Lambdas are all it takes. To throw away the option
of using the class style where it is appropriate just because
JavaScript doesn't have bits os syntax sugar for it would be a shame.

I don't know. I don't regularly use languages with classes.
JavaScript is my most used language and I just never found the need to
simulate classes to do anything. Now as this thread has been largely
about calling a "super method", I agree with your comment that it
isn't relegated to classical inheritance patterns. That I do use and
due to the well-documented clumsiness of using constructors, it is
always a little awkward. I just see classes as even more awkward for
ECMAScript.
It looks like the next major revision of ECMAScript will have some
sort of class construct in it. The interesting thing about how the
committee seems to be designing it is that these classes are just
sugar for the prototype-based system.

I'm not paying any attention to them. If they ever produce a
specification, I'll read it.
 
P

Peter Michaux

I don't know.  I don't regularly use languages with classes.
JavaScript is my most used language and I just never found the need to
simulate classes to do anything.  Now as this thread has been largely
about calling a "super method", I agree with your comment that it
isn't relegated to classical inheritance patterns.  That I do use and
due to the well-documented clumsiness of using constructors, it is
always a little awkward.

It sure is awkward, unfortunately.
I just see classes as even more awkward for
ECMAScript.
[snip]

I'm not paying any attention to them.  If they ever produce a
specification, I'll read it.

I'd be willing to bet they at least get 3.1 out in 2009.

http://wiki.ecmascript.org/doku.php?id=es3.1:es3.1_proposal_working_draft

Peter
 
D

dylan m. austin

I disagree. Classes are a pattern. Prototypes are a pattern. Each is
useful in different situations. It just so happens that JavaScript has
some in-language support for the prototype style. JavaScript is very
capable of expressing the class style because JavaScript functions are
lambdas (more or less.) "Structure and Interpretation of Computer
Programs" has many elegant uses of the class style in Scheme and
Scheme doesn't have any particular language support for any OOP
programming style. Lambdas are all it takes.

I'll bet classical style works quite well for a ton of situations.
Think of all the real live working code written with it. Still, a lot
of effort has probably been spent in classical approaches with
javascript in situations where it might not be necessary or even best.

It'd be interesting to see those Scheme/lambda concepts from the
source you mention applied to javascript. You haven't already covered
something like that in your blog have you? Or have you seen anything
like that around?
 
P

Peter Michaux

I'll bet classical style works quite well for a ton of situations.
Think of all the real live working code written with it. Still, a lot
of effort has probably been spent in classical approaches with
javascript in situations where it might not be necessary or even best.

It'd be interesting to see those Scheme/lambda concepts from the
source you mention applied to javascript. You haven't already covered
something like that in your blog have you? Or have you seen anything like that around?

No I haven't seen the SICP examples translated to JavaScript. If you
read SICP, which I whole heartedly recommend as the best reading a
JavaScript programmer could do, you won't have any trouble translating
the OOP examples to JavaScript.

The only real issue with the way OOP is done in SICP, when translated
to JavaScript, is performance. Using the built-in message dispatch is
faster than each object being its own dispatch function. For example,
in JavaScript you might have

var o = {
foo: function() {return 1;},
bar: function() {return 2;}
};

o.foo();
o.bar();

In the SICP style, an object is a function of its messages. In a
really naive use of the SICP style it might be

var o = function(message) {
if (message == 'foo') {
return 1;
}
else if (message == 'bar'){
return 2;
}
else {
throw new Error('unknown message');
}
};

o('foo');
o('bar');

In the above the if--else-if conditionals need to be tested in
sequence (grows linearly in time with more messages) which is slower
than in the first version using dot notation for method dispatch.

A slightly more sophisticated implementation of the SICP style
taylored to JavaScript might be

var o = (function() {

var messages = {
foo: function() {
return 1;
},
bar: function() {
return 2;
}
};

return function(message) {
var args = Array.prototype.splice(arguments, 0);
args.shift();
return messages[message].apply(null, args);
};

})();

o('foo');
o('bar');

In this example a hashing algorithm probably finds the appropriate
property of the messages object and that is roughly constant in time.

----

You can see that in the SICP style, the object is its own dispatch
function. This makes all sorts of things possible. For example, method
missing is easy

return function(message) {
var args = Array.prototype.splice(arguments, 0);
args.shift();
if (messages.hasOwnProperty(message)) {
return messages[message].apply(null, args);
}
else {
return methodMissing.apply(null, args);
}
};

o('foo');
o('asdf'); // uses methodMissing

----

Performance is important and so having objects be their own dispatch
functions should only be used when necessary.

----

The unfortunate part is people are also caught up about syntax. I
don't really care if I write any of the following three

o.setProp(5);
o.prop = 5;
o('prop=', 5);

because I'd rather be writing

(o 'prop= 5)

anyway because then hygenic macros would be available :)

The semantics of the above four could all be the same. That is, a
setter function runs.

----

If you like this sort of thing I think you would enjoy SICP and you
get to learn Scheme along the way which is a beautiful thing.

http://www.amazon.com/Structure-Int...d_bbs_1?ie=UTF8&s=books&qid=1225432918&sr=8-1

My favorite programming book.

Peter
 
G

Gregor Kofler

dylan m. austin meinte:
It's not likely. Did you see the excerpt from his writing included at
the bottom of the first message in this thread?

I'm pretty sure he doesn't. Though Jorge's post left an impression, as
Crockford "advocates" this approach.

Gregor
 
J

Jorge

dylan m. austin meinte:


I'm pretty sure he doesn't. Though Jorge's post left an impression, as
Crockford "advocates" this approach.

That wasn't my intention. But this is unrelated to the classical vs
prototypical inheritance debate, as Michaux has noted already.

If we leave that debate aside, the answer to dylan (the OP) shouldn't
be just "what a clumsy method" "I wouldn't recommend it" kind of "junk
junk !", unless you tell as well what a better way of doing it is.

I'd repeat the question I made to David Mark: which method would you
use ?
 
J

Jonathan Fine

Jorge said:
I'd repeat the question I made to David Mark: which method would you
use ?

Here's a couple of blog posts. I'm surprised that no-one have mentioned
John Resig's yet.

http://ejohn.org/blog/simple-javascript-inheritance/
http://jonathanfine.wordpress.com/2008/09/21/implementing-super-in-javascript/


Here's an extract of the key piece of code in my blog:
====
var sup = function(klass, name){
return function(){
var fn = klass.proto[name];
return Function.call.apply(fn, arguments);
};
};
====

It may take you white to understand Function.call.apply.
 
D

dylan m. austin

If we leave that debate aside, the answer to dylan (the OP) shouldn't
be just "what a clumsy method" "I wouldn't recommend it" kind of "junk
junk !", unless you tell as well what a better way of doing it is.

I'd repeat the question I made to David Mark: which method would you
use ?

Thanks Jorge. I've gotta second you on this. For those that have used
the super-like concept at some point, how was it implemented?

We've seen a message from David Mark admitting use of something super-
ish. I inferred that it might make use of constructor references and
therefore would differ considerably from the pattern I presented.
Though he made it sound as if it's still a bit awkward. Better than
clumsy, right ;) Let's see it.

Thanks everyone. I'm enjoying this discussion even if we derail a bit.
 
D

David Mark

That wasn't my intention. But this is unrelated to the classical vs
prototypical inheritance debate, as Michaux has noted already.

If we leave that debate aside, the answer to dylan (the OP) shouldn't
be just "what a clumsy method" "I wouldn't recommend it" kind of "junk
junk !", unless you tell as well what a better way of doing it is.

I'd repeat the question I made to David Mark: which method would you
use ?

I answered that (the call method.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top