[Proto-Scripty] Re: Why is there a $super-Parameter?
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?
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?
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?
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?
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?
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?
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?
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?
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.