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

Reply via email to