On Friday, June 8, 2012 at 8:29 PM, Jimb Esser wrote: > Binding more than once is very common > >
The bound function returned by fn.bind cannot be rebound and will silently ignore any attempts to do so. > - any code that is written with > a closure instead can be written with a static function and a .bind > (and, in general, be more efficient, causing less heap pressure). > > I think you might be misusing terminology. Perhaps you could share a code example that illustrates your claim? Rick > > But, yeah, the immediate bind vs call was just in response to AJs > query, and it's pretty clear there's no reason to do that > (unless .bind was magically efficient, which it's not, it's just > generally more efficient than a new closure). > > > > On Jun 8, 5:22 pm, Rick Waldron <[email protected]> wrote: > > On Fri, Jun 8, 2012 at 7:23 PM, Jimb Esser <[email protected]> wrote: > > > [Moved to nodejs instead of nodejs-dev since this is of general interest > > > and only tangental to the original request] > > > > > > > > > > I've never thought of using .bind instead of .call, but since .bind does > > > allocate something, and .call theoretically doesn't have to, I'd just > > > assume .call is more efficient, though I've learned any performance > > > assumptions about JS are usually incorrect ^_^. > > > > > > > > > > Doing a quick jsperf test of the things discussed here: > > > http://jsperf.com/bind-vs-call2 > > > Results are... questionable, and I don't put too much stock in micro-tests > > > like this, as the optimizer is good at making them go fast in inconsistent > > > ways. But, anyway, f.call(o) is way faster than f.bind(o)(), which is not > > > surprising. Slightly surprising, .bind seems to underperform closures > > > significantly in this case, though (at least on the older version of V8 > > > node is using), in real-world apps (at least, ours), I'm pretty certain > > > .bind is generally better... also allocates less memory (although in a > > > micro-test like this V8 likely effectively optimizes out any memory > > > allocations from the no-op closures). > > > > > > > > > This comparison is unbalanced -- when would you ever bind() more then once? > > The bound function cannot be rebound. Furthermore, when would you ever > > bind() and immediately execute? Never - because the correct approach is to > > use call() when immediate invocation is required. bind() is one shot deal > > that returns a new bound function to be called later. > > > > Rick > > > > > > > > > > > > > > > > > > > > > - Jimb Esser > > > > > On Fri, Jun 8, 2012 at 3:14 PM, AJ ONeal <[email protected]> wrote: > > > > > > Interesting. So have you found bind() to be more or less efficient than > > > > .call() and or .apply()? > > > > > > > > > > > > > > > AJ ONeal > > > > > > On Fri, Jun 8, 2012 at 3:48 PM, Jimb Esser <[email protected]> wrote: > > > > > > > Technically, at least in V8, .bind is a lot lighter weight than an > > > > > anonymous function. There are a large number of micro-benchmarks to > > > > > look > > > > > at on jsperf.com, but for an actual anecdote, at one point we > > > > > accidentally required in a module which overrode > > > > > Function.prototype.bind > > > > > with something that created an anonymous function (some > > > > > browser-support > > > > > code for pre-.bind browsers), and our performance tanked, garbage > > > > > collection times increased significantly. > > > > > > > > > > > > > > > > > > > > > On Fri, Jun 8, 2012 at 2:25 PM, AJ ONeal <[email protected]> wrote: > > > > > > > > If I'm not mistaken, bind() has the same technical drawbacks as > > > > > > using > > > > > > an anonymous function (higher memory usage, more garbage > > > > > > collection, and > > > > > > slower says Tim), but it does solve the maintainability / > > > > > > prettiness issue. > > > > > > > > > > > > > > > > > > > > > > > > > > > > I just want to point out that Raspberry Pi is now shipping. > > > > > > NodeJS is a very attractive option for development. > > > > > > > > > > > > > > > > > > > > > > > > > > > > My own experience with my ARM-based media server has lead me to be a > > > > > > believer in prototypes and leaner code. I can't say that one little > > > > > > anony > > > > > > here and there is going to blow up an application, but I know for a > > > > > > fact > > > > > > that there are significant performance gains when they are avoided. > > > > > > > > > > > > > > > > > > > > > > > > > > > > I know it doesn't seem like a big deal now. But one day you may > > > > > > change > > > > > > your mind. > > > > > > > > > > > > > > > > > > > > > > > > > > > > AJ ONeal > > > > > > > > On Fri, Jun 8, 2012 at 2:22 PM, George Stagas > > > > > > <[email protected]>wrote: > > > > > > > > > No need to change the API, we have .bind() - use the language > > > > > > > features, don't reinvent them. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > 2012/6/8 Tim Caswell <[email protected]>: > > > > > > > > > > On Fri, Jun 8, 2012 at 2:10 PM, tjholowaychuk < > > > > > > > [email protected]> > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > what's wrong with .bind() ? > > > > > > > > > > Mainly the overhead. Bind creates a new function every time > > > > > > > > it's > > > > > > > called, > > > > > > > > and calling the bound function is a bit slower, especially in > > > > > > > > V8. > > > > > > > > > > > > > > (Insert > > > > > > > > statement about performance only mattering if it's > > > > > > > > significant...) > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > I usually will bind all my methods from the prototype that will > > > > > > > > be > > > > > > > used as > > > > > > > > callbacks to the instance itself inside the constructor. This > > > > > > > > gives > > > > > > > > > > > > > > me a > > > > > > > > ton more "own" properties, but otherwise is fairly elegant. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Jun 8, 11:52 am, AJ ONeal <[email protected]> wrote: > > > > > > > > > > emitter.on('data', myModule.dataHandler, myModule); > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Even if myModule were to subclass EventEmitter, wouldn't I > > > > > > > > > > still > > > > > > > need to > > > > > > > > > > pass in the `myModule` instance so that I get the correct > > > > > > > > > > `this`? > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > I > > > > > > > > > > don't > > > > > > > > > > think I understood what you meant by that. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > And then these cases as well: > > > > > > > > > > > > fs.readFile(file, encoding, myModule.fileHandler, > > > > > > > > > > myModule); > > > > > > > > > > > > process.nextTick(myModule.tickHandler, myModule); > > > > > > > > > > > > The list goes on. Obviously not a small project. Not > > > > > > > > > > difficult > > > > > > > either, > > > > > > > > > > just > > > > > > > > > > tedious. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > AJ ONeal > > > > > > > > > > > > On Fri, Jun 8, 2012 at 12:42 PM, Tim Caswell > > > > > > > > > > <[email protected] > > > > > > > > > > > > wrote: > > > > > > > > > > > Actually event emitters already call in the scope of the > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > emitter, so > > > > > > > > > > > there > > > > > > > > > > > is no need for a specific "this" value there. Just > > > > > > > > > > > subclass > > > > > > > > > > > EventEmitter > > > > > > > > > > > and use normal methods. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Fri, Jun 8, 2012 at 1:34 PM, AJ ONeal > > > > > > > > > > > <[email protected]> > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > If you're going to use `this` then you must have a > > > > > > > > > > > > callback. > > > > > > > It would > > > > > > > > > > > > make no sense to have a `this` and nothing to apply it > > > > > > > > > > > > to. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > You think EventEmitters would feel the overhead of the > > > > > > > > > > > > if? > > > > > > > > > > > > > > // context is Array, Object, or Function. > > > > > > > > > > > > // Numbers, Strings, and Booleans need not `apply` > > > > > > > > > > > > (very > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > punny) > > > > > > > > > > > > if (context) { > > > > > > > > > > > > fn.call(context, a, b, c); > > > > > > > > > > > > } else { > > > > > > > > > > > > fn(a, b, c); > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > As far as the guesswork, well, I hear you on that. I've > > > > > > > already done > > > > > > > > > > > > my > > > > > > > > > > > > ranting at UtahJS Conf. Put this as one more in the > > > > > > > > > > > > bucket of > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > reasons > > > > > > > > > > > > that > > > > > > > > > > > > callbacks-last was not a well-thought out idea.... > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > AJ ONeal > > > > > > > > > > > > > > On Fri, Jun 8, 2012 at 12:27 PM, Tim Caswell < > > > > > > > [email protected]> > > > > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > I think it's a useful addition, but it does cause a > > > > > > > > > > > > > little > > > > > > > overhead > > > > > > > > > > > > > (though it's probably not noticeable compared to the > > > > > > > > > > > > > actual > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > work the > > > > > > > > > > > > > async > > > > > > > > > > > > > function is doing). EventEmitters might feel the > > > > > > > > > > > > > pain since > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > they > > > > > > > > > > > > > are sync. > > > > > > > > > > > > > I do worry that it makes things harder for our > > > > > > > > > > > > > argument > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > guessing > > > > > > > > > > > > > code that > > > > > > > > > > > > > assumes the last arg is a callback. Now there will > > > > > > > > > > > > > be an > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > optional > > > > > > > > > > > > > argument > > > > > > > > > > > > > after the callback that can be anything (including > > > > > > > > > > > > > another > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > function) > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Fri, Jun 8, 2012 at 1:18 PM, AJ ONeal > > > > > > > > > > > > > <[email protected]> > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Yes, That's what I am suggesting. > > > > > > > > > > > > > > > > AJ ONeal > > > > > > > > > > > > > > > > On Fri, Jun 8, 2012 at 12:17 PM, Tim Caswell > > > > > > > > > > > > > > <[email protected]>wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > So this proposal is to modify the API of all async > > > > > > > functions to > > > > > > > > > > > > > > > have > > > > > > > > > > > > > > > an extra thisp argument after the callback > > > > > > > > > > > > > > > argument (like > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > done in > > > > > > > > > > > > > > > Array.prototype.forEach)? > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Fri, Jun 8, 2012 at 1:06 PM, AJ ONeal < > > > > > > > [email protected]> > > > > > > > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > I would like to propose that an additional > > > > > > > > > > > > > > > > parameter, > > > > > > > `context` > > > > > > > > > > > > > > > > be > > > > > > > > > > > > > > > > added to core node modules that accept > > > > > > > > > > > > > > > > callbacks to give > > > > > > > > > > > > > > > > this-ness to the > > > > > > > > > > > > > > > > callback. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > The reason being is that I'm trying to > > > > > > > > > > > > > > > > eliminate anonymous > > > > > > > > > > > > > > > > callbacks > > > > > > > > > > > > > > > > from my code and have generally cleaner, more > > > > > > > > > > > > > > > > readable > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > code (as > > > > > > > > > > > > > > > > well as > > > > > > > > > > > > > > > > lower memory usage and less garbage collection). > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > I don't know if this has been discussed before, > > > > > > > > > > > > > > > > but I'd > > > > > > > like to > > > > > > > > > > > > > > > > put > > > > > > > > > > > > > > > > it on the table. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > AJ ONeal > > > > > -- > > > Job Board:http://jobs.nodejs.org/ > > > Posting guidelines: > > > https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines > > > You received this message because you are subscribed to the Google > > > Groups "nodejs" group. > > > To post to this group, send email to [email protected] > > > To unsubscribe from this group, send email to > > > [email protected] > > > For more options, visit this group at > > > http://groups.google.com/group/nodejs?hl=en?hl=en > > > > > > > > > > -- > Job Board: http://jobs.nodejs.org/ > Posting guidelines: > https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines > You received this message because you are subscribed to the Google > Groups "nodejs" group. > To post to this group, send email to [email protected] > To unsubscribe from this group, send email to > [email protected] > For more options, visit this group at > http://groups.google.com/group/nodejs?hl=en?hl=en > > -- Job Board: http://jobs.nodejs.org/ Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines You received this message because you are subscribed to the Google Groups "nodejs" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/nodejs?hl=en?hl=en
