Re: RFC proposal : "new" keyword shorthand
| From: | Andreas Hennings | Date: | Fri, 07 Jun 2024 19:02:39 +0000 |
| Subject: | Re: RFC proposal : "new" keyword shorthand | ||
| References: | 1 2 3 4 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-123544@lists.php.net to get a copy of this message | ||
On Fri, 7 Jun 2024 at 20:31, Larry Garfield <larry@garfieldtech.com> wrote:
>
> On Fri, Jun 7, 2024, at 5:56 PM, ericmann@php.net wrote:
>
> >> 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
> > --
> >
> > I'm not a fan of using ~ for this shorthand, due to the same issues
> > that have been brought up elsewhere (i.e. it already has meaning). But
> > the idea of a new interface auto-defining a function of the same name
> > is attractive. It's something I've done manually to mirror code in PHP
> > from other implementations existing in Scala leveraging case classes.
> >
> > https://docs.scala-lang.org/tour/case-classes.html for
> > anyone
> > unfamiliar with the construct:
> >
> > ```
> > case class Book(isbn: String)
> >
> > val frankenstein = Book("978-0486282114")
> > ```
> >
> > Doing something like this in PHP is a bit more ... verbose today:
> >
> > ```
> > class Book
> > {
> > public function __construct(public string $isbn) {}
> > }
> >
> > function Book(string $isbn): Book
> > {
> > return new Book($isbn);
> > }
> >
> > $frankenstein = Book("978-0486282114")
> > ```
> >
> > That's a lot of boilerplate for the shorthand to not require a
> >
new
> > keyword. Which is to say, I both agree in principle with the RFC and
> > think this would add value (particularly if I could extend the default
> > behavior of this kind of interface to support immutability, comparison,
> > etc similar to Scala case classes). I'm just not a fan of the current ~
> > proposal.
> >
> > ~Eric
>
> The issue with auto-generating a function constructor for a class is that we still don't
> have function autoloading. Which means this:
>
> // Point.php
>
> #[MakeFactoryFunction] (or whatever)
> class Point {
> public function __construct(public int $x, public int $y) {}
> }
>
> // index.php
>
> $p = Point(4, 5);
>
> will look for a function named "Point", not find one defined yet, and fatal.
>
> If we had function autoloading, that would work, assuming a reasonable generic autoloader for
> that case could be written. Who was it that's been talking about that for a while? :-)
>
> Or if we had some marker to indicate "this function call is a wrapper for a class so
> autoload it like a class", that could then trigger the class autoloader. But... that's
> basically what the original ~ proposal is, in the end. Though I agree that ~ is not a great symbol
> for it. PHP has, sadly, run out of unused symbols. (I've run into this a couple of times
> now.)
>
> --Larry Garfield
Hello Benoit.
others already pointed out problems with the $obj = ~C(); syntax,
but also with the other option, $obj = C();.
Personally I would prefer a suffix operator that would look similar to
a static method call.
This would make it a lot easier to switch between calling a static
factory and "new."
Unfortunately, $obj = C::new(); is not an option, because "new" is a
legal method name, so there could already be existing methods with
that name.
Also, $obj = C::__construct(); would be just wrong.
But if we can find anything in that direction, I would much prefer it
over a prefix operator.
E.g. $obj = C::+(); is currently not valid syntax, so it would be a
candidate, even though I don't really like it.
-- Andreas