On Tue, Dec 16, 2025, at 5:25 AM, Deleu wrote:
> On Tue, Dec 16, 2025 at 5:10 AM Rowan Tommins [IMSoP] 
> <[email protected]> wrote:
>> (Replying to a few of you in one go, I hope the formatting is clear) 
>> 
>> >>> we have changed the RFC to use => instead.  So the new syntax is
>> >>>
>> >>> using (new CM() => $cVar) {
>> >>>   // Do stuff here.
>> >>> }
>> >>>
>> >>
>> >> Going to be controversial here, but this is confusing, because it operates
>> >> in the exact opposite of every other usage of => we have. 
>> >
>> > I agree with Matthew.
>> >
>> > I think it makes more sense to reverse them, like this:
>> >
>> >     using ($cVar => new CM()) {
>> >         // Do stuff here.
>> >     }
>> 
>> 
>> It took me a long time to figure out what you were both saying here, because 
>> to me the direction of the arrow seems to consistently indicate data flow: 
>> you call the function, and data comes out; you enter the context, and a 
>> variable comes out.
>> 
>> But I think I see it now: you're treating the context variable like an array 
>> key, that is somehow "bound to" the result. Except that's not what's 
>> happening, otherwise we could just use "=".
>> 
>> 
>> >I also agree with Matthew but the reversed proposed here looks very very
>> >awkward to me. I think the most natural thing is the “as” but I may have
>> >missed the discussion on why it had to be changed.
>> >
>> >Thinking of foreach ($array as $value), an item from the array (left) is
>> >assigned to $value (right).
>> 
>> 
>> This is the way to read the "as" syntax, yes; as I've said in a few places, 
>> a Context Manager is like an iterator that goes around once.
>> 
>> 
>> > That seems symmetrical to using (new Manager as
>> >$manager) where the instance (left) is assigned to the variable (right).
>> 
>> 
>> This, however, is why it was changed: that is *not* what is happening. The 
>> Context Manager is not assigned to the variable, it *produces a value* which 
>> is assigned to the variable. 
>> 
>> Again, look at the foreach equivalence: you wouldn't write "foreach(new 
>> MyIterator as $iterator)", because it's not the iterator that ends up in the 
>> variable, it's the *items produced by* the iterator. 
>> 
>> So you have "foreach(new MyIterator as $item)" and "using(new 
>> MyContextManager as $contextVar)". 
>> 
>> But evidently that is not obvious to readers.
>
> My conclusion here is exactly the opposite of yours because this 
> explanation makes `as` even more symmetrical now. As you've mentioned 
> `foreach(new MyIterator as $iterator)` is not how it works. An iterator 
> *produces a value* that is assigned to the variable after `as`. 
> Symmetrically, `using(new ContextManager as $context)` the 
> ContextManager is also producing a value that is assigned to the 
> variable after `as`. The only difference is in the keyword: foreach 
> will loop, but using will not loop since ContextManager is not an 
> iterator.
>
> I'm assuming this would also be a valid syntax: `using ($manager = new 
> ContextManager as $context)` which gives us a shot at capturing the 
> context manager.
>
> I wrote a little snippet to try and see (using GitHub Gist Syntax 
> Highlighter) how some of the options would look like once IDE support / 
> syntax highlighting is baked in:
>
> image.png
>
> Ultimately, people will take a quick reading in a Context Manager 
> documentation and the parallels to explain how it works seems to be 
> very well in place for `as`, imo.
>
> In the image above I tried adding `for using` because I was trying 
> really hard to come up with a word that could replace `each` in 
> `foreach` to make it even more symmetrical, but I could not find 
> anything decent.
>
> - `for context(new ContextManager as $context)` 
> This one reads well, but the fact its two words (and a long word for 
> that matter) doesn't sit well.
>
> - `for with(new ContextManager as $context)`
> I'm not a native English speaker, but I think this doesn't read at all
>
> - `for one(new ContextManager as $context)`
> Kind of implies it works with iterators (similar to each), which is not 
> exactly the case and the language has very little motivation to create 
> an iterator that loops only once just to make this work.
>
> - `for using(new ContextManager as $context)`
> Similar thoughts as `for context`, the only difference that makes me 
> like this one more is because `for context` doesn't sit well with `try 
> context` while `for using` could go well with `try using`.
>
> In any case, the longer I sit with this the more I dislike `=>` for this. 
>
> In an array, `=>` is an assignment of key/value pairs. 
> For foreach ($iterator as $key => $value), the => is a destructing 
> instruction that aligns with how the array was originally assigned.
> For the arrow function, it's kind of implied in the name ARROW function 
> that we would need a syntax in the lines of `fn () =>`. I don't think 
> this relates well with arrays, but it works well to me because of how 
> universal arrow functions are in Javascript. 
> For match ($value), it reads as `WHEN ($value) MATCH '' THEN. The arrow 
> here `=>` is the THEN.
>
> My conclusion is that `=>` is either a value placement (for arrays) or 
> an instruction execution (for arrow function and match). As such, If => 
> were to be incorporated into Context Managers, I think it would make 
> much more sense like this:
>
> `using (new ContextManager as $context) => [single line expression]` 
> where the arrow creates a symmetry with how arrow functions work.
>
>
> -- 
> Marco Deleu

First, yeesh, where were y'all 2 weeks ago? :-P

Second, I find it fascinating that there's so many different 
mutually-incompatible spins on what => means.  As argued in the short-functions 
and auto-capture-closure RFCs from a few years ago, => in nearly all cases 
currently means "evaluates to."

$arr = [
  'a' => 'A",
  'b' => 'B',
];

$arr['a'] // This "evaluates to" A

match ($foo) {
  'a' => 'A',
  'b' => 'B', // The 'b' case "evaluates to" B
};

fn($foo) => 'bar'; // This function "evaluates to" bar

foreach ($arr as $k => $v) {}

The last is a little bit inconsistent, but can still be read as "$k, and the 
thing that $k evaluates to."

So given that, and as Rowan noted the context manager is *NOT* the context 
variable:

using ($cm evaluates to $cv) {}

That's the meaning we're going for.

If there's some better word than =>, we're still open to it, but I am going to 
insist on left-to-right reading.  $cm is created first, then it produces $cv.

'as' is what we had originally, since that's what Python used.  However, it was 
pointed out that it was confusing as it implied the CM and CV were the same 
thing, or rather the expression on the left gets assigned to $cv, which is not 
the case.  Hence the change.

A symbol does have the (dis?)advantage of a somewhat squishier meaning than a 
keyword.

--Larry Garfield

Reply via email to