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: 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

Reply via email to