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