Re: Lamda-aware higher order functions
Now if I understand correctly, "test" at the beginning of your posting
is supposed to stand for some example "algorithm object" of the same ilk
as "for_each" in the snippet above. So you're suggesting encoding the
computation of the lambda's parameter and return types into the
algorithm object itself? Makes sense...
I guess what I am trying to accomplish would be similar to ruby-style
blocks. It doesn't necessarily have to apply to std algorithms; it
could be used for callbacks and signals, also. For example, using ruby
blocks you would iterate like this:
collection.each { |x| print x }
This is because the "each" method is accepts a lambda. When the
function calls "yield", it calls the lambda block. Now, of course, we
dont have polymorphic lambdas, so the special ruby-like functions(or
lambda-aware functions, im not sure what to call them) would let the
compiler know what variable type they pass to the lambda as
parameters. So in essence, the compiler would deduce the type(but it
wouldnt be polymorphic). The way this could look would be like this:
$(for_each(some_range), x) { cout << x; };
This would call "for_each" like this:
for_each(some_range, [] (typename range_value<some_range>::type x)
{ cout << x; });
Now, how does it know that x is of the type "typename
range_value<some_range>::type"? That is because the function returns a
special "object" that says each of the types it passes into the
lambda.
Now of course this "$" macro works great for a lot of functions, but
as with almost all macros, it has its caveats. One of its caveats, is
that it cant be used with pipable range adaptors. It, of course, would
be great if I could write something like this:
//Find all the last names of people named "Joe"
some_range | $(filtered, x) { return x.first_name = "Joe" } | $
(transformed, x) { return x.last_name; };
Of course this wont work, because it is a macro, and not an operator,
so it would need to be called like this:
$($(some_range | filtered, x) { return x.first_name = "Joe"; } |
transformed, x) { return x.last_name; }
Which is harder to read and write. I dont know of anyway with using
the macros to get around this. Perhaps I dont use the pipable adaptors
for filter and transform, but instead create some special "functions"
that can use the "$" macro(lets call filter => where, and transform =>
select). I could place them inside of another lambda, maybe and write
something like this:
$(from(some_range), x) { $(where) { return x.first_name = "Joe" } | $
(select) { return x.last_name; }; }
I am not sure at all if this would work. However, its starting look a
lot like linq in C#, but fairly verbose. It would be nice to have it
compact like in C#, but im afraid the macros needed to do that would
just make it look awful, if boost supported something like this, it
would look like this:
BOOST_FROM(some_range, x, BOOST_WHERE(x.first_name = "Joe"),
BOOST_SELECT(x.last_name))
theres no way "from", "select" and "where" could use there lower case
version, it could very possibly interfere with a lot of other names.
It could be written like this maybe:
FROM(some_range, x, where(x.first_name = "Joe"), select(x.last_name))
This could be very possible, but I guess I digressed.
I think it might be a whole lot easier to have real polymorphic lambdas
;-)
No doubt polymorphic lambdas would make this a lot easier, however,
this wont happen for at least another 5 years(assuming they create
another standard that soon). Im trying to write something that would
help make writing lambdas much more compact and cleaner now. This all
could be done by a library in order to make writing these "lambda-
aware" functions easier(I am not sure what the appropriate term would
be for these functions).
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]