Welcome! Log In Create A New Profile

Advanced

[PHP-DEV] Suggested change: change priority of new and ->

Posted by Mcmuffin Mcguffin 
Mcmuffin Mcguffin
[PHP-DEV] Suggested change: change priority of new and ->
February 08, 2018 07:50PM
Hi,

It's a common idiom in object-oriented languages to create an object and
then immediately call a method on it, such as (in C# or Java):

new DateTime ().ToString ()

However, PHP grammar does not work this way. You have to put an additional
round of parentheses around new clause, such as:

(new DateTime ())->format ('Y-m-d')

This is rather clunky for such a common scenario (you usually have to walk
all the way back to the beginning of the expression to fix it). I have a
pattern of using static factories in place of constructor just to avoid
extra parentheses. Besides, the issue is relatively easy to fix. I've done
and tested a change for grammar in this area. It's a slight adjustment to
definition of dereferencable:

dereferencable:
> variable { $$ = $1; }
> | '(' expr ')' { $$ = $2; }
> * | new_expr { $$ = $1; }*
> | dereferencable_scalar { $$ = $1; }
> ;
>

There was a problem with shift/reduces though. PHP has a level of
complexity in new expression which other languages don't. It's variable
class instantiation, such as:

new $class (arguments)

Expressions in place of $class can be rather complex, though I don't think
they really need to be. For example, such stuff is allowed:

new $var[0]->prop (arguments)

— which seems redundant and confusing. My fix to the problem was to force
parentheses around complex expressions such as above:

new ($var[0]->prop) (arguments)

— while keeping simple cases of "new $class (arguments)" without change.
Yes, this moves parentheses from one place to another (and occasionally
breaks the old code) but frequency wise I think it's an improvement.

What do you think?

Jaroslav Wegner
Haralan Dobrev
Re: [PHP-DEV] Suggested change: change priority of new and ->
February 08, 2018 11:40PM
I really like the proposal and it's definitely improving more common modern
use cases.

However, I understand why the precedence is like that now in PHP to begin
with and so I think this should target PHP 8.

This change would be a bit similar to other weird use cases of variables
which were changed with PHP 7.

Best,
Harry

On Thu, 8 Feb 2018 at 20:45 Mcmuffin Mcguffin <[email protected]>
wrote:

> Hi,
>
> It's a common idiom in object-oriented languages to create an object and
> then immediately call a method on it, such as (in C# or Java):
>
> new DateTime ().ToString ()
>
> However, PHP grammar does not work this way. You have to put an additional
> round of parentheses around new clause, such as:
>
> (new DateTime ())->format ('Y-m-d')
>
> This is rather clunky for such a common scenario (you usually have to walk
> all the way back to the beginning of the expression to fix it). I have a
> pattern of using static factories in place of constructor just to avoid
> extra parentheses. Besides, the issue is relatively easy to fix. I've done
> and tested a change for grammar in this area. It's a slight adjustment to
> definition of dereferencable:
>
> dereferencable:
> > variable { $$ = $1; }
> > | '(' expr ')' { $$ = $2; }
> > * | new_expr { $$ = $1; }*
> > | dereferencable_scalar { $$ = $1; }
> > ;
> >
>
> There was a problem with shift/reduces though. PHP has a level of
> complexity in new expression which other languages don't. It's variable
> class instantiation, such as:
>
> new $class (arguments)
>
> Expressions in place of $class can be rather complex, though I don't think
> they really need to be. For example, such stuff is allowed:
>
> new $var[0]->prop (arguments)
>
> — which seems redundant and confusing. My fix to the problem was to force
> parentheses around complex expressions such as above:
>
> new ($var[0]->prop) (arguments)
>
> — while keeping simple cases of "new $class (arguments)" without change.
> Yes, this moves parentheses from one place to another (and occasionally
> breaks the old code) but frequency wise I think it's an improvement.
>
> What do you think?
>
> Jaroslav Wegner
>
--

Haralan Dobrev
CTO @ Clippings.com

https://hkdobrev.com
Fleshgrinder
Re: [PHP-DEV] Suggested change: change priority of new and ->
February 15, 2018 08:20AM
On 2/8/2018 7:38 PM, Mcmuffin Mcguffin wrote:
> What do you think?
>
> Jaroslav Wegner
>

Thanks for the hard work to figure out what the roots of this annoyance
is. This could land in the next PHP version, considering that many other
breaking changes were also allowed in the past, given the following
prerequisites:

* RFC with a 2/3 majority vote
* Tool to convert any possibly broken code into valid code (basically
putting parenthesis around any complex `new (...)()`).
* Update to
https://github.com/php/php-langspec/blob/master/spec/10-expressions.md#the-new-operator

--
Richard "Fleshgrinder" Fussenegger

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Stephen Reay
Re: [PHP-DEV] Suggested change: change priority of new and ->
February 15, 2018 09:40AM
> On 9 Feb 2018, at 01:38, Mcmuffin Mcguffin <[email protected]> wrote:
>
> new $var[0]

Is that creating an instance of the class name stored in the 0th index of the array $var or is it creating an instance of the class name stored in $var and accessing the 0th index using ArrayAccess?

Cheers

Stephen

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Pedro Lacerda
Re: [PHP-DEV] Suggested change: change priority of new and ->
February 15, 2018 10:30AM
Great contribution, very sensible even if subtile.

Is the kind of change that improve a lot but cause some trouble to people
used to the old way or when upgrading legacy codebases.

2018-02-15 5:32 GMT-03:00 Stephen Reay <[email protected]>:

>
> > On 9 Feb 2018, at 01:38, Mcmuffin Mcguffin <[email protected]>
> wrote:
> >
> > new $var[0]
>
> Is that creating an instance of the class name stored in the 0th index of
> the array $var or is it creating an instance of the class name stored in
> $var and accessing the 0th index using ArrayAccess?
>
> Cheers
>
> Stephen
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


--
Atenciosamente,
Pedro Lacerda
Mcmuffin Mcguffin
Re: [PHP-DEV] Suggested change: change priority of new and ->
February 17, 2018 03:10PM
>
> Is that creating an instance of the class name stored in the 0th index of
> the array $var or is it creating an instance of the class name stored in
> $var and accessing the 0th index using ArrayAccess?
>

As soon as $var gets involved, it should be prioritized above the new
operator. So it's equivalent of "new ($var[0])"

Jaroslav
Rowan Collins
Re: [PHP-DEV] Suggested change: change priority of new and ->
February 17, 2018 03:50PM
On 8 February 2018 18:38:36 GMT+00:00, Mcmuffin Mcguffin <[email protected]> wrote:
>Hi,
>
>It's a common idiom in object-oriented languages to create an object
>and
>then immediately call a method on it, such as (in C# or Java):
>
>new DateTime ().ToString ()
>
>However, PHP grammar does not work this way.

This would definitely be nice to have, and thanks for looking into what the necessary change would look like.

I think the next challenge is to work out the different ways a dynamic class construction could happen, and which ones:
a) will be unaffected by the change
b) are an error now and will be allowed after
c) are allowed now and will be an error after
d) will work in both versions but change behaviour

It's anything that falls into category (d) that is particularly problematic, as it means users will see odd bugs of they don't know about the change. The clearer we can make these examples, the better.

Contrary to other responses, I think this would definitely need to happen in a major version, as it is quite clearly a breaking change. There's not much that can be done to deprecate code relying on the current rules, but we can publicise how to make code that is compatible before and after.

Regards,

--
Rowan Collins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Andrea Faulds
[PHP-DEV] Re: Suggested change: change priority of new and ->
February 19, 2018 12:50AM
Hi,

I'm not… quite sure if it changes anything, but it seems worth pointing
out PHP has two syntaxes for `new`. You can do `new DateTime()`, but you
can /also/ do `new DateTime` without the brackets.

So, while you can't do `new DateTime()->format(DATE_ATOM)`, you *can* do
`(new DateTime)->format(DATE_ATOM)`. This is just as short. It's only
for constructor calls requiring arguments that we get the problem.

It also makes me wonder if it's not dereferenceable because then `new
DateTime()` would be ambiguous: is it constructing a DateTime, or is it
invoking a newly-constructed DateTime as a function? Be aware that
__invoke can be implemented by a class to make its objects callable.

Thanks!

--
Andrea Faulds
https://ajf.me/

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Sorry, only registered users may post in this forum.

Click here to login