Newsgroups: php.internals
Path: news.php.net
Xref: news.php.net php.internals:117931
Return-Path: <arnaud.lb@gmail.com>
Delivered-To: mailing list internals@lists.php.net
Received: (qmail 25043 invoked from network); 13 Jun 2022 11:10:08 -0000
Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5)
  by pb1.pair.com with SMTP; 13 Jun 2022 11:10:08 -0000
Received: from php-smtp4.php.net (localhost [127.0.0.1])
	by php-smtp4.php.net (Postfix) with ESMTP id 8B764180384
	for <internals@lists.php.net>; Mon, 13 Jun 2022 05:57:23 -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: <arnaud.lb@gmail.com>
Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51])
	(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 <internals@lists.php.net>; Mon, 13 Jun 2022 05:57:23 -0700 (PDT)
Received: by mail-wr1-f51.google.com with SMTP id h19so3798788wrc.12
        for <internals@lists.php.net>; Mon, 13 Jun 2022 05:57:23 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20210112;
        h=from:to:cc:subject:date:message-id:in-reply-to:references
         :mime-version:content-transfer-encoding;
        bh=fxOaJPYgQ/mqVVY7pFovjutb+ys2Cses0pxE9cDgquk=;
        b=WQlFsFdDbrkBeneRQA0dVJv/Iqqn3Q36QS4qZrmidFvopoHxMtu8J2yOcRq2Ids9l0
         ZsmewtjYrPGNFbWx8QZLi3Qc3UXRF6+N48Uz2VO++GXpYsO6sLdSUrAR4NkIHWBWK61X
         liZpf07vEHVGB6PIsTEnjDGAR5UcjouMVSa1QxwGSD7Ob8MOOAwP1xeFpYf5Ti3U1syw
         sl53HQebnpzAHqAcwa1IBZR7jBSQNleMT2D19VVPLRLxlZbVEv1x4Xy6vNGEGJrF84wJ
         wzhSG6cbviORmmwhQfrqJpQPJMdqqSnTrwpp1Lt53IW0GbEcVLkQmkxbZKrdZwXJsbYo
         gspQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20210112;
        h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to
         :references:mime-version:content-transfer-encoding;
        bh=fxOaJPYgQ/mqVVY7pFovjutb+ys2Cses0pxE9cDgquk=;
        b=uoLYvqBaPZ/M07WCqYGf1WGhf9BTjeZyAPVmESBAEb6XuAUDtY/lW1e6QNLY8hcCUq
         WxsNNe+Ob5MOB/JQpA/N1pV5QcAY07yxF0J+IYNJOC0DR0uUVkGJ6Tegh8zsKIY+4P9M
         DJyuhYPVtz+8KIBraHTyxsZpY5pkNSKntBomh/TtEvFDaaoJxWRbAOVkeZ4XWq1QTc6J
         2cjRzAZ2fPj4hiHkrOWWqUujF4m5dHLuSUQpVb4+sn0eA+aPe0mw6uUsGuDCRDvsPsbX
         51wSF98vFtHeBlaAyZr5rs0krQqabXJm26nwYkBREUz2CPfiKUXOYoCVYA71hxK3ZrR2
         Wn2g==
X-Gm-Message-State: AOAM532mi16fxsyZt+GKuxwEBssAp5akpOb5t8DjBxt6k/3NtCbVnHKE
	OzWe/qEtSPm5QxmKZ4F8UACqLRe98sGRIw==
X-Google-Smtp-Source: ABdhPJydAMfOXeH3w2Ljhfl83W9FEPM/1WeUNPX/vvLIZhg8qRZ3DhzVMJKynASPSWhhYfiaz98s0Q==
X-Received: by 2002:a05:6000:1b8d:b0:219:8930:6e54 with SMTP id r13-20020a0560001b8d00b0021989306e54mr24120033wru.99.1655125041817;
        Mon, 13 Jun 2022 05:57:21 -0700 (PDT)
Received: from arnaud-t490.localnet (2a01cb04054b5b0000c66a4556b36e2a.ipv6.abo.wanadoo.fr. [2a01:cb04:54b:5b00:c6:6a45:56b3:6e2a])
        by smtp.gmail.com with ESMTPSA id v14-20020a5d4a4e000000b0020fc3e24041sm8656702wrs.106.2022.06.13.05.57.21
        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
        Mon, 13 Jun 2022 05:57:21 -0700 (PDT)
To: internals@lists.php.net
Cc: Rowan Tommins <rowan.collins@gmail.com>
Date: Mon, 13 Jun 2022 14:57:21 +0200
Message-ID: <2347345.PIDvDuAF1L@arnaud-t490>
In-Reply-To: <8310f3fd-0011-970e-5379-b2b6e03942b2@gmail.com>
References: <2b35605f-8da8-46b1-aec3-00bd1bfe47fd@www.fastmail.com> <8310f3fd-0011-970e-5379-b2b6e03942b2@gmail.com>
MIME-Version: 1.0
Content-Transfer-Encoding: 7Bit
Content-Type: text/plain; charset="us-ascii"
Subject: Re: [PHP-DEV] [RFC] Short Closures 2, aka auto-capture take 3
From: arnaud.lb@gmail.com (Arnaud Le Blanc)

On samedi 11 juin 2022 23:14:28 CEST Rowan Tommins wrote:
> My main concern is summed up accidentally by your choice of subject line
> for this thread: is the proposal to add *short closure syntax* or is it
> to add *auto-capturing closures*?

The proposal is to extend the Arrow Functions syntax so that it allows 
multiple statements. I wanted to give a name to the RFC, so that we could 
refer to the feature by that name instead of the longer "auto-capture multi-
statement closures". But the auto-capture behavior is an important aspect we 
want to inherit from Arrow Functions.

> As such, I think we need additional features to opt
> back out of capturing, and explicitly mark function- or block-scoped
> variables.

Currently the `use()` syntax co-exists with auto-capture, but we could change 
it so that an explicit `use()` list disables auto-capture instead:

```php
fn () use ($a) { } // Would capture $a and disable auto-capture
fn () use () { }   // Would capture nothing and disable auto-capture
```

> On the other hand, "auto-capturing" could be seen as a feature in its
> own right; something that users will opt into when it makes sense, while
> continuing to use explicit capture in others. If that is the aim, the
> proposed syntax is decidedly sub-optimal: to a new user, there is no
> obvious reason why "fn" and "function" should imply different semantics,
> or which one is which. A dedicated syntax such as use(*) or use(...)
> would be much clearer. We could even separately propose that "fn" and
> "function" be interchangeable everywhere, allowing combinations such as
> "fn() use(...) { return $x; }" and "function() => $x;"

Unfortunately, Arrow Functions already auto-capture today, so requiring a 
`use(*)` to enable auto-capture would be a breaking change.

> I don't find the comparison to a foreach loop very convincing. Loops are
> still only accessing variables while the function is running, not saving
> them to be used at some indeterminate later time.

Do you have an example where this would be a problem?

> This is also where comparison to other languages falls down: most
> languages which capture implicitly for closures also merge scopes
> implicitly at other times - e.g. global variables in functions; instance
> properties in methods; or nested block scopes. Generally they also have
> a way to opt out of those, and mark a variable as local to a function or
> block; PHP does not, because it has always required an opt *in*.

These languages capture/inherit in a read-write fashion. Being able to scope a 
variable (opt out of capture) is absolutely necessary otherwise there is only 
one scope.

In these languages it is easy to accidentally override/bind a variable from 
the parent scope by forgetting a variable declaration. 

Auto-capture in PHP is by-value. This makes this impossible. It also makes 
explicit declarations non-necessary and much less useful.

> Which leads me back to my constructive suggestion: let's introduce a
> block scoping syntax (e.g. "let $foo;") as a useful feature in its own
> right, before we introduce short closures.

I like this, especially if it also allows to specify a type. However, I don't 
think it's needed before this RFC.

> As proposed, users will need to have some idea of what "live variable
> analysis" means, or add dummy assignments, if they want to be sure a
> variable is actually local. With a block scoping keyword, they can mark
> local variables explicitly, as they would in other languages.

Live-variable analysis is mentioned in as part of implementation details. It 
should not be necessary to understand these details to understand the behavior 
of auto-capture.

I've updated the "Auto-capture semantics" section of the RFC.

Regards,
--
Arnaud Le Blanc