Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129067 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by lists.php.net (Postfix) with ESMTPS id E23191A00BC for ; Tue, 4 Nov 2025 12:31:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1762259504; bh=XdrH1l+67EoQKxEWo24wowxxGPlsB2H7RlNefCg3rmA=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=Ykuej5367ce8rmILnlETZVsN59hD2dt4u54DyBAEmLh+nvqR83NDBTef8xmuTidP+ aCOhdHJFS8wexVBxJdvOXikGV/s2NglUx6TNGhs+kt+iWPd/DYDN1mBHc2d+uerN0y Kd35ol9aNvl+nebQ685Mh8cHbZPiIeZKZR4mPRGNnmQmxo70XQ2qpzB7dnVT+q3Oa7 m+7UbyCjZB2zQVgJs2wM7KaMVu7lf6uD8PJfeTDYLw0yLhsv+ubtieTdWyeoWksHyu NR+93uiyneiwTPn7Ws+ajzBDdo/PpbJvPEMVWpf/KSxQvI9irQp+nE9oFUKRh+WsYv 1wWejD+mvkUQQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 717C0180041 for ; Tue, 4 Nov 2025 12:31:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) 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,DMARC_PASS,FREEMAIL_FROM, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from mail-ej1-f51.google.com (mail-ej1-f51.google.com [209.85.218.51]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Tue, 4 Nov 2025 12:31:43 +0000 (UTC) Received: by mail-ej1-f51.google.com with SMTP id a640c23a62f3a-afcb7ae6ed0so989725066b.3 for ; Tue, 04 Nov 2025 04:31:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1762259497; x=1762864297; darn=lists.php.net; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=eWPIGU3j1yqtQs7xDCqAZDHXpjL6GNLmjJU1YoDsiNQ=; b=W6WAcqjqZmlQeiuBRoy74fJYs2ChphKcOlyNLtuknRhi61EFz08GCIdNVcZRrcpCsL G2AfbLZLF1MX4B30hqQRMe08CvxwGPLwnjsCwhZP71HYZA2iFaWNHYDUHy2U3QoKfGmp LPaxu16xomMozP9FrUWBiAD7MjNgViqanfUq2X/CuYnTXsMCHrJlkbGF099fr3iuan0H pKRUGrxFbZ8FTzqZ2xHhsM8JAMkUXwx9U4vArEzCK2t/gAJ1/DZN+U185XvsvjpG979k TekzBw8o6JQYAkfDgYfMXcJ6NrIIV+qjZIhJ10WQHXTy1euJtrWnqACzdSlFeFJgUCAs QcBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762259497; x=1762864297; 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=eWPIGU3j1yqtQs7xDCqAZDHXpjL6GNLmjJU1YoDsiNQ=; b=CDs2jXkSNh5N1C+oDtgyj3ycFnSCIqJm6yPXOrUit00OMOndECDN0eZXECfUHcvCOJ lyzUuHv0crEHR2LKkfzLUT2+b7j1ILsvoYVeSiFTJ5WxYvdxr1ovpCX7ILg/uUd2bx/1 wpTNMasCCNm3oJbfWXoURafqAEDLY2xTAcfbgpIw/iFIPKT6OZnM7j23/C8YhaYAAEqF wQYs+1W2ruFYMW1hhuxkm1wLPn6F2dOsfZJr3vxpY5kWISJO4hRoKxJOmUyRpp0nWU+C OGREMUWloyoStAsf/spdxQW4giYQeBNVdw51sDqJp4IMFx8TfIPYEXSO0X7CEjnKQrzQ /B6g== X-Gm-Message-State: AOJu0Yxq+QDiYewc9ZxAYP3PvoyNhDEKpT/1mV5ZDvHgsb6wDqguxg3U Fk55Wm/eaxjol7MsSaAddRjQVjtPacjyQa6+3XUBG/thVgC7U5M1XJtY5QR1HYRtmECnHbKnoIs 0r4WakdQSal7kHP0rkAF9E/D6wxNmLg2Em/ZRFVQ= X-Gm-Gg: ASbGncvmtOH8UMc+q1qO27kXd8KJpjRi+8Iag8HJohwSr2ffF6tUP1TTSoqi6InGdj4 NU7Og0NseYdjy48UG3FBQut/dHKgOvsPgeroIdNG9khVd7FnLdoN3/B3Q0FFUc/kRBPqAaFuQT9 EZNwIsyxvolv7Z8SQVP8RMjOGSxb0v+myCcg/l7TYxw2YDGMbUa9C34mQ3LJRGi6y1xPpT1oR0V DdgiQrG6NXdbWPFoGdjMtjAjUoyQ7g6itTIVP68a8no1tW4AI8brV+jp8nJ/XGin3wgZiM= X-Google-Smtp-Source: AGHT+IHV/4ny5ePRO30CP3dx9Z0l59JAEQxDb9N0MZrUjJ4uEKGh1LGJYXuuphU0EocwV482eCfSk2x8C++F/ZKzMJU= X-Received: by 2002:a17:907:3cd6:b0:b6d:79fa:b166 with SMTP id a640c23a62f3a-b70708b1503mr1496432766b.63.1762259496309; Tue, 04 Nov 2025 04:31:36 -0800 (PST) Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 References: In-Reply-To: Date: Tue, 4 Nov 2025 13:31:24 +0100 X-Gm-Features: AWmQ_bnWkObplt685Ety3745sDMGBgNk1YpX9mBm2deVQc0sSMpfZXt4-amGoBE Message-ID: Subject: Re: [PHP-DEV] [RFC][Discussion] use construct (Block Scoping) To: Seifeddine Gmati Cc: internals@lists.php.net Content-Type: multipart/alternative; boundary="0000000000004797440642c403ea" From: arnaud.lb@gmail.com (Arnaud Le Blanc) --0000000000004797440642c403ea Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Seifeddine, Tim, I'm in favor of a feature similar to those listed in the RFC (Python=E2=80= =99s `with` [1], C#=E2=80=99s `using` [2], Hack's `using` [6]), but the proposal= is not equivalent to these. There are major differences that prevent it from addressing the same use-cases. First, the RFC proposes that variables are only unset() when leaving the block, while Python, C#, Hack, and Java-s' try-with [3] (which is not cited, but is similar), also immediately "close" or "dispose" of the resource/object when leaving the block. This is important, as there are a number of cases in which unset() alone will not immediately call a destructor or close a resource. Then, at least in Python, disposal is made aware of exceptions, so that it can take different steps in that case. The proposal relies on destructors or automatic closing of resources, but this should not be relied on when timing matters. In general, destructors should be avoided IMHO [4][5]. They are useful in languages with stack-allocated variables because timing and order can be guaranteed, but not in heap-allocated languages with automatic GC. PHP resources/objects are heap-allocated, and its GC mechanism behavior/semantics is similar to Java's due to cycles: resource/objects are not guaranteed to be closed/disposed of immediately, and the order in which this happens is undefined. Here are some use-cases that Python's `with`, C#'s `using`, or Java's `try-with` were designed to address, but are not addressed by this RFC: // Commit the transaction as soon as the block is left, or roll it back if an exception is thrown: with ($db->beginTransaction() as $transaction) { $transaction->execute(...); $transaction->execute(...); } If $transaction escapes, it's not committed at the end of the block. Regardless, it's not possible to automatically rollback the transaction in case of exception. // Close file descriptor as soon as the block is left: with (get_fd() as $fd) { // ... } If $fd escapes, it's not closed at the end of the block. This may affect the program's behavior is various ways: * The system's file descriptor limit may be reached before the GC triggers * If $fd was a socket, and the other side waits for closing, it may hang * If $fd has unflushed writes, readers will have an inconsistent view // Await Scope at end of block: with (new Async\Scope() as $scope) { // ... } Again, if $scope escapes, it's not awaited at the end of the block, and it's not possible to automatically cancel in case of exception. Escaping/capturing is difficult to avoid, especially in large code bases, as it can not be checked with static analysis, typing, or avoided by means of API design. Sometimes it's even necessary, e.g. a file descriptor may be referenced by an I/O polling mechanism. > The RFC proposes the `use` keyword. What are your thoughts on a new `using` keyword instead, similar to C# or Hack? A possible alternative that doesn't introduce a new keyword is Java's try () syntax. > How do you feel about the questions raised in the "Open Issues" section? I would prefer Option B (Restore), as this is what I would expect from block scoping. > Introducing a Disposable interface (similar to C#'s IDisposable) to allow objects to define custom, explicit cleanup logic that is automatically called by use. I'm in favor of introducing this immediately, for the reasons above, and also because introducing this later would make it difficult to adopt the interface (implementing IDisposable on an existing class breaks existing code using it in use()). I have a preference for Python's interface, as it allows to optionally decouple (and hide) the dispose logic from the resource, makes it possible to trigger a different behavior on exception, and also makes it easier to introduce disposables without breaking code. Also, making the interface optional, such that use($foo) is allowed when $foo does not implement it, may mask programming mistakes and make the feature confusing. [1] https://peps.python.org/pep-0343/ [2] https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statemen= ts/using [3] https://docs.oracle.com/javase/8/docs/technotes/guides/language/try-with-re= sources.html [4] https://externals.io/message/125696#125710 [5] https://openjdk.org/jeps/421 [6] https://docs.hhvm.com/hack/statements/using Best Regards, Arnaud On Mon, Nov 3, 2025 at 10:47=E2=80=AFPM Seifeddine Gmati wrote: > Hello internals, > > Tim and I would like to open the discussion on our new RFC that we've bee= n > working on: "use construct (Block Scoping)". > > We wanted to raise a few initial points: > > - > > The RFC proposes the `use` keyword. What are your thoughts on a new ` > using` keyword instead, similar to C# or Hack? > - > > How do you feel about the questions raised in the "Open Issues" > section? > - > > What are your general thoughts on the RFC? > > Please find the following resources for your reference: > > - > > RFC: https://wiki.php.net/rfc/optin_block_scoping > - > > POC: > https://github.com/php/php-src/compare/master...TimWolla:php-src:block= -scope > > Thanks, > > Seifeddine Gmati. > > --0000000000004797440642c403ea Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Seifeddine, Tim,

I'm in favo= r of a feature similar to those listed in the RFC (Python=E2=80=99s `with` = [1], C#=E2=80=99s `using` [2], Hack's `using` [6]), but the proposal is= not equivalent to these. There are major differences that prevent it from = addressing the same use-cases.

First, the RFC proposes that variab= les are only unset() when leaving the block, while Python, C#, Hack, and Ja= va-s' try-with [3] (which is not cited, but is similar), also immediate= ly "close" or "dispose" of the resource/object when lea= ving the block. This is important, as there are a number of cases in which = unset() alone will not immediately call a destructor or close a resource.
Then, at least in Python, disposal is made aware of exceptions, so th= at it can take different steps in that case.

The proposal relies on = destructors or automatic closing of resources, but this should not be relie= d on when timing matters. In general, destructors should be avoided IMHO [4= ][5]. They are useful in languages with stack-allocated variables because t= iming and order can be guaranteed, but not in heap-allocated languages with= automatic GC. PHP resources/objects are heap-allocated, and its GC mechani= sm behavior/semantics is similar to Java's due to cycles: resource/obje= cts are not guaranteed to be closed/disposed of immediately, and the order = in which this happens is undefined.

Here are some use-cases that Pyt= hon's `with`, C#'s `using`, or Java's `try-with` were designed = to address, but are not addressed by this RFC:

// Commit the transaction as soon as the block is left, or roll = it back if an exception is thrown:
with ($db->beginTransaction() as $= transaction) {
=C2=A0 =C2=A0 $transaction->execute(...);
=C2=A0 = =C2=A0 $transaction->execute(...);
}

If $transaction esc= apes, it's not committed at the end of the block. Regardless, it's = not possible to automatically rollback the transaction in case of exception= .

// Close file descriptor as soon a= s the block is left:
with (get_fd() as $fd) {
=C2=A0 // ...
}
<= /div>
If $fd escapes, it's not closed at the end of the block. = This may affect the program's behavior is various ways:
=C2=A0* Th= e system's file descriptor limit may be reached before the GC triggers<= br>=C2=A0* If $fd was a socket, and the other side waits for closing, it ma= y hang
=C2=A0* If $fd has unflushed writes, readers will have an inconsi= stent view

// Await Scope at end of = block:
with (new Async\Scope() as $scope) {
=C2=A0 // ...
}

Again, if $scope escapes, it's not awaited at the end of the blo= ck, and it's not possible to automatically cancel in case of exception.=

Escaping/capturing is difficult to avoid, especially in large = code bases, as it can not be checked with static analysis, typing, or avoid= ed by means of API design. Sometimes it's even necessary, e.g. a file d= escriptor may be referenced by an I/O polling mechanism.

> The = RFC proposes the `use` keyword. What are your thoughts on a new `using` key= word instead, similar to C# or Hack?

A possible alternative that doe= sn't introduce a new keyword is Java's try () syntax.

> H= ow do you feel about the questions raised in the "Open Issues" se= ction?

I would prefer Option B (Restore), as this is what I wou= ld expect from block scoping.

>=C2=A0Introducin= g a Disposable interface=20 (similar to C#'s IDisposable) to allow objects to define custom,=20 explicit cleanup logic that is automatically called by use.

<= /div>
I'm in favor of introducing this immediately, for the reasons= above, and also because introducing this later would make it difficult to = adopt the interface (implementing IDisposable on an existing class breaks e= xisting code using it in use()). I have a preference for Python's inter= face, as it allows to optionally decouple (and hide) the dispose logic from= the resource, makes it possible to trigger a different behavior on excepti= on, and also makes it easier to introduce disposables without breaking code= . Also, making the interface optional, such that use($foo) is allowed when = $foo does not implement it, may mask programming mistakes and make the feat= ure confusing.

[1] https://peps.python.org/pep-0343/
[2] https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/stateme= nts/using
[3] https://docs.oracle.com/javas= e/8/docs/technotes/guides/language/try-with-resources.html
[4] https://externals.io/mess= age/125696#125710

Best Regards,
Arnaud

On Mon, Nov 3, 2025 at 10:47=E2=80=AFPM Seifeddine Gmati = <azjezz@carthage.software> wrote:

Hello internals,

Tim and I would like to open the discussion = on our new RFC that we've been working on: "use construct (Block S= coping)".

We= wanted to raise a few initial points:

  • The RFC proposes the=C2=A0`use` = keyword. What are your thoughts on a new `using` keyword inste= ad, similar to C# or Hack?

  • How do you feel about the questions raised in the "= Open Issues" section?

  • What are your general thoughts on the RFC?

Please find the foll= owing resources for your reference:

Thanks,

Seifeddine Gmati.


--0000000000004797440642c403ea--