Overloading lambda's in C++11
Een C++ proposal dat lambda expressions generiek maakt (ofwel, templated arguments), N3418, bespreekt toevallig ook een techniek om lambda's te overloaden die momenteel in C++11 al werkt en die ik jullie niet wilde laten ontgaan. Leipe shit, ouwe!
C++:
Lambda's zijn stiekem gewoon classes met een operator(). Je kunt er dus van overerven, en bovenstaande truc werkt dan ook door een class van twee lambda's over te laten erven en beide operator()'s in de huidige scope te stoppen dmv een using declaration.
Bovenstaande code is ook uit te breiden zodat hij werkt met een arbitrair aantal lambda's, en daarnaast ook met losse functies en pointer-to-members:
C++:
Werkt in zowel VC++ met November '12 CTP compiler als in GCC 4.7.2
C++:
1 | template<class F1, class F2>
|
Lambda's zijn stiekem gewoon classes met een operator(). Je kunt er dus van overerven, en bovenstaande truc werkt dan ook door een class van twee lambda's over te laten erven en beide operator()'s in de huidige scope te stoppen dmv een using declaration.
Bovenstaande code is ook uit te breiden zodat hij werkt met een arbitrair aantal lambda's, en daarnaast ook met losse functies en pointer-to-members:
C++:
1 | #include <iostream>
|
Werkt in zowel VC++ met November '12 CTP compiler als in GCC 4.7.2
A more useful bind() for Javascript 
bind or similar functionality has been a part of many javascript codebases and has made its official introduction in Javascript 1.8.5. Coming from a C++ background myself, where std::bind made its way through the TR1 library into standard C++11 after years of perculating within the boost library, I found that Javascript's version is lacking in certain features.
Recently this blog post was brought to my attention. Disregarding the underlying message of the post for the moment, the issue at hand was that the following Javascript expression:
JavaScript:
resulted in:
JavaScript:
While this might not be very intuitive for the average non-javascript developer, the actual problem lies in the fact that Array.prototype.map calls the supplied callback with 3 arguments (respectively: value, index and the array being mapped), and that parseInt accepts 2 - value and radix - with the latter being optional. Thusly, the array indices 0 through 4 are being interpreted as radix, causing the string '10' to be parsed for all 5 radices.
API design considerations aside, it would've been nice if we somehow were able to express: hey, I have this function accepting 2 argument, and I'd like to bind the second argument to a fixed value. Sounds like a job for... (queue drumroll)... Function.prototype.bind()! Well, it sounds like that, except that it really isn't. It would've suited the job perfectly if you wanted to fix the first argument, but the second? Come on! Been smoking crack lately?
And of course, some might say that simply using a lambda would suffice:
JavaScript:
and some would be right. But then what is the point of bind's existence, really? Would it not have been cool if you could simply use bind to say: pass the first argument through, but set the second argument to 10. For example, using this syntax:
JavaScript:
Well, you can now
. Inspired by C++'s std::bind, I've implemented a new version, Function.prototype.bind2(). Specifically, one that also accepts the following placeholders as its arguments:
JavaScript:
Source code:
JavaScript:
Disclaimer: I'm not a javascript afficionado. I know above code polutes the global namespace (in particular with the Placeholder constructor), and you might not want that. You could wrap it in a local scope if you want...
Recently this blog post was brought to my attention. Disregarding the underlying message of the post for the moment, the issue at hand was that the following Javascript expression:
JavaScript:
1 | ['10','10','10','10','10'].map(parseInt); |
resulted in:
JavaScript:
1 | [10, NaN, 2, 3, 4] |
While this might not be very intuitive for the average non-javascript developer, the actual problem lies in the fact that Array.prototype.map calls the supplied callback with 3 arguments (respectively: value, index and the array being mapped), and that parseInt accepts 2 - value and radix - with the latter being optional. Thusly, the array indices 0 through 4 are being interpreted as radix, causing the string '10' to be parsed for all 5 radices.
API design considerations aside, it would've been nice if we somehow were able to express: hey, I have this function accepting 2 argument, and I'd like to bind the second argument to a fixed value. Sounds like a job for... (queue drumroll)... Function.prototype.bind()! Well, it sounds like that, except that it really isn't. It would've suited the job perfectly if you wanted to fix the first argument, but the second? Come on! Been smoking crack lately?
And of course, some might say that simply using a lambda would suffice:
JavaScript:
1 | ['10','10','10','10','10'].map(function(x) { return parseInt(x, 10); }); |
and some would be right. But then what is the point of bind's existence, really? Would it not have been cool if you could simply use bind to say: pass the first argument through, but set the second argument to 10. For example, using this syntax:
JavaScript:
1 | var f = parseInt.bind(null, $_, 10);
|
Well, you can now
- $this - represents the 'this' that is used to call the function with
- $1..$9 - represent the arguments 1 through 9
- $_ - represents the argument at that location
- $end - a special placeholder to indicate that further arguments are to be ignored (can only be used as the last argument to bind2().
JavaScript:
1 | ['1', '2', '3', '4'].map(parseInt.bind2(null, $_, 10)); // [1, 2, 3 ,4]
|
Source code:
JavaScript:
1 | function Placeholder(i) { if (i) this.index = i; }
|
Disclaimer: I'm not a javascript afficionado. I know above code polutes the global namespace (in particular with the Placeholder constructor), and you might not want that. You could wrap it in a local scope if you want...