Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:120845 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 89067 invoked from network); 18 Jul 2023 19:19:01 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 18 Jul 2023 19:19:01 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 5BECE1804D4 for ; Tue, 18 Jul 2023 12:19:00 -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, 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-il1-f179.google.com (mail-il1-f179.google.com [209.85.166.179]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Tue, 18 Jul 2023 12:18:59 -0700 (PDT) Received: by mail-il1-f179.google.com with SMTP id e9e14a558f8ab-345f1e0abf9so26676205ab.3 for ; Tue, 18 Jul 2023 12:18:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1689707939; x=1690312739; h=cc:to:subject:message-id:date:from:references:in-reply-to :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=7iKdd+a9CQigf60kpeTtfR7VfWKILjHAsNhU9jVluIg=; b=GwKmXMFP/R/xoPMrTqk5F1oBuaVA0YM7d+oDketYKt/z5SGmdYwNNvJT+wXked8PZF +XjhkhA/1ggkhTqf8Oa9imLd6Lvg2sMihhhvaxOcSlUcFZNkdtElV47cCKnvlwXwa4yj HtgcrN15gB3PsWFf5m+Ptwz+1wLbEDAFUFoa9rVvJNMEMC07Dm7+2ilqgpa6hr6Z96vz POA1Fd7UAToIedBdwpfBjhKeemCPcRONwOrJSgNSuN1/02msMYiXub1dyXWPXskFdzzt wi8aeBqLFfRJ/eT/WshLuKPfc88IY4Tr+0xslnN+yytDZug7BemWQsvPOyMAqq+/reaO 8Evg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689707939; x=1690312739; h=cc:to:subject:message-id:date:from:references:in-reply-to :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=7iKdd+a9CQigf60kpeTtfR7VfWKILjHAsNhU9jVluIg=; b=ESwm41peWAhWHDyh3EhDtsP+RYEkKi6GFBWwdK8xtx5h+FFoOXYTqllKUeVHiZALit uXRWDMdISePuzgypxjKiE7P4i0mu+atDV7eyZPelh540zmD8TnZwJi/1YuQU0wgr+JvB 95GrSdHZrSRByizehaj4Pkg3sjGAXCejHdC0QYNyw1/P0dcOZXa0ZVsqqddjZgVRcj4M JGiQD7KuzDgue0MRKjcktrz24Di95nhNyXcryk/5zQk09onjgZZHmLgBUSVJaiDYRMea cPWZEkwKIMJBTAr+CQwvKxt48skwPykQ/0xUGIh4aMSbtyJ1j8csYByD9jwN91K5B0h8 SBkw== X-Gm-Message-State: ABy/qLYwDeAKFPc8UKu12m4owfYkB5LSa4s48l/nD8vNxCSvLsuhw7wF oZcTvolcUgn0JkrXfPP/M7B6699v//7VV0SDgt6CbMFB X-Google-Smtp-Source: APBJJlGIRDWZnNETPTUXWtWpKaut0Wf05hbcSYu/EfyTkKVBoTtaxzzU2Xz3zq9NiEMrVaxFwKjObOQF7dbegxV4kxw= X-Received: by 2002:a92:cc43:0:b0:347:6d5f:ab2f with SMTP id t3-20020a92cc43000000b003476d5fab2fmr312964ilq.6.1689707938857; Tue, 18 Jul 2023 12:18:58 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:ad5:4204:0:b0:2e2:2af1:79d7 with HTTP; Tue, 18 Jul 2023 12:18:58 -0700 (PDT) In-Reply-To: <014c449a-fa84-4fa2-bfec-518a8fdb4ff1@app.fastmail.com> References: <8055b366-32f1-4d2c-85d0-0cf665e6c8d3@app.fastmail.com> <014c449a-fa84-4fa2-bfec-518a8fdb4ff1@app.fastmail.com> Date: Tue, 18 Jul 2023 21:18:58 +0200 Message-ID: To: Larry Garfield Cc: php internals Content-Type: text/plain; charset="UTF-8" Subject: Re: [PHP-DEV] pipes, scalar objects and on? From: olleharstedt@gmail.com (=?UTF-8?Q?Olle_H=C3=A4rstedt?=) 2023-07-18 20:08 GMT+02:00, Larry Garfield : > On Tue, Jul 18, 2023, at 5:08 PM, Karoly Negyesi wrote: >> My favorite pipeline is Elixir, where "The pipe operator |> passes the >> result of an expression as the first parameter of another expression".. >> But >> it works there because unlike with PHP, it's almost always the first >> argument you want. If it's not the first argument you needed to do some >> tricks which was only cleaned up in 2021 so now they do: >> >> 5 >> |> then(&Enum.take(1..10, &1)) >> |> Enum.reverse() >> >> but I digress. >> >> My problem here is... we actually need something that passes the RFC >> vote. >> >> What flexibility is missing here? > > Please don't top post. > > The main flexibility for callables is the ability to build a closure on the > fly. For example, using $$ (which Hack does, and I insist on calling > T_BLING) means that for array and string functions you still need to worry > about parameter order. With a callable, you can effectively emulate > Elixir's behavior if you want. > > For example, my FP library has a whole bunch of higher order functions that > just return pipe-ready functions: > > https://github.com/Crell/fp/blob/master/src/array.php > > Which, with a pipe operator, would allow for: > > $result = $arr > |> amap(trim(...)) > |> afilter(is_int(...)) > |> reduce(0, $fn) > |> trim(...) // At this point it's a string and trim() is already unary, > so we can just use it. > ; > > Which is pretty nice, IMO. It "flows" nicely, supports both higher order > functions and direct calls equally well, and allows for all kinds of further > expansion that I haven't thought of yet. > > The Hack style would require thinking about the fact that array_map() and > array_filter() take their arguments in reverse order from each other, which > is just silly. This way, that problem goes away entirely. > > It also allows a pipe to be used as a quasi alternative to scalar methods, > because (if we set aside visibility for the moment) a method is just a > function with an implicit $this parameter. Callables and higher order > functions make that a lot cleaner. > > The caveat is that it does add an extra step to use many of the existing > array or string stdlib functions. However, that's work that can be done > once. The link above is under 500 lines, heavily documented, and covers > every array use case I've run into so far. > > Related improvements: > > * Writing a higher order function right now is rather cumbersome. There > were two previous RFCs that would have made that vastly nicer > (short-functions and auto-capture closures), but neither passed. They would > have allowed for: > > function amap(callable $c) => fn (iterable $it): array { > if (is_array($it)) { > return array_map($c, $it); > } > $result = []; > foreach ($it as $k => $v) { > $result[$k] = $c($v); > } > return $result; > }; > > Which I think is pretty nice. > > * PFA would give us the best of both worlds, as if you wanted you could do: > > $result = $arr > |> array_map(trim(...), ?) > |> array_filter(?, is_int(...)) > |> array_reduce(?, $fn, 0) > |> trim(...) > ; Damn, that PFA RFC would _really_ help with removing noise, instead of wrapping with fn ($x) => ... everywhere. Shame it didn't pass. :/ 29 vs 20 votes. Olle