Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:88614 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 35878 invoked from network); 1 Oct 2015 17:38:09 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 1 Oct 2015 17:38:09 -0000 Authentication-Results: pb1.pair.com header.from=morrison.levi@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=morrison.levi@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.213.46 as permitted sender) X-PHP-List-Original-Sender: morrison.levi@gmail.com X-Host-Fingerprint: 209.85.213.46 mail-vk0-f46.google.com Received: from [209.85.213.46] ([209.85.213.46:33768] helo=mail-vk0-f46.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 0C/C1-26330-F7F6D065 for ; Thu, 01 Oct 2015 13:38:08 -0400 Received: by vkgd64 with SMTP id d64so45105007vkg.0 for ; Thu, 01 Oct 2015 10:38:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date:message-id:subject :from:to:cc:content-type; bh=XcQCpXWQERW4DTs5Qa3wEjGNuk+oaVaA4kWogusZZuY=; b=rTljk7TtTCDpgdmKESry/GWoIVtYdrLgMwfBqQ5d1cO/ZuFPYkG48NPWlhjZStSSYq ujr+CcYgiuvib4C4LPgFAsiySrG1ERG/zcSlF/hhG2po9Kz1d/dFiGThCEZD4Sf74YE7 xhdKc94iJsMNXrghldOjhde+PuePta6J5G67VN5XUayZPAwV8mQxMzBvL+71qDNMLxXK Bm98E4G8K3ype4mRmyVRpCxTSPfZ+LMKyslRvDnm3AHtEbMLxzhtPefL5kDIzhKYlq25 o+TZyoONhkEwxiiEvDBa2hi+hqGFF5HnqXF0fIO8DYTwSXl95NAidPjCKdo0KLq8nX2n myBw== MIME-Version: 1.0 X-Received: by 10.31.158.213 with SMTP id h204mr7448527vke.48.1443721085145; Thu, 01 Oct 2015 10:38:05 -0700 (PDT) Sender: morrison.levi@gmail.com Received: by 10.31.41.205 with HTTP; Thu, 1 Oct 2015 10:38:05 -0700 (PDT) In-Reply-To: <560D638E.5020706@gmail.com> References: <5606D0EB.3060106@gmail.com> <560D0F94.8060009@gmail.com> <560D282F.6060202@gmail.com> <560D638E.5020706@gmail.com> Date: Thu, 1 Oct 2015 11:38:05 -0600 X-Google-Sender-Auth: Pv8YITBJGtou1EBYd7f5FG-JaO4 Message-ID: To: Rowan Collins Cc: "internals@lists.php.net" Content-Type: text/plain; charset=UTF-8 Subject: Re: [PHP-DEV] Arrow function expressions in PHP From: levim@php.net (Levi Morrison) On Thu, Oct 1, 2015 at 10:47 AM, Rowan Collins 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.