[Proto-Scripty] Re: Why is there a $super-Parameter?

2011-03-25 Thread Luke
Ok, Thanks a lot (again!) T.J.! :)

-- 
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com.
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.



[Proto-Scripty] Re: Why is there a $super-Parameter?

2011-03-24 Thread joe t.
i'd been kicking the sand wondering if i should go ahead and ask you
to re-post that link, because i'd seen it months ago and then lost it.

Glad this came up again (as i'm sure it will in the future) so i could
just jump at the link and say thank you.

And you're exactly right about the complexity trade-off. Had your
approach been implemented in Prototype to save on performance, i never
would have understood it when i first started learning Prototype. Now
that i know it really well, and understand the fundamentals of "this"
much better, i'm going to adopt your method.
-joe t.


On Mar 18, 12:13 pm, "T.J. Crowder"  wrote:
> Hi again,
>
> Sorry for the double-post, somehow I managed to forget to say: My
> mechanism isn't just (slightly) more long-winded, it's also more
> complex to understand -- it demands more of the programmer. That's its
> real downside, not the trivial difference in the length of
>
>     method.$super.call(this, arg);
>
> vs.
>
>     $super(arg);
>
> To use my mechanism, you have to understand how JavaScript functions
> and the `this` keyword work, and it's very easy to make mistakes like
> this:
>
>     method.$super(arg);
>
> ...which fails when the parent class's code tries to use `this`.
>
> So it's about trade-offs. Prototype's mechanism is more newbie-
> friendly, and there's real strength in that. My mechanism is
> dramatically more efficient, and quite easy to use once you understand
> the language a bit better, but not for newbies.
>
> -- T.J. :-)
>
> On Mar 18, 4:01 pm, "T.J. Crowder"  wrote:
>
>
>
>
>
>
>
> > Hi Ryan,
>
> > > Just want to point out that the "marked runtime cost" is only at class
> > > definition time, not instance creation nor method call time.
>
> > Actually, it's every single time anything calls a method that has the `
> > $super` argument (whether the `$super` argument gets used or not).
> > Every single call, there are multiple overhead function calls and a
> > function *creation*. Here's what happens:
>
> > 1. The call to your method is actually to a Prototype wrapper for your
> > method
> > 2. The wrapper calls `Function#bind` (yes, every time)
> > 3. `bind` calls `Array#slice`, because `bind` handles arguments
> > (although it doesn't in this case)
> > 4. `bind` creates and returns a new function
> > 5. The wrapper calls its internal `update` function to update the
> > arguments
> > 6. The wrapper calls your actual method via `apply`
>
> > If you actually *use* `$super`, then there are about five extra
> > function calls involved before the parent method actually gets called
> > (but no new functions get created).
>
> > So the runtime costs are significant, not just at `Class.create` time
> > (decompiling every public function in your class to find out whether
> > it has a `$super` argument), but also on each and every call to a
> > method with a `$super` argument (several additional function calls,
> > including creating new function objects).
>
> > Probably *at least* 95% of the time you *don't care*, but still, I was
> > pretty shocked when I found out what it was doing, which is what lead
> > me to thinking if there was a better way. My mechanism doesn't do any
> > function decompilation, doesn't create any functions when your methods
> > are called, and introduces *no* extra calls at all [a call to one of
> > your methods goes straight to your method, and your call to the parent
> > method goes straight to the parent method (unless you use an optional
> > helper function)]. But the notation is a bit longer. ;-)
>
> > How much longer? If you use proper named functions, the call can be
>
> >     method.$super.call(this, arg);
>
> > ...compared with Prototype's:
>
> >     $super(arg);
>
> > If you use anonymous functions (`method: function(arg) { ... }`), then
> > it's
>
> >     this.method.$super.call(this, arg);
>
> > I don't use anonymous functions, so I get the shorter one.
>
> > -- T.J.  :-)
>
> > On Mar 18, 2:39 pm, Ryan Gahl  wrote:
>
> > > On Fri, Mar 18, 2011 at 9:30 AM, T.J. Crowder 
> > > wrote:
>
> > > > Prototype's magical `$super` comes at a marked runtime cost
>
> > > Just want to point out that the "marked runtime cost" is only at class
> > > definition time, not instance creation nor method call time. So yeah, the
> > > performance thing is a non issue.

-- 
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com.
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.



[Proto-Scripty] Re: Why is there a $super-Parameter?

2011-03-24 Thread Luke
It's late, but I have to ask something though that it still don't 
understand. Why *doesn't* prototype just add a reference to the parent-class 
in subclasses? Like

klass.prototype.superclass = superclass

...in Class.Create. Is it because the *this*-reference would go out of 
scope?

-- 
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com.
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.



[Proto-Scripty] Re: Why is there a $super-Parameter?

2011-03-24 Thread T.J. Crowder
Hi

On Mar 24, 4:54 pm, Luke  wrote:
> It's late, but I have to ask something though that it still don't
> understand. Why *doesn't* prototype just add a reference to the parent-class
> in subclasses? Like
>
> klass.prototype.superclass = superclass
>
> ...in Class.Create. Is it because the *this*-reference would go out of
> scope?

You mean so you could reference it in instances via `this.superclass`?
Because of the grandchild problem. When you look at implementing a
superclass/subclass hierarchy with JavaScript, it's easy to create one
that will work one level deep (Parent->Child). Making it work
GrandParent->Parent->Child and deeper is difficult.

Remember that `this` always refers to the actual object, so if your
Child code calls the parent's `foo` via
`this.superclass.foo.call(this)` (recall the `.call(this)` is needed
to preserve `this`), that's fine and it works great. But what happens
when the Parent's code then does `this.superclass.foo.call(this)`?
Right! Exactly the same thing, because it's using the same property
(`superclass`) of the same object (`this`), and so it calls *itself*.
Infinite loop time.

Here are a couple of examples. I haven't used Prototype, but I've done
what Prototype would effectively be doing if it worked as you were
suggesting above:

http://jsbin.com/esalu5<-- Parent->Child, all fine and dandy
http://jsbin.com/esalu5/2  <-- GrandParent->Parent->Child, loop city

There is *no* way to use a property on `this` (inherited from the
prototype or otherwise) to refer to the superclass, not that works
more than one level deep. It can't, because if you start with `this`,
all levels are working with the same data. That's why I based my
mechanism on the actual function objects themselves; they're unique,
and they're right there to hand. :-)

HTH,
--
T.J. Crowder
Independent Software Engineer
tj / crowder software / com
www / crowder software / com

-- 
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com.
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.



[Proto-Scripty] Re: Why is there a $super-Parameter?

2011-03-18 Thread T.J. Crowder
Hi again,

Sorry for the double-post, somehow I managed to forget to say: My
mechanism isn't just (slightly) more long-winded, it's also more
complex to understand -- it demands more of the programmer. That's its
real downside, not the trivial difference in the length of

method.$super.call(this, arg);

vs.

$super(arg);

To use my mechanism, you have to understand how JavaScript functions
and the `this` keyword work, and it's very easy to make mistakes like
this:

method.$super(arg);

...which fails when the parent class's code tries to use `this`.

So it's about trade-offs. Prototype's mechanism is more newbie-
friendly, and there's real strength in that. My mechanism is
dramatically more efficient, and quite easy to use once you understand
the language a bit better, but not for newbies.

-- T.J. :-)

On Mar 18, 4:01 pm, "T.J. Crowder"  wrote:
> Hi Ryan,
>
> > Just want to point out that the "marked runtime cost" is only at class
> > definition time, not instance creation nor method call time.
>
> Actually, it's every single time anything calls a method that has the `
> $super` argument (whether the `$super` argument gets used or not).
> Every single call, there are multiple overhead function calls and a
> function *creation*. Here's what happens:
>
> 1. The call to your method is actually to a Prototype wrapper for your
> method
> 2. The wrapper calls `Function#bind` (yes, every time)
> 3. `bind` calls `Array#slice`, because `bind` handles arguments
> (although it doesn't in this case)
> 4. `bind` creates and returns a new function
> 5. The wrapper calls its internal `update` function to update the
> arguments
> 6. The wrapper calls your actual method via `apply`
>
> If you actually *use* `$super`, then there are about five extra
> function calls involved before the parent method actually gets called
> (but no new functions get created).
>
> So the runtime costs are significant, not just at `Class.create` time
> (decompiling every public function in your class to find out whether
> it has a `$super` argument), but also on each and every call to a
> method with a `$super` argument (several additional function calls,
> including creating new function objects).
>
> Probably *at least* 95% of the time you *don't care*, but still, I was
> pretty shocked when I found out what it was doing, which is what lead
> me to thinking if there was a better way. My mechanism doesn't do any
> function decompilation, doesn't create any functions when your methods
> are called, and introduces *no* extra calls at all [a call to one of
> your methods goes straight to your method, and your call to the parent
> method goes straight to the parent method (unless you use an optional
> helper function)]. But the notation is a bit longer. ;-)
>
> How much longer? If you use proper named functions, the call can be
>
>     method.$super.call(this, arg);
>
> ...compared with Prototype's:
>
>     $super(arg);
>
> If you use anonymous functions (`method: function(arg) { ... }`), then
> it's
>
>     this.method.$super.call(this, arg);
>
> I don't use anonymous functions, so I get the shorter one.
>
> -- T.J.  :-)
>
> On Mar 18, 2:39 pm, Ryan Gahl  wrote:
>
>
>
>
>
>
>
> > On Fri, Mar 18, 2011 at 9:30 AM, T.J. Crowder 
> > wrote:
>
> > > Prototype's magical `$super` comes at a marked runtime cost
>
> > Just want to point out that the "marked runtime cost" is only at class
> > definition time, not instance creation nor method call time. So yeah, the
> > performance thing is a non issue.

-- 
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com.
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.



[Proto-Scripty] Re: Why is there a $super-Parameter?

2011-03-18 Thread T.J. Crowder
Hi Ryan,

> Just want to point out that the "marked runtime cost" is only at class
> definition time, not instance creation nor method call time.

Actually, it's every single time anything calls a method that has the `
$super` argument (whether the `$super` argument gets used or not).
Every single call, there are multiple overhead function calls and a
function *creation*. Here's what happens:

1. The call to your method is actually to a Prototype wrapper for your
method
2. The wrapper calls `Function#bind` (yes, every time)
3. `bind` calls `Array#slice`, because `bind` handles arguments
(although it doesn't in this case)
4. `bind` creates and returns a new function
5. The wrapper calls its internal `update` function to update the
arguments
6. The wrapper calls your actual method via `apply`

If you actually *use* `$super`, then there are about five extra
function calls involved before the parent method actually gets called
(but no new functions get created).

So the runtime costs are significant, not just at `Class.create` time
(decompiling every public function in your class to find out whether
it has a `$super` argument), but also on each and every call to a
method with a `$super` argument (several additional function calls,
including creating new function objects).

Probably *at least* 95% of the time you *don't care*, but still, I was
pretty shocked when I found out what it was doing, which is what lead
me to thinking if there was a better way. My mechanism doesn't do any
function decompilation, doesn't create any functions when your methods
are called, and introduces *no* extra calls at all [a call to one of
your methods goes straight to your method, and your call to the parent
method goes straight to the parent method (unless you use an optional
helper function)]. But the notation is a bit longer. ;-)

How much longer? If you use proper named functions, the call can be

method.$super.call(this, arg);

...compared with Prototype's:

$super(arg);

If you use anonymous functions (`method: function(arg) { ... }`), then
it's

this.method.$super.call(this, arg);

I don't use anonymous functions, so I get the shorter one.

-- T.J.  :-)

On Mar 18, 2:39 pm, Ryan Gahl  wrote:
> On Fri, Mar 18, 2011 at 9:30 AM, T.J. Crowder wrote:
>
> > Prototype's magical `$super` comes at a marked runtime cost
>
> Just want to point out that the "marked runtime cost" is only at class
> definition time, not instance creation nor method call time. So yeah, the
> performance thing is a non issue.

-- 
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com.
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.



[Proto-Scripty] Re: Why is there a $super-Parameter?

2011-03-18 Thread Luke
Thanks a lot TJ that helps!

-- 
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com.
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.



Re: [Proto-Scripty] Re: Why is there a $super-Parameter?

2011-03-18 Thread Ryan Gahl
On Fri, Mar 18, 2011 at 9:30 AM, T.J. Crowder wrote:

> Prototype's magical `$super` comes at a marked runtime cost



Just want to point out that the "marked runtime cost" is only at class
definition time, not instance creation nor method call time. So yeah, the
performance thing is a non issue.

-- 
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com.
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.



[Proto-Scripty] Re: Why is there a $super-Parameter?

2011-03-18 Thread T.J. Crowder
Hi,

> why not just use this.superclass.method in the subclass?

If you mean:

this.superclass.method(arg);

...there are a couple of problems there. The first, which could easily
be fixed, is that the above would lose the meaning of `this` within
the call to the parent method. To preserve it, you'd need to do this:

this.superclass.method.call(this, arg);

But that won't work either, because there is no
`this.superclass.method` available (in fact, no `this.superclass`)
within the code of an instance's method: http://jsbin.com/uhitu5

The closest to `this.superclass.method` you can come is:

this.constructor.superclass.prototype.method.call(this, arg);

...which works (http://jsbin.com/uhitu5/3) but I think you'd agree is
fairly long-winded. :-) (It also assumes nothing writes to the
`constructor` property, which is *probably* a valid assumption, and
yet...)

Or you could constantly reiterate the name of your class:

ThisClass.superclass.prototype.method.call(this, arg);

...which also works (http://jsbin.com/uhitu5/2) but makes it a pain to
rename your class.

Or reiterate the name of your parent class:

ParentClass.prototype.method.call(this, arg);

...which also works but makes it a pain to rename the parent class or
rebase your class.

Regardless, compared with Prototype's magic

$super(arg);

...even the most terse of the above is verbose. :-)

Prototype's magical `$super` comes at a marked runtime cost -- not
that it usually matters -- and relies on unstandardized behavior
(function decompilation), which is probably more of a concern (as it's
known not to work on some mobile browsers). I did an alternate
mechanism that's more efficient and doesn't rely on function
decompilation, but at the cost of adding slightly to the complexity of
making the call:

method.$super.call(this, arg);

or with a helper method (which is added overhead):

this.callSuper(method, arg);

Details here, it may be useful reading for your thesis (or not):
http://blog.niftysnippets.org/2009/09/simple-efficient-supercalls-in.html

HTH,
--
T.J. Crowder
Independent Software Engineer
tj / crowder software / com
www / crowder software / com

On Mar 18, 1:13 pm, Luke  wrote:
> I'm sorry, what I meant was this.superclass In Prototype's class
> implementation you can see that if you provide a parent-class in prototype's
> Class.Create-Method, that class will be referenced as superclass in the
> class you are creating:
>
>   function create() {
>     var parent = null, properties = $A(arguments);
>     if (Object.isFunction(properties[0]))
>       parent = properties.shift();
>
>     // ...
>
>     klass.superclass = parent;
>
>     // ...
>
>     return klass;
>   }
>
> why not just use this.superclass.method in the subclass?

-- 
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com.
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.