Re: RFC proposal : "new" keyword shorthand
| From: | Rob Landers | Date: | Fri, 07 Jun 2024 17:35:30 +0000 |
| Subject: | Re: RFC proposal : "new" keyword shorthand | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-123541@lists.php.net to get a copy of this message | ||
On Fri, Jun 7, 2024, at 18:03, Benoît Condaminet wrote:
> Hello,
>
> Following the RFC process, I'm sending this to propose a PHP change. More precisely a new
> zend language token.
>
> This is somehow linked to the recently accepted RFC called "new MyClass()->method()
> without parentheses", the goal is to introduce a shorthand for the "new" keyword.
>
> *Motivations :*
> The new keyword sometime has a bad DX, for example when chaining Class instantiation like this
> :
> $foobar = new Foo( new Bar(), new Etc());
>
> We can quickly have very long class object construction in some case.
>
> In lot of Framework, to improve DX, static function construct are often used to avoid the new
> keyword, some create additional object builders, etc.
>
> As a first try, I start updated code to completely make the new keyword optional, like in Dart
> language for example, but it require very big change, with lot of impact (collision with function).
>
> So here is *my proposal : *
>
> Add a "new" shorthand, using the tilde character : "~"
> I made a POC, and it works well, declaring a new language token T_SHORT_NEW that simply reuse
> ZEND_AST_NEW under the hood.
>
> Here are some example of what it may look like for userland, through some tests I wrote :
> --TEST--
> New keyword shorthand
> --FILE--
> <?php
> class A {
> public function b() {
> echo "I'm B";
> }
> }
>
> ~A()->b();
>
> ?>
> --EXPECT--
> I'm B
> Other with nested :
>
> --TEST--
> New keyword shorthand encapsulation
> --FILE--
> <?php
> class Foo {
> public function __construct(
> public string $name
> ) {}
> }
>
> class Bar {
> public function __construct(
> public Foo $foo
> ) {}
> }
>
> $bar = ~Bar(~Foo("I'm foo in bar"));
> echo $bar->foo->name;
>
> ?>
> --EXPECT--
> I'm foo in bar
> As a last word, just wanted to add it will work on nested Attribute too, so for example this
> nested Attribute used in Doctrine :
>
> #[AttributeOverrides([
> new AttributeOverride(
> name: "id",
> column: new Column(name: "guest_id", type: "integer", length: 140)
> ),
> new AttributeOverride(
> name: "name",
> column: new Column(name: "guest_name", nullable: false, unique: true, length:
> 240)
> )]
> )]
>
> Will also work like this :
> #[AttributeOverrides([
> ~AttributeOverride(
> name: "id",
> column: new Column(name: "guest_id", type: "integer", length: 140)
> ),
> ~AttributeOverride(
> name: "name",
> column: new Column(name: "guest_name", nullable: false, unique: true, length:
> 240)
> )]
> )]
>
> About implementation, it should'n have any impact on SAPI or extension, the new keyword
> will still exist, it's just a new shorthand.
>
> I think you get the point, is it something that some of you would be interested in? I would be
> happy to make a proper RFC proposal.
>
> Just registered a wiki account : benconda
>
> Thank you,
>
> --
> Cordialement,
> Benoit Condaminet
Instead of ~ (which reminds me of the pendulum of symbols to written to symbols and back again every
10ish years; “or” vs “||”), why not make a shorthand way to write a function that calls a
constructor (kinda sorta like C# extension methods)? Something kinda like:
class MyClass implements Invocable {
public function __construct($i) {}
}
MyClass($i);
Where the Invocable interface defines a function of the same class name in the namespace that is an
alias for a new objects and forwards args to the constructor. This could be quite handy for value
objects.
I’m not necessarily a fan of magic or symbols, but just tossing it out there to spark ideas.
— Rob