Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:119734 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 89311 invoked from network); 17 Mar 2023 08:54:33 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 17 Mar 2023 08:54:33 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id BC2551804F7 for ; Fri, 17 Mar 2023 01:54:32 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-yw1-f182.google.com (mail-yw1-f182.google.com [209.85.128.182]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Fri, 17 Mar 2023 01:54:32 -0700 (PDT) Received: by mail-yw1-f182.google.com with SMTP id 00721157ae682-54184571389so81887127b3.4 for ; Fri, 17 Mar 2023 01:54:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1679043272; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=oYsimr63XZLF+FEdRdgrUWv++iYl3WRDrDtIBbYAi3s=; b=isG/XBRAeMNzIeidKxNI/hBxKP7HxKo6mxyUuEGmgdzUI2roiJMy5xjKcH51oM6ZL9 jU22WgjhrcdTTORuR6fYwCUMqqJLkbaEqpwbukbGKZemRolX7HJoSwh1AgweA6oR5Wxo zrpVMtQYI657kf89cP9WyB0Ht1/p5EUt1ounMcMGe+ZyI9Ii9QXZmAiyrV+F5Gepln/r 3YOH91EVJloA0lYv/fudf9e3q4deiKbmqE42BX1H4R9HH7O/+UB5nLeHFzjlrhz295Gw 0E4J+b1XGl7j2eoBmE4XCGLYSBKTBd9CIGPBCts03c/KVWDMiN/qybiN+2aDO9+isvbT x4xw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679043272; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=oYsimr63XZLF+FEdRdgrUWv++iYl3WRDrDtIBbYAi3s=; b=NhmRutdDpLZDFnpJk2NrKovTledguGtcuuSxmUR3OdID7ASw2TyZtQ0Db8Ky87O1iC /oLM/gBTBPIp/iQXu51BO4MABIuA685CMYPjI9ZpY4l3Lm/grtKXDtYUTJXc7ne3lw2a 2fu56iPOb2zqzEbi53AkxXYyDr9c5SsoaXFYQHqKMfNBmcqaY4EeZKk2pO1Ktz8CrvP/ ao7XBO0Cu48wGlffCpte+GJgiNsxq6A3N1YRsX1KQj4bvV7uuHcqfOMt4ACROLRspMY/ EIIyBSYZaZrfMlF8QVL+HqAg/KYfnDDltc1peeViynSWWYIjUM+aZmuLmP123hBIBEBH vohw== X-Gm-Message-State: AO0yUKWAGbPhcE8+QfqLT7bFQF1IlAYpdL7eF2wREBXGdI9lnB+nC0mw UFYnmXZeYIPmsFJGdu0D7qnMqAIEpqeWAZUOCM054mFB4/Uapg== X-Google-Smtp-Source: AK7set+DGSmYUFkV4yb6vha28oAzpoDmrzbsDyQEwqlgd1YQ17a//9go2FSjHp4ctcGw1fMny03QUNaKXebTAeMF2oM= X-Received: by 2002:a81:af02:0:b0:541:822f:af40 with SMTP id n2-20020a81af02000000b00541822faf40mr4345875ywh.10.1679043271615; Fri, 17 Mar 2023 01:54:31 -0700 (PDT) MIME-Version: 1.0 References: <9975B833-EE24-4ED7-B28E-841B92988BA0@cschneid.com> <1A2CE63B-ECCA-403D-83AC-B1E26279323C@gmail.com> <9a2140b4-97bb-4a9c-90c5-809274c83f75@app.fastmail.com> <88c4a63c-859b-94d5-e314-3399fb2c3fb0@gmail.com> <1a4d4434-7318-4831-9fc0-8b48a6400a62@app.fastmail.com> <73033e11-a521-40a3-a29e-14d575332aea@app.fastmail.com> In-Reply-To: <73033e11-a521-40a3-a29e-14d575332aea@app.fastmail.com> Date: Fri, 17 Mar 2023 09:54:20 +0100 Message-ID: To: Larry Garfield Cc: php internals Content-Type: multipart/alternative; boundary="000000000000c46b1805f714b9f6" Subject: Re: [PHP-DEV] First-class callable partial application From: michal.brzuchalski@gmail.com (=?UTF-8?Q?Micha=C5=82_Marcin_Brzuchalski?=) --000000000000c46b1805f714b9f6 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Larry, czw., 16 mar 2023 o 23:26 Larry Garfield napisa=C5=82(a): > On Thu, Mar 16, 2023, at 4:14 AM, Rowan Tommins wrote: > > On 15/03/2023 21:12, Dan Ackroyd wrote: > >> Would it be desirable to split those two things into two separate > >> RFCs, by having the first RFC not have native syntax support, but > >> instead another static method on Closure? e.g. something like: > >> > >> Closure::partial($callable, array $position_params, array > >> $named_params): Closure {} > > > > > > Hm... now we have the first-class callable syntax, making it an instanc= e > > method on Closure would allow this: > > > > $mapFoo =3D array_map(...)->partial([$foo]); > > $filterFoo =3D array_filter(...)->partial([1 =3D> $foo]); > > > > Which could copy over the full signature, so be equivalent to this: > > > > $mapFoo =3D static fn(array ...$arrays): array =3D> array_map($foo, > ...$arrays); > > $filterFoo =3D static fn(array $array, int $mode =3D 0): array =3D> > > array_filter($array, $foo, $mode); > > > > While being a similar length to a much less rich version: > > > > $mapFoo =3D fn($array) =3D> array_map($foo, $array); > > $filterFoo =3D fn($array) =3D> array_filter($array, $foo); > > Fascinating! I... don't know if we considered something like that or not > 3 years ago. It's been a while. > > It's definitely not as nice as the integrated syntax, but it does have th= e > advantage of the implementation almost certainly being rather pedestrian = in > comparison. That approach would favor left-to-right application, but not > force it, which is probably sufficient. > > As a thought experiment, if we had that syntax and functions that were > designed to be used with them, it would look like so: > > function amap(callable $c, iterable $it) { ... } > function implode(string $sep, iterable $it) { ... } > function length(string $s) { ... } > > $arr =3D [1, 2, 3]; > > $a2 =3D amap(...)->partial(chr(...))($arr); > > $str =3D implode(...)->partial(',')($a2); > > Or, if combined with pipes: > > $size =3D $arr > |> amap(...)->partial(chr(...)) > |> implode(...)->partial(',') > |> length(...); > > Which... is not terrible, especially as it doesn't preclude using higher > order functions for more control. > Maybe we could introduce two additional methods on a Closure similar to what Java have https://docs.oracle.com/javase/8/docs/api/java/util/function/Function.html * andThen() - which functionality is like a pipe operator * apply() - which you can call without the option to bind/rebind and just pass arguments for execution The pipe operator can be introduced later, but we could already have the functionality on Closure. The above example might look readable as well: $size =3D amap(...)->partial(chr(...)) ->andThen(implode(...)->partial(',')) ->andThen(length(...)) ->apply($arr); Cheers, Micha=C5=82 Marcin Brzuchalski --000000000000c46b1805f714b9f6--