Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:100493 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 65649 invoked from network); 9 Sep 2017 21:18:23 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 9 Sep 2017 21:18:23 -0000 X-Host-Fingerprint: 95.148.131.225 unknown Received: from [95.148.131.225] ([95.148.131.225:26392] helo=localhost.localdomain) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id AD/E9-10715-D9A54B95 for ; Sat, 09 Sep 2017 17:18:21 -0400 Message-ID: To: internals@lists.php.net References: <82.32.10715.A8E03B95@pb1.pair.com> Date: Sat, 9 Sep 2017 22:18:18 +0100 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:49.0) Gecko/20100101 Firefox/49.0 SeaMonkey/2.46 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Posted-By: 95.148.131.225 Subject: Re: [PHP-DEV] [RFC] [Discussion] Operator functions From: ajf@ajf.me (Andrea Faulds) Hi Nikita, Nikita Popov wrote: > On Fri, Sep 8, 2017 at 11:41 PM, Andrea Faulds wrote: > > I like the general idea here, but have some comments. > > My main observation is that this proposal is only really useful in > combination with a form of partial application. Indeed. I think the RFC feels somewhat incomplete without such a facility. Unfortunately it's not really the right place to add partial application either (at least, not a generic form thereof). RFCs should generally cover a single feature. What I might do is write a separate patch and RFC to add a partial application function (and probably some other similarly useful things like composition or currying), then delay voting on this RFC until it's done. > Passing operators to > array_reduce() is cute, but it's not a major application, especially as we > already have built-in functions for the two common operations (array_sum > and array_product). > > Where operators-as-functions really shine is in cases where only one of the > operands is bound. You acknowledge this in the RFC, and provide a few > examples using a (not yet existing) partialApply() function: > > // Select only the positive numbers > $positiveSubset = array_filters($numbers, partialApply('>', 0)); > > However, this code is subtly broken. Partial application (at least without > specifying a more specific behavior) operates from left to right, so this > code would be equivalent to: > > // Select only the positive numbers > $positiveSubset = array_filters($numbers, function($n) { return 0 > $n; > }); > > As such, it would return all negative numbers, not all positive numbers. You're quite right. This is what happens when I don't bother to test all my examples actually work first. ;) > > This is a general issue of partial application in combination with > operators: For the operations that do not commute, you nearly always want > to bind the right operand, not the left. This is indeed an interesting issue. In the case of `>` of course you can just use `<` instead, but it would be better to have a more general solution. An idea I had the other day was that PHP's arrays could solve this problem. Perhaps `partialApply('>', [1 => 0])` would bind the second parameter, and `partialApply('>', [0])` would bind the first. > > For my own purposes, I define an operator() function as follows: > https://github.com/nikic/iter/blob/master/src/iter.fn.php#L60 > > This function either accepts a single argument such as operator('+'), in > which case it is essentially equivalent to this proposal. Or it accepts two > arguments, in which case the right operand will be bound, such as > operator('>', 0). > > I wonder if providing such a function might not be a better solution to > this problem. It also has the additional advantage that it can be easily > polyfilled in older PHP versions. That's an interesting way to do it, and I can see the benefit of doing it that way. Though I feel it gets rid of the thing that I particularly liked about the current proposal (versus various other ideas that never made it to the RFC stage), which that it's concise, simple, and doesn't single out operators from other functions (no special function or language construct you need to use). The downside is of course it can't be polyfilled, but given people are already writing wrapper functions anyway, it doesn't bother me so much. Thanks for your response! -- Andrea Faulds https://ajf.me/