Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:114492 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 58180 invoked from network); 17 May 2021 08:19:05 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 17 May 2021 08:19:05 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 817F5180211 for ; Mon, 17 May 2021 01:28:15 -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,NICE_REPLY_A, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Mon, 17 May 2021 01:28:15 -0700 (PDT) Received: by mail-wm1-f43.google.com with SMTP id k5-20020a05600c4785b0290174b7945d7eso2630431wmo.2 for ; Mon, 17 May 2021 01:28:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-transfer-encoding:content-language; bh=x5pfT3xuHk9/CYp0qFwhBrKE4cD77Ab4e4v0Ug0Kevo=; b=RZBanXC9NQ7sLckbNdH+sUFZOO0GLWfqv4s+F7//hCEbcDLRSn2C898mkRUktLJS+c jUOEqdhrBCfIVP5uHWAVBURtZDlMGeQvCZqxvcijUJpVWtQ1Z9nnLoDN74kWTdu+p86U fuRU2XNrWHA8rUU+0YTN9MlzXmVInxN/qMDe+lvOgkpcvGoRSZ2JmbJKUl6h+PZRjjLb r1mpc65XQwI3nuK4u8ELpEgPaElXb1AfdlG78ULBeyWaAzTMYUPOkA5fMIh3lZod34LJ R37/DdPkNnj6tIbsNd/Uz/KgU5sdhoIm4qc9FONbnuQBYG3hKyqWl9bb/+x7Nl4E/ZCI +1zw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding :content-language; bh=x5pfT3xuHk9/CYp0qFwhBrKE4cD77Ab4e4v0Ug0Kevo=; b=pniAwksq1gKhxvvTe9v4Xp7GqG/b/r2M+qkTfgwAJNbzRC+bqDlUQo37IyLt+1LneH Jg1fKTg/QI3s+ujF+FA7ekieB7Fzl9JvTHIaCSAo0ksWVjhhjFw7ywMxBkhuRpDil+Sp /c9pb2sJPKDie+Z7kt4UiTaj18u2Piax0g9P3261+jCbmPihYOXYFV/YVWn+VSnUtWt4 jYpWXaSHPo9t06J4fU+aiwsVfZ08JJ36wSC8gc48tEzDYNdmuclQ4WWk+DMNi4LVXr2k 8WUfIzviobCl6ygRVNVIVDq4yc0ZFa4vruZpd1lc991chKKTYFjZ+WJ3mYXIVMdZnmgf lL5A== X-Gm-Message-State: AOAM531wYcu3B1RWlugIXZivwBoLYUFsqteXq+cwwt/2fxTsnMtU753V FeEF/6r2fIit+RcFj3eAbf3FoD+EoUo= X-Google-Smtp-Source: ABdhPJx4d7gs5pPCW+mJl+irgTOg8jON3Tr09jPMTzk7bjjp/n7x2WY/pQpLjPtDeq32+gFufSWzjw== X-Received: by 2002:a1c:bdc4:: with SMTP id n187mr20646195wmf.175.1621240091443; Mon, 17 May 2021 01:28:11 -0700 (PDT) Received: from [192.168.0.22] (cpc104104-brig22-2-0-cust548.3-3.cable.virginm.net. [82.10.58.37]) by smtp.googlemail.com with ESMTPSA id m9sm6499533wmq.40.2021.05.17.01.28.10 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 17 May 2021 01:28:10 -0700 (PDT) To: internals@lists.php.net References: Message-ID: <2d7fb03a-addb-f22b-e3fd-957f758569f9@gmail.com> Date: Mon, 17 May 2021 09:28:09 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.10.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-Language: en-GB Subject: Re: [PHP-DEV] [RFC] Partial function application From: rowan.collins@gmail.com (Rowan Tommins) On 25/04/2021 20:25, Larry Garfield wrote: > Greetings, Internalians! > > I would like to offer for your consideration another RFC, specifically syntax for partial function application. > > https://wiki.php.net/rfc/partial_function_application During off-list discussions, it's become clear that there are two different ways of modelling what this feature does, which is leading to a bit of misunderstanding and frustration (and some plain disagreement on which is the *better* model). At risk of getting it wrong and confusing things more, I'd like to attempt to describe the two models. The first model is that a partial application starts with an empty signature, and adds arguments to it based on placeholders. You could picture the steps like this: function foo(int $a, int $b, int $c) { /* whatever */ } $partial = foo(?, ?, 42); Step 1 - empty closure: $partial = fn() => foo(); Step 2 - 1st argument is a ? so copy that parameter from the original: $partial = fn(int $a) => foo($a); Step 3 - 2nd argument is a ? so copy from the original: $partial = fn(int $a, int $b) => foo($a, $b); Step 4 - 3rd argument is a fixed value, so don't add to signature, only to the call: fn(int $a, int $b) => foo($a, $b, 42); The second model is that a partial application starts with a *complete* signature, and splices in the *fixed* values. The steps go more like this: function foo(int $a, int $b, int $c) { /* whatever */ } $partial = foo(?, ?, 42); Step 1 - copy original signature: $partial = fn(int $a, int $b, int $c) => foo($a, $b, $c); Step 2 - 1st argument is a ? so skip over it Step 3 - 2nd argument is a ? so skip over it Step 4 - 3rd argument is a fixed value, so splice a value into the signature at that location: $partial = fn(int $a, int $b, 42) => foo($a, $b, 42); Step 5 - fixed values don't actually belong on the left-hand side: $partial = fn(int $a, int $b) => foo($a, $b, 42); For simple examples like the above, the two models are essentially equivalent, but they lead to different expectations for some features; for instance, trailing arguments and placeholders: - In the model where you're building from empty, writing foo(42, ?, ?) to mean "copy exactly two arguments" feels natural. To say "copy all arguments", or "copy all remaining arguments", you'd then need a different syntax, like foo(42, ...) or foo(42, ??). In this model, the trailing "?" in the current proposal is magic: it changes from meaning "copy exactly one argument" to "copy all remaining arguments". - In the model where you're splicing arguments into a full signature, foo(42, ?, ?) is pointless: the action is to splice in the 42, then "skip over" two arguments; but nothing happens *after* skipping over them, so you could just not mention them. No extra token is needed to copy all remaining arguments, because that already happened at the start. The only reason to use a trailing "?" at all is because foo(42) would just be a normal function call, and adding a redundant "skip over" marker in foo(42, ?) tells the compiler it's a partial. Regards, -- Rowan Tommins [IMSoP]