A while back, Nikita mentioned that it should now be easy to offer an abbreviated syntax for functions that are just a single expression. I decided to take a crack at it and it turns out he was right. I thus offer this RFC:
https://wiki.php.net/rfc/short-functions
Hopefully I made a decent enough case for it. It's entirely a convenience factor, but I think for many OOP cases (getter methods and factored out operations) and functional cases (where functions should generally be a single expression conceptually) it does make the code nicer, more compact, and more readable.
dons flame retardant suit
--
Larry Garfield
larry@garfieldtech.com
A while back, Nikita mentioned that it should now be easy to offer an abbreviated syntax for functions that are just a single expression. I decided to take a crack at it and it turns out he was right. I thus offer this RFC:
https://wiki.php.net/rfc/short-functions
Hopefully I made a decent enough case for it. It's entirely a convenience factor, but I think for many OOP cases (getter methods and factored out operations) and functional cases (where functions should generally be a single expression conceptually) it does make the code nicer, more compact, and more readable.
Simple and elegant. I like it.
I have two comments, but not about the feature.
One comment is about the RFC itself, and the other is about a use-case used to justify the feature that could warrant its own bespoke feature.
-
The section on "Conditional methods" is really just an argument about the benefits of encapsulating complex logic into well-named functions as you could achieve exactly the same benefit with the existing function syntax. It does not appear to me that it provides any specific justification for the feature in the RFC. Should it really be part of the RFC?
-
In the section "Decorating functions in live code" where you state "Often times, methods exist that are just delegating to some other method, either in the same object or a composed object." I think we could see great benefit from explicitly building delegation into classes much like how Go provides type embedding[1]. For PHP, extending the syntax for traits could be used to support delegation of one class to another embedded class. Can you see this as a potential feature?
-Mike
A while back, Nikita mentioned that it should now be easy to offer an abbreviated syntax for functions that are just a single expression. I decided to take a crack at it and it turns out he was right. I thus offer this RFC:
https://wiki.php.net/rfc/short-functions
Hopefully I made a decent enough case for it. It's entirely a convenience factor, but I think for many OOP cases (getter methods and factored out operations) and functional cases (where functions should generally be a single expression conceptually) it does make the code nicer, more compact, and more readable.
Simple and elegant. I like it.
I have two comments, but not about the feature.
One comment is about the RFC itself, and the other is about a use-case
used to justify the feature that could warrant its own bespoke feature.
- The section on "Conditional methods" is really just an argument
about the benefits of encapsulating complex logic into well-named
functions as you could achieve exactly the same benefit with the
existing function syntax. It does not appear to me that it provides
any specific justification for the feature in the RFC. Should it really
be part of the RFC?
In pre-RFC discussion, one of the pushbacks I got was "pfft, how common are single-line methods anyway?" That example is mainly to demonstrate "quite common, actually, in fact common refactoring patterns tend to produce them a lot." It's not the refactoring itself that benefits, per se, as it is the refactoring technique produces functions that would benefit from it.
- In the section "Decorating functions in live code" where you state
"Often times, methods exist that are just delegating to some other
method, either in the same object or a composed object." I think we
could see great benefit from explicitly building delegation into
classes much like how Go provides type embedding[1]. For PHP, extending
the syntax for traits could be used to support delegation of one class
to another embedded class. Can you see this as a potential feature?-Mike
I'd be in favor of some kind of automated "delegate this interface's methods to this object property" syntax, although that is unrelated to the RFC at hand.
--Larry Garfield
A while back, Nikita mentioned that it should now be easy to offer an abbreviated syntax for functions that are just a single expression. I decided to take a crack at it and it turns out he was right. I thus offer this RFC:
https://wiki.php.net/rfc/short-functions
Hopefully I made a decent enough case for it. It's entirely a convenience factor, but I think for many OOP cases (getter methods and factored out operations) and functional cases (where functions should generally be a single expression conceptually) it does make the code nicer, more compact, and more readable.
Simple and elegant. I like it.
I have two comments, but not about the feature.
One comment is about the RFC itself, and the other is about a use-case
used to justify the feature that could warrant its own bespoke feature.
- The section on "Conditional methods" is really just an argument
about the benefits of encapsulating complex logic into well-named
functions as you could achieve exactly the same benefit with the
existing function syntax. It does not appear to me that it provides
any specific justification for the feature in the RFC. Should it really
be part of the RFC?In pre-RFC discussion, one of the pushbacks I got was "pfft, how common are single-line methods anyway?" That example is mainly to demonstrate "quite common, actually, in fact common refactoring patterns tend to produce them a lot." It's not the refactoring itself that benefits, per se, as it is the refactoring technique produces functions that would benefit from it.
Thank you for clarifying. I understand now why you included that section.
I think the problem I had understanding the section's purpose was the construction of the first sentence where "common refactoring technique" was its subject.
May I propose you consider a different construction that focuses on the frequency with which single-expression functions are needed? Here is but one such potential alternate:
"One might ask how commonly we need single-expression functions? Consider the "if," "switch" and "while" statements. When their expressions are complex, we can add clarity by encapsulating into a single-expression function:"
Also it might be good to rename the section "Conditional methods" to something like "Use-case frequency" to focus on the reason for inclusion, or if the purpose of the heading needs to be about how it would be used in the language then maybe "Control Flow Statement Expressions" would be more appropriate?
Anyway, just offering these suggestion in hopes that ensuring your RFC is as clear as it can be will make it more likely to pass.
-Mike
- In the section "Decorating functions in live code" where you state
"Often times, methods exist that are just delegating to some other
method, either in the same object or a composed object." I think we
could see great benefit from explicitly building delegation into
classes much like how Go provides type embedding[1]. For PHP, extending
the syntax for traits could be used to support delegation of one class
to another embedded class. Can you see this as a potential feature?-Mike
I'd be in favor of some kind of automated "delegate this interface's methods to this object property" syntax, although that is unrelated to the RFC at hand.
--Larry Garfield
A while back, Nikita mentioned that it should now be easy to offer an
abbreviated syntax for functions that are just a single expression. I
decided to take a crack at it and it turns out he was right. I thus
offer this RFC:https://wiki.php.net/rfc/short-functions
Hopefully I made a decent enough case for it. It's entirely a
convenience factor, but I think for many OOP cases (getter methods and
factored out operations) and functional cases (where functions should
generally be a single expression conceptually) it does make the code
nicer, more compact, and more readable.dons flame retardant suit
There's been some discussion on the PR that I'm looping back here for completeness, mainly about using "function" vs "fn" for short named functions.
I can see good arguments for either, and in the end don't care all that much. My main concern was that function
was easier to implement, but Sara graciously offered an alternate patch that uses fn
instead. I'll make a PR out of that sometime later today. If we feel it's highly bikeshedable I'm happy to make that a secondary vote, or if a clear consensus emerges either way before then we can go with whatever that is.
I think I moderately prefer function
for visual consistency, especially inside a class, but it's not a hill I feel like being moderately injured on. :-)
--Larry Garfield
Hi Larry Garfield,
A while back, Nikita mentioned that it should now be easy to offer an
abbreviated syntax for functions that are just a single expression. I
decided to take a crack at it and it turns out he was right. I thus
offer this RFC:https://wiki.php.net/rfc/short-functions
Hopefully I made a decent enough case for it. It's entirely a
convenience factor, but I think for many OOP cases (getter methods and
factored out operations) and functional cases (where functions should
generally be a single expression conceptually) it does make the code
nicer, more compact, and more readable.dons flame retardant suit
There's been some discussion on the PR that I'm looping back here for completeness, mainly about using "function" vs "fn" for short named functions.
I can see good arguments for either, and in the end don't care all that much. My main concern was that
function
was easier to implement, but Sara graciously offered an alternate patch that usesfn
instead. I'll make a PR out of that sometime later today. If we feel it's highly bikeshedable I'm happy to make that a secondary vote, or if a clear consensus emerges either way before then we can go with whatever that is.I think I moderately prefer
function
for visual consistency, especially inside a class, but it's not a hill I feel like being moderately injured on. :-)
The feature overall looks convenient.
I'd also be against fn
for the consistency - as the RFC says, "Functions are simpler than lambdas, as there is no need for closing over variables contextually"
The major difference between fn
and function() {}
is the fact that the former automatically uses variables by value from the outer scope,
and it'd be confusing to reuse that for methods and/or global functions that don't use variables for the outer scope.
(I don't know if the RFC mentioned this explicitly)
(e.g. $multiple = 3; fn named_multiply($x) => $x * $multiple;
is what a user may expect fn
to mean)
I guess that was mentioned in the PR discussion already, but mentioning this on-list for others: https://github.com/php/php-src/pull/6221#issuecomment-713605293
- Unrelated to this RFC: If we were ever to have class methods and named global functions that did take variables from the outer scope by reference (like in Python), that may cause complications in opcache (e.g. for anonymous classes),
and I don't really have a use case for that. Butfn
would make sense for that type of feature.
-- Tyson Andre
A while back, Nikita mentioned that it should now be easy to offer an
abbreviated syntax for functions that are just a single expression. I
decided to take a crack at it and it turns out he was right. I thus
offer this RFC:
I like it. It fits nicely with my mental model of arrow functions as
being special syntax for "functionising" a single expression. It may
appeal less to people who see arrow functions as "the better way to
write closures", and are hoping to extend them with full procedural bodies.
There's been some discussion on the PR that I'm looping back here for completeness, mainly about using "function" vs "fn" for short named functions.
You could list that under Open Issues on the RFC.
It occurred to me recently that maybe we could make "function" and "fn"
synonyms everywhere, i.e. make both "$double = function($x) => $x *2;"
and "$double = fn($x) use ($x) { return $x *2; };" valid. I'm not sure
if that's desirable, or even if there's a reason it can't be done, but
it would mean you don't have to make a decision on this RFC...
Regards,
--
Rowan Tommins (né Collins)
[IMSoP]
It occurred to me recently that maybe we could make "function" and "fn"
synonyms everywhere, i.e. make both "$double = function($x) => $x *2;"
and "$double = fn($x) use ($x) { return $x *2; };" valid. I'm not sure
if that's desirable, or even if there's a reason it can't be done, but
it would mean you don't have to make a decision on this RFC...
Sara mentioned that as well. I can see the appeal, but at the same time I foresee that leading to a question about when to use which, divergent coding standards with different people doing it differently and different projects eventually adopting different standards, eventually a PSR that attempts to standardize it, probably by proposing the same "when it's a short-function of some kind" rule, and only some projects adopt it. Basically, a mess.
Whatever we do, it should be language-consistent so that there's no bikeshed potential.
--Larry Garfield
On Tue, Oct 20, 2020 at 8:20 PM Larry Garfield larry@garfieldtech.com
wrote:
A while back, Nikita mentioned that it should now be easy to offer an
abbreviated syntax for functions that are just a single expression. I
decided to take a crack at it and it turns out he was right. I thus offer
this RFC:https://wiki.php.net/rfc/short-functions
Hopefully I made a decent enough case for it. It's entirely a convenience
factor, but I think for many OOP cases (getter methods and factored out
operations) and functional cases (where functions should generally be a
single expression conceptually) it does make the code nicer, more compact,
and more readable.dons flame retardant suit
Overall, I do not like this proposal. I can see the appeal, and I can also
see a (rather weak) consistency argument for it, but ultimately I think
this will do more harm than good. It introduces a second way to write the
same thing, without providing a major saving in brevity. You might try to
argue the same about arrow functions, but I think the relative difference
is much more significant there.
If we take a class like this:
class X {
public function getFoo(): int {
return $this->foo;
}
public function setFoo(int $value): void {
$this->foo = $value;
}
public function getBar(): int {
return $this->bar;
}
public function setBar(int $value): void {
$this->bar = $value:
}
}
And convert it to the proposed syntax:
class X {
public function getFoo(): int => $this->foo;
public function setFoo(int $value): void {
$this->foo = $value;
}
public function getBar(): int => $this->bar;
public function setBar(int $value): void {
$this->bar = $value;
}
}
I don't think we've managed to save much screen real estate here, but we
did make the code harder to scan: In practice you will always end up mixing
the => and the {} notations, which makes it harder to pick out the function
bodies.
Now, we could make this more compact by writing it like this (and this
would be a significant saving):
class X {
public function getFoo(): int => $this->foo;
public function setFoo(int $value): int => $this->foo = $value;
public function getBar(): int => $this->bar;
public function setBar(int $value): int => $this->bar = $value;
}
Note that this is not the same: The setters now return the value they're
setting. You wouldn't ever do this if you used the long-hand notation, but
I can bet you that this is going to become something people routinely do
with this syntax, because it is the path of least resistance and avoids the
awkward syntax mix for getters and setters.
Now, in my first example I cheated: I used sane code formatting instead of
following PHP-FIGs recommendations (swear words omitted here). If we were
writing C++ code, which has different baseline expectations on what
acceptable formatting is, this code might have been written compactly as:
class X {
public function getFoo(): int { return $this->foo; }
public function setFoo(int $value): void { $this->foo = $value; }
public function getBar(): int { return $this->bar; }
public function setBar(int $value): void { $this->bar = $value; }
}
You'll note that this looks very similar to my last example -- with the
difference that it does not butcher the return value of the setters. Which
really goes to show that this is not a language problem, but a problem with
an unnecessarily verbose coding style guide. If you think that this kind of
concise notation is valuable, then I think the style guide should be the
first point of attack.
I think the most concerning example in the RFC is this one:
function pick_one(int $a) => match($a) {
1 => 'One',
2 => 'Two',
3 => 'Three',
default => 'More',
};
With match, the actual implementation of the function may be quite large,
even though it is only a single expression. In this case the (relative)
saving is particularly small, and the question of which form you should be
using becomes more prominent. I personally wouldn't want to see that code,
but that would require drawing a line regarding which types of expressions
are acceptable to use with this syntax and which aren't.
I also dislike the somewhat subtle requirement for a trailing semicolon
after the closing brace in this case -- it makes sense for sure, but it
looks wrong at a glance, because it's not immediately apparent that this is
not a function block, but a match block.
Regards,
Nikita
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.
Just dropping my 50 cents.
Best regards,
Michał Marcin Brzuchalski
wt., 20 paź 2020 o 20:20 Larry Garfield larry@garfieldtech.com napisał(a):
A while back, Nikita mentioned that it should now be easy to offer an
abbreviated syntax for functions that are just a single expression. I
decided to take a crack at it and it turns out he was right. I thus offer
this RFC:https://wiki.php.net/rfc/short-functions
Hopefully I made a decent enough case for it. It's entirely a convenience
factor, but I think for many OOP cases (getter methods and factored out
operations) and functional cases (where functions should generally be a
single expression conceptually) it does make the code nicer, more compact,
and more readable.dons flame retardant suit
--
Larry Garfield
larry@garfieldtech.com--
To unsubscribe, visit: https://www.php.net/unsub.php
The use of > instead of => could if possible indicate the method being
void
and reduce even more:
I think that for void, it could just identify it and not return nothing
automatically.
function a(): int => b(); // equivalents to function a(): int { return b();
}
function x(): void => y(); // equivalents to function x(): void { y(); }
Atenciosamente,
David Rodrigues
Em seg., 26 de out. de 2020 às 11:23, Michał Marcin Brzuchalski <
michal.brzuchalski@gmail.com> escreveu:
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.
Just dropping my 50 cents.
Best regards,
Michał Marcin Brzuchalskiwt., 20 paź 2020 o 20:20 Larry Garfield larry@garfieldtech.com
napisał(a):A while back, Nikita mentioned that it should now be easy to offer an
abbreviated syntax for functions that are just a single expression. I
decided to take a crack at it and it turns out he was right. I thus
offer
this RFC:https://wiki.php.net/rfc/short-functions
Hopefully I made a decent enough case for it. It's entirely a
convenience
factor, but I think for many OOP cases (getter methods and factored out
operations) and functional cases (where functions should generally be a
single expression conceptually) it does make the code nicer, more
compact,
and more readable.dons flame retardant suit
--
Larry Garfield
larry@garfieldtech.com--
To unsubscribe, visit: https://www.php.net/unsub.php
Hi David,
pon., 26 paź 2020 o 15:29 David Rodrigues david.proweb@gmail.com
napisał(a):
The use of > instead of => could if possible indicate the method being
void
and reduce even more:I think that for void, it could just identify it and not return nothing
automatically.function a(): int => b(); // equivalents to function a(): int { return
b(); }
function x(): void => y(); // equivalents to function x(): void { y(); }
Sure, but I've used > without adding return type ':void' intentionally what
could possibly indicate the void
if talking about reducing the return type at all for void methods.
Cheers,
Michał Marcin Brzuchalski
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;
}
-Mike
Just dropping my 50 cents.
Best regards,
Michał Marcin Brzuchalski
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);
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
Hey Larry,
In my vision, this proposal is a good addition to PHP exactly as stated in
this pull request (https://github.com/php/php-src/pull/6221): where only
the "=> expr;" is introduced, and not the "fn".
For visual consistency in the future of PHP functions/methods, I think it's
important to differ "=> expr;" from "fn":
- "=> expr;" means "arrow": syntax that defines functions/methods with
one-line return expressions. - "fn" means "short": syntax that makes functions inherit scope. It's
already in use by arrow short closures (
https://wiki.php.net/rfc/arrow_functions_v2 ).
Therefore, from my understanding, your proposal would allow all the
following things to be possible:
// arrow function
function foo() => /** */;
// arrow closure
$foo = function () => /** */;
// fn/short arrow closure ( already introduced in PHP 7.4 )
$foo = fn() => /** */;
class Foo {
// arrow method
poublic function bar() => /** */;
}
If this proposal keeps using the "function", and not the "fn", I don't see
any conflict with my Proposal (multi-line short closures -
https://github.com/php/php-src/pull/6246).
Good luck with the RFC.
- Nuno
Hey Larry,
In my vision, this proposal is a good addition to PHP exactly as stated in
this pull request (https://github.com/php/php-src/pull/6221): where only
the "=> expr;" is introduced, and not the "fn".For visual consistency in the future of PHP functions/methods, I think it's
important to differ "=> expr;" from "fn":
- "=> expr;" means "arrow": syntax that defines functions/methods with
one-line return expressions.- "fn" means "short": syntax that makes functions inherit scope. It's
already in use by arrow short closures (
https://wiki.php.net/rfc/arrow_functions_v2 ).Therefore, from my understanding, your proposal would allow all the
following things to be possible:// arrow function function foo() => /** */; // arrow closure $foo = function () => /** */; // fn/short arrow closure ( already introduced in PHP 7.4 ) $foo = fn() => /** */; class Foo { // arrow method poublic function bar() => /** */; }
If this proposal keeps using the "function", and not the "fn", I don't see
any conflict with my Proposal (multi-line short closures -
https://github.com/php/php-src/pull/6246).Good luck with the RFC.
- Nuno
Yes, that's how it would fall out, assuming multi-line-arrows happen. I'm honestly still torn on that myself for various reasons, but "=> means expression, fn means auto-capture, use one or both as appropriate" seems like a reasonable syntax guideline that we can teach people.
--Larry Garfield