On Tue, Oct 27, 2020, at 1:35 AM, Mike Schinkel wrote:
>
>
> > On Oct 26, 2020, at 10:23 AM, Michał Marcin Brzuchalski
> > <[email protected]> wrote:
> >
> > Hi Larry,
> >
> > I'm wondering why we hadn't thought yet about reducing the need for $this
> > in this syntax.
> > Since arrow functions have an ability to capture variables defined in
> > parent scope why not
> > think of the same for class properties which will automatically reduce
> > short methods verbosity.
> >
> > class X {
> > public function __construct(private int $foo, private int $bar) {}
> > public function getFoo(): int => $foo;
> > public function getBar(): int => $bar;
> > }
> >
> > And then going further why not removing = from arrow which indicated that
> > there is no return value for void functions:
> >
> > class X {
> > public function __construct(private int $foo, private int $bar) {}
> > public function getFoo(): int => $foo;
> > public function setFoo(int $value): void > $foo = $value;
> > public function getBar(): int => $bar;
> > public function setBar(int $value): void > $bar = $value;
> > }
> >
> > The use of > instead of => could if possible indicate the method being void
> > and reduce even more:
> >
> > class X {
> > public function __construct(private int $foo, private int $bar) {}
> > public function getFoo(): int => $foo;
> > public function setFoo(int $value) > $foo = $value;
> > public function getBar(): int => $bar;
> > public function setBar(int $value) > $bar = $value;
> > }
> >
> > Would it be possible?
> >
> > If not I think we should reanimate property accessors.
>
> Which brings us back to https://externals.io/message/64469
> <https://externals.io/message/64469> from 7 years ago. And there is
> this:
> https://www.reddit.com/r/PHP/comments/budr7q/php_74_setters_and_getters_have_died/
>
> <https://www.reddit.com/r/PHP/comments/budr7q/php_74_setters_and_getters_have_died/>
>
> With getters/setters, it would seem Larry's proposal might allow for
> more conciseness than it can with all other current syntax being the
> same as PHP 8.0 per Nikita.
>
> Consider this, as one straw man type of new syntax:
>
> class TimePeriod {
> private int $Seconds = 3600;
> public float $Hours {
> get():float => $this->Seconds / 3600;
> set(int $v) => $this->Seconds = intval($v*3600);
> }
> }
>
> Or for a different use-case with different straw man syntax that could
> possibly work in addition to above syntax, where externally $Balance is
> readonly whereas internally Balance is treated like it is private so it
> can be set (I also used Michal's ">" to indicate void, although I am
> not sure that using a greater-than in a different context is a good
> idea):
>
> class Account {
> public get int $Balance;
> public function Deposit(int $amount) > $this->Balance += $amount;
> public function Withdraw(int $amount) > $this->Balance -= $amount;
> }
Responding to several things at once here:
Honestly, getters is not my primary target with this RFC. They're more a nice
side effect, given how common they are. I am more interested in "expression
functions": functions that are just a pure input->output map. Sometimes those
are methods, but frequently they're just functions.
A shortened setter is not really what I'm after, therefore. If anything, I'd
prefer to make an expression that returns a new object with one change that can
then be returned by this syntax, making with-er methods easier. That would fit
better with value objects.
And, in fact, named parameters already gives us something very very close in
8.0:
class Point {
public function __construct(private int $x, private int $y) {}
protected function modClone(...$args): static {
$new = clone($this);
foreach ($args as $k => $v) {
$new->$k = $v;
}
return $new;
}
public function moveUp(int $amt) {
return $this->modClone(y: $this->y + $amt);
}
}
$p1 = new Point(3, 5);
$p2 = $p1->moveUp(4);
https://3v4l.org/lg4Ac
That allows for a single-expression with-er method with no additional syntax,
just one simple utility method. Which, with this RFC, could be shortened to:
class Point {
public function __construct(private int $x, private int $y) {}
protected function modClone(...$args): static {
$new = clone($this);
foreach ($args as $k => $v) {
$new->$k = $v;
}
return $new;
}
public function x(): => $this->x;
public function y(): => $this->y;
public function distFromOrigin() => sqrt($this->x ** 2 + $this->y ** 2);
public function moveUp(int $amt): static => $this->modClone(y: $this->y +
$amt);
}
Which... I actually really like, now that I look at it. I'd rather look at how
to make modClone() more trivial or even included natively than a dedicated
setter syntax. But that's for another RFC.
That's also why I don't really want to consider auto-scoping to $this. That's
unnecessary magic that would, if anything, make converting between a short and
long function harder. At this point I can type $this-> from pure muscle memory
in a fraction of a second so I'm not too bothered by it. :-)
To Nikita's point about visual confusion in a class, that's fair. However, as
noted I think it's more useful for functions anyway. Also, the problem goes
away if you cluster your code effectively, which is already a good (albeit not
universal) practice, and if you can use a with-er style method as above.
viz:
class User {
public function __construct(
private int $id,
private string $username,
private string $role,
private string $firstName,
private string $lastName,
) {}
public function getId(): int => $this->id;
public function getUserName(): string => $this->username;
public function getRole(): string => $this->role;
public function getFullName(): string => sprintf(%s %s', $this->firstName,
$this->lastName);
public function setUserName(string $name): static =>
$this->modClone(username: $name);
public function setRole(string $role): static => $this->modClone(role: $role);
public function rehashPassword(): void {
// ... Stuff here.
}
}
That looks quite readable to me, and even encourages putting all the simple
getters together, both those that are raw getters and the "pseudo-property"
ones like getFullName(). Looking at it, I quite like it both visually and for
what it encourages.
--Larry Garfield
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php