Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:128904 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 A293C1A00BC for ; Wed, 22 Oct 2025 15:30:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1761147028; bh=h8XWx3NIwsRfCw+N1j2OSf0cf9tVPKYLjqHQGYWn/yo=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=kKthtQxmflFhwlcTkAzy7lopieVJlL8NSGMrkcABx7mXETxYo5wglPd2A5tH0/kyr TO7KmKWtZG+LcmOld5egyH1Z9R4aNrbTth3ak/n6J2+53Sf1p5LcSI2v9XBWIXpZWN CeEg6wBbSe4ILxP8mzZnoO/Q5sSTQJeDMS8suk8+HArdOGLWEWyvFzoy9U6ac2+Ucv 9OJoinQCL6KVKVVic63wQUUT/Y7brDIKPEF4JCNEQqNrt4NWzZajoTYhCCH/uGg6PX ndhZN2eYRJ1x7eoegzVIpLLjv3YMxZCPwfrutlvEjraoVgmADAK3aWhXaUt8Pbp2+V cVYFlRTZMFzsQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 6241418007E for ; Wed, 22 Oct 2025 15:30:27 +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=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from mail-ua1-f43.google.com (mail-ua1-f43.google.com [209.85.222.43]) (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 ; Wed, 22 Oct 2025 15:30:27 +0000 (UTC) Received: by mail-ua1-f43.google.com with SMTP id a1e0cc1a2514c-932c247fb9aso1677248241.2 for ; Wed, 22 Oct 2025 08:30:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1761147021; x=1761751821; darn=lists.php.net; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=h8XWx3NIwsRfCw+N1j2OSf0cf9tVPKYLjqHQGYWn/yo=; b=DVXo4YCAxhJyaQ7oUpl3LXXKEIPw2SkO6OfEy2NC6Mo+NVQEnMG2+MjQQDm2QzKgCJ So8FRCiItt4WXkuhqAeiZ0cRK/8syK7s5jejV0fBl4r3FI9ue1YiYzNtuMQYVwP+oWVi uq7cPACdKOGjlsrAIIus7127/zLh2UaA0ojBbb25K4nc/ODW99q8mbZvzCiTd/4C2GUC g9T6tBd+E1cMjUM12mW4PZHu9cMn0O7qt5w8AULRBM4AwwpHnpwSKMWNt+kdzQ3f2ClO YN9ohkT37T0x0KmsAQZvrCm0KsCpHh+J4ud18a4vZs3+QxjkJkP0y3Os15bD39w20SJE jlxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761147021; x=1761751821; h=content-transfer-encoding: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=h8XWx3NIwsRfCw+N1j2OSf0cf9tVPKYLjqHQGYWn/yo=; b=eSY+Y6Ld8TPaga2qUo1WGHwtVcqOebrtU79LM8/DsePzZNgXRmj839/7wITfV6FwCv a0HN24Ve4kOQZExRJmHkYvAeWCoj+PgSWfmK0LkZiczLr7QZmhBmLyKgDuKZUChA9Kzz +KPGD5UGxuwbY0LsBSAIfz5VlcQ4xK54VHITQzCJh2/0HqHuAFf8ypG+J2UMGgtM8j8Y JdPj+JYgsm61Mzsln2s5FSjsKBM+D43szMKOiM+mbyK9CKDOSS2EB+sz/OU3B6Q7np5H 5RQnt4kLtY+V2lT1OtI8d79+kxVJ3Vbm5o/qP3hpJRZCnU6CzMwXWqmAAN6i8rVq0Qay BD1A== X-Forwarded-Encrypted: i=1; AJvYcCXqvFknDaZ3phf2Zs2FjFFRge+WPMvKnfhPPCAp6uHVglb5qvjB8HvAv4bGa3HgV1KUhcE6FGQPO1c=@lists.php.net X-Gm-Message-State: AOJu0YzoSrQTOkqGBlAN2/67tWjrrVxpoNBAVoz8t4vhiyS1iYOV0OdN QDVZYBP18FzXuGw5pxVYBNrNNiXhV/BVo4YwzBQm/ZI2ZSs4V+snlXIslhxHjlF7L8WX1KJV83z CvLxLbC8WNjmWwdzsESMvJo7DI/teuJ0= X-Gm-Gg: ASbGncveJiIqdw2CLbQbq/CpMop3+Mo+wPfwM7DxqS+39CQZ1W6hg7jLel5G9L4ES23 aZNtNJ+QC1LnPN/GtORDPMfugSg34ErTT5m3rq6ewsKTQV9+2j9ZlwMvjmtNdvlBnqP+5bsCBP3 qSklD4tHOdEhfY2TQpqZHbPQrK/dNo+o86ZettvXrJjH9zS4vye6ZEpIYbstPJpVKFMRUav3WWr u5VKFY3XX4/LO24lA0CHykXUSN+Une+lcEGoTBVxz68cR8wwCi+68Osj12H3NUQh1XRF23RB0yw 0aj5b0KK/Le8Gf0= X-Google-Smtp-Source: AGHT+IE80aSHb5akWBEIP2ix0VT/5zV9Nh1CCtfR8DQuf7kWmWfbSqL0VSg/gVM23VRX9JmpkWF8k7v8vPpJ0CdXXnE= X-Received: by 2002:a05:6102:3050:b0:5db:2217:3b63 with SMTP id ada2fe7eead31-5db221740f2mr775905137.39.1761147021257; Wed, 22 Oct 2025 08:30:21 -0700 (PDT) Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 References: <0e4e39d6-9cc9-4970-92e0-2463143b4011@app.fastmail.com> <37180d8d-85b4-49a3-a672-334bf4329470@app.fastmail.com> <2f8524a7-dea2-4fbf-933a-c538d3706253@app.fastmail.com> <151800a7-1094-49bc-8e43-c593a74741af@app.fastmail.com> <772a457f-69b6-4a76-8224-081917d719f6@app.fastmail.com> In-Reply-To: <772a457f-69b6-4a76-8224-081917d719f6@app.fastmail.com> Date: Wed, 22 Oct 2025 18:30:09 +0300 X-Gm-Features: AS18NWBLZtGTwVghRHEYQta3re2ZjU8j8WM2sVADXfcibROWJviApMTGIMvbYIc Message-ID: Subject: Re: [PHP-DEV] PHP True Async RFC Stage 4 To: Rob Landers Cc: Aaron Piotrowski , PHP Internals Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable From: edmond.ht@gmail.com (Edmond Dantes) > This isn't even the same example. We're not talking about type juggling, = but an interface. Mixed is not an object nor an interface. Why? Type and Interface are contracts. > The "FutureLike" type is exactly what I'm arguing for! I have nothing against this interface. My point is different: 1. Should the await and awaitXX functions accept only Future? 2. Should Awaitable be hidden from the PHP userland? > foreach($next =3D await($awaitable)) { } What=E2=80=99s the problem here? The object will return a result. If the result is iterable, it will go into the foreach loop. An absolutely normal situation. > error: multiple usages of multi-shot Awaitable; you may get a different r= esult on each invocation of await() Why can=E2=80=99t you call await twice? What=E2=80=99s illegal about it? If it=E2=80=99s a Future, you=E2=80=99ll get the previous result; if it=E2= =80=99s an Awaitable, you=E2=80=99ll get the second value. But the correctness of the code here 100% depends on the programmer=E2=80= =99s intent. > The RFC doesn't spell this out and needs some work here. I don=E2=80=99t understand what exactly isn=E2=80=99t specified in the RFC? > When I say "violations" I mean that, assuming $a and $b resolve instantly= : > awaitAll([$a, $b]) !=3D=3D [await($a), await($b)] > ... This is a logical error. =D0=A1ircular reasoning. The desired behavior is being used here as proof of the undesired one. (recursion) In the general case, these equations should not work =E2=80=94 and that=E2= =80=99s normal if the code expects entities that are not Future, but, for example, channels. > This is my mistake though. The discussion about await() is all mixed up w= ith coroutines so its hard to tell what the actual behaviour for await() is= outside of the context of coroutines. > The violation I thought of only applies to coroutines, the actual behavio= ur is "undefined" in the RFC. `await()` does two things: 1. Puts the coroutine into a waiting state. 2. Wakes it up when the `Awaitable` object emits an event. `awaitAny` / `awaitAll` do the same but for a list of objects or an iterato= r. However, the result of `await()` depends on the object being awaited. Thus, there are two separate contracts here: 1. **The waiting contract** =E2=80=94 how the waiting occurs. 2. **The result contract** =E2=80=94 how the result is obtained. From a language design perspective, there should be an explicit representation for these contracts. Something similar appeared only in Swift (e.g., `try await`). So, from the standpoint of =E2=80=9Cperfect design,=E2=80=9D this is a simp= lification, which makes it not ideal. I can remove the `Awaitable` interface from the `RFC` and replace it with `FutureLike`. It costs nothing to do so. But before doing that, I want to be at least 95% sure that in 2=E2=80=933 years we won=E2=80=99t have to bring it back or add workarounds. > It has everything to do with it! If a multi-shot Awaitable keeps emitting= , this causes repeated wakeups to the same continuation. It has to schedule= this every time and there isn't a way to say "don't > produce until consum= ed". You can basically starve other tasks from executing. However, if you u= se iterables of single-shot Awaitables, you get backpressure "for free" and= don't request the next > future until the previous one is complete, otherwise, the buffering press= ure lands in the awaitable (unbounded memory) or in the schedulers ready qu= eue (which affects fairness). Further, when > cancelling a multi-shot awaitable, should the scheduler drop pending emis= sions and what happens if it keeps re-enqueing it anyway? It makes the sche= duler far more complicated than it needs to > be! If an Awaitable object isn=E2=80=99t being awaited, it can=E2=80=99t emit e= vents, nor can it interfere with the scheduler. Unless the programmer explicitly creates new coroutines for every event by = hand. If an Awaitable has a lot of data and wakes up 1000 coroutines, then the scheduler will ensure that all those coroutines get executed. But until these 1000 coroutines finish processing the data, the Awaitable cannot wake anyone else. So there is a natural limit to the number of subscribers. it can only be exceeded through explicitly incorrect handling of coroutines. Because the scheduler=E2=80=99s algorithm is extremely simple, it has littl= e to no starvation issues. Starvation problems usually arise in schedulers that use more =E2=80=9Cintelligent=E2=80=9D approaches. > A footgun is any reasonable looking code that subtly breaks because the c= ontract is weak, not because the programmer didn't RTFM. The code cannot be considered =E2=80=9Creasonable,=E2=80=9D because in this= case the programmer is clearly violating the contract. And not because the contract is complex or confusing, but because they completely ignored it. This doesn=E2=80=99t look like a footgun.