# Raising the precedence of the new operator

- Thread: https://externals.io/message/113953
- Original archive: https://news-web.php.net/php.internals/113953
- Started by andre@webkr.de on 2021-04-05T16:40:49+00:00
- Messages: 12
- RFC: new MyClass()->method() without parentheses (Implemented (PHP 8.4)) — https://externals.io/rfc/new_without_parentheses.md
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #113953 — andre@webkr.de — 2021-04-05T16:40:49+00:00

URL: https://externals.io/message/113953#113953

I was wondering... PHP is the only language I know of where you have to
write `(new Foo())->bar()` instead of
`new Foo()->bar()`. This is particularly apparent with the builder pattern:

$developer->drink((new Coffee())->withCream()->withSugar());
$logger->log((new LogMessage())->withMessage('Coffee was drunk'));

Since `new Foo()->bar()` cannot (and probably should not) be used to
"dynamically instantiate a new thing of the class
name returned by function Foo()", it seems like it would be no problem to
change the precedence rules so that
`new Foo()->bar()` means "instantiate a new Foo and call bar() on it".

It's currently a syntax error, so allowing it would be automatically
compatible.

Has this ever been discussed before?

---

## #113954 — Ben Ramsey — 2021-04-05T16:47:26+00:00

URL: https://externals.io/message/113953#113954 · In reply to: #113953

> 
> 
> I was wondering... PHP is the only language I know of where you have to
> write `(new Foo())->bar()` instead of
> `new Foo()->bar()`. This is particularly apparent with the builder pattern:
> 
> $developer->drink((new Coffee())->withCream()->withSugar());
> $logger->log((new LogMessage())->withMessage('Coffee was drunk'));
> 
> Since `new Foo()->bar()` cannot (and probably should not) be used to
> "dynamically instantiate a new thing of the class
> name returned by function Foo()", it seems like it would be no problem to
> change the precedence rules so that
> `new Foo()->bar()` means "instantiate a new Foo and call bar() on it".
> 
> It's currently a syntax error, so allowing it would be automatically
> compatible.
> 
> Has this ever been discussed before?


Mike Schinkel and I recently discussed this off-list. Mike, now’s your
time to chime in with your ideas on this. :-)

My $0.02 is that this is unnecessary, but I can see how others might
want it to avoid parenthesis soup.

Cheers,
Ben

---

## #113955 — Christoph M. Becker — 2021-04-05T17:12:46+00:00

URL: https://externals.io/message/113953#113955 · In reply to: #113953

> I was wondering... PHP is the only language I know of where you have to
> write `(new Foo())->bar()` instead of
> `new Foo()->bar()`. This is particularly apparent with the builder pattern:
>
> $developer->drink((new Coffee())->withCream()->withSugar());
> $logger->log((new LogMessage())->withMessage('Coffee was drunk'));
>
> Since `new Foo()->bar()` cannot (and probably should not) be used to
> "dynamically instantiate a new thing of the class
> name returned by function Foo()", it seems like it would be no problem to
> change the precedence rules so that
> `new Foo()->bar()` means "instantiate a new Foo and call bar() on it".
>
> It's currently a syntax error, so allowing it would be automatically
> compatible.
>
> Has this ever been discussed before?

See <https://bugs.php.net/bug.php?id=70549>.

--
Christoph M. Becker

---

## #113957 — Ben Ramsey — 2021-04-05T17:19:35+00:00

URL: https://externals.io/message/113953#113957 · In reply to: #113955

> 
> 
> 
> 
> > […]
> 
> See <https://bugs.php.net/bug.php?id=70549>.


The last comment on that issue reads:

> @Nikic
> Good news. I'll prepare RFC for 7.1.

Was there an RFC for it? I can’t find one.

Cheers,
Ben

---

## #113958 — Mike Schinkel — 2021-04-05T17:42:15+00:00

URL: https://externals.io/message/113953#113958 · In reply to: #113954

> 
> 
> > […]
> 
> 
> Mike Schinkel and I recently discussed this off-list. Mike, now’s your
> time to chime in with your ideas on this. :-)

Thanks for the invite.

I had asked Ben what he thought about allowing the following syntax as a synonym for `new Foo()`:

Foo::new()

That would be backward compatible because you currently cannot have a method named `new()`.

> My $0.02 is that this is unnecessary, but I can see how others might
> want it to avoid parenthesis soup.

Yes, off list Ben said he did not see the need for it, so I did not bring it up on the list.  

But now since he has invited me to... :-)

If we had such syntax then that would also Andre and others to use (and reduce the necessity of needing so many parens:

     Foo::new()->bar()

Thoughts?

-Mike

---

## #113964 — andre@webkr.de — 2021-04-05T19:51:35+00:00

URL: https://externals.io/message/113953#113964 · In reply to: #113958

Mike Schinkel wrote:

> I had asked Ben what he thought about allowing the following syntax as a synonym for `new Foo()`:
>
> Foo::new()

This can already be done in application code, having the language add a synonym is IMO unnecessary magic and breaks the
principle of the least surprise.

The solution proposed in https://bugs.php.net/bug.php?id=70549 however is very similar to what I'm asking.
Note that in that bug entry the solution was based on the premise that `$obj = new $foo->bar();` was valid code, which
it isn't. (https://3v4l.org/lpN1T)

---

## #113965 — Rowan Tommins — 2021-04-05T20:10:09+00:00

URL: https://externals.io/message/113953#113965 · In reply to: #113964

> Note that in that bug entry the solution was based on the premise that `$obj = new $foo->bar();` was valid code, which
> it isn't. (https://3v4l.org/lpN1T)


Looking at the error message, that code parsed as valid, but failed at 
run-time, because it was looking for a property $bar, not a method 
bar(). Working version: https://3v4l.org/S9gLf

It's equivalent to:

$className = $foo->bar;
$obj = new $className();


I think this means that just changing the operator precedence would be a 
compatibility break, and we would need to allow a more restricted 
version, as discussed on that feature request.

Regards,

-- 
Rowan Tommins
[IMSoP]

---

## #113966 — Stanislav Malyshev — 2021-04-05T20:26:52+00:00

URL: https://externals.io/message/113953#113966 · In reply to: #113953

Hi!


> I was wondering... PHP is the only language I know of where you have to
> write `(new Foo())->bar()` instead of
> `new Foo()->bar()`. This is particularly apparent with the builder pattern:

Enabling something that is syntax error now sounds pretty innocent, but 
I wonder if messing with precedence would cause some deeper consequences 
in different expressions. We need to be careful here given how much code 
(and how much weird code) there exists in PHP. If we can guarantee that 
we can enable this construct without causing any side effects, then it's 
fine I think.
-- 
Stas Malyshev
smalyshev@gmail.com

---

## #113967 — andre@webkr.de — 2021-04-05T20:28:24+00:00

URL: https://externals.io/message/113953#113967 · In reply to: #113965

Rowan Tommins wrote:

> it was looking for a property $bar, not a method bar(). Working version: https://3v4l.org/S9gLf

Oh, right.

> we would need to allow a more restricted version, as discussed on that feature request.

Yeah, that would be great. I think it would already cover the by far most common use case.

---

## #113968 — Christoph M. Becker — 2021-04-05T20:40:14+00:00

URL: https://externals.io/message/113953#113968 · In reply to: #113957

> > […]
>
> The last comment on that issue reads:
>
> > […]
>
> Was there an RFC for it? I can’t find one.

I don't think there ever was an RFC for this.

--
Christoph M. Becker

---

## #113969 — Marco Pivetta — 2021-04-05T20:51:33+00:00

URL: https://externals.io/message/113953#113969 · In reply to: #113958

>
> > […]
> pattern:
> > […]
> to
> > […]
>
> Thanks for the invite.
>
> I had asked Ben what he thought about allowing the following syntax as a
> synonym for `new Foo()`:
>
> Foo::new()
>
> That would be backward compatible because you currently cannot have a
> method named `new()`.
>

I have static ctors named `new` in multiple codebases:
https://3v4l.org/FudWpk

---

## #113970 — Marco Pivetta — 2021-04-05T20:52:53+00:00

URL: https://externals.io/message/113953#113970 · In reply to: #113969

>
>
> 
>
> > […]
>
> I have static ctors named `new` in multiple codebases:
> https://3v4l.org/FudWpk
>





> Sorry, mails synchronized now, and I did not realize that you already had
a waterfall of responses related to this :|
