On Thu, Oct 1, 2015 at 10:47 AM, Rowan Collins <rowan.coll...@gmail.com> wrote: > Levi Morrison wrote on 01/10/2015 16:52: >> >> This is >> close:https://github.com/morrisonlevi/Algorithm/blob/master/src/reduce.php > > > When would you store or pass around the intermediate callback (the result of > reduce($initial)) without immediately invoking it with a callback? If you > just run "reduce($initial)($my_fn)($data)", it seems no more useful than > "reduce(42, $my_fn, $data)", which would be more efficient internally. > > If anything, I can imagine wanting to write $my_reduce = reduce($my_fn) and > then $my_reduce($initial, $data), but that's still 2 steps rather than 3. > > Genuine question, not a criticism - this functional(?) style of composition > is not something I'm very familiar with. (For the same reason, I struggle to > read that function definition no matter which syntax it's expressed in.)
I've worked out what I think are elegant definitions that are highly composable and usable by iterators and arrays alike. For example, it's common in our code base to do a filter followed by a map (or series of maps) and sometimes followed by a reduce. Here's a simplified example, with definitions taken from the linked repository: $algorithm = chain( filter(function($x) => $x % 2 > 0), map(function($x) => $x * 2), sum() ); $algorithm([1,2,3]); If you understand the (very common) algorithms filter and map then this is trivial to understand. More than that, it's easy to write and very difficult to introduce bugs into it since you are writing very simple functions that perform a single task. Chain works is because the functions passed to it accept iterables as their only parameter and return either an another iterable or a reducing function (in this example sum is the reducer). This is why the functions are returning closures that accept only one parameter. This can be done with a binding function with more traditional definitions like Nikita Popov's iter library, or by writing inline closures: $algorithm = chain( // using a bind function bind('iter\\fn\\filter', function($x) => $x % 2 > 0), bind('iter\\fn\\map', function($x) => $x * 2), // using a closure (showed the closure with this one because // the parameter order doesn't work well with bind) function($input) => iter\fn\reduce(function($x, $y) => $x + $y, $input, 0) ); $algorithm([1,2,3]); There's a lot more noise here, which is why the library I linked returns a series of closures. Both are valid, but if you are going to write this particular style then the closure style has less noise when called. Hopefully that was helpful. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php