Hi Rowan,
On 26-02-2024 23:46, Rowan Tommins [IMSoP] wrote:
On 26/02/2024 20:21, Frederik Bosch wrote:
I do note that $this->propName might suggest that the backing value
is accessible from other locations than only the property's own
get/set methods, because of $this usage.
Yes, I actually stumbled over that confusion when I was writing some
of the examples in my lengthy e-mail in this thread. As I understand
it, this would work:
public string $foo {
get { $this->foo ??= 0; $this->foo++; return $this->foo; }
set { throw new Exception; }
}
Outside the hooks, trying to write to $this->foo would throw the
exception, because it refers to the hooked property as a whole; but
inside, the same name refers to something different, which isn't
accessible anywhere else.
Now that I've looked more at how Kotlin uses "field", I understand why
it makes sense - it's not an alias for the property itself, but the
way to access a "backing store" which has no other name.
Using $this->foo as the name is tempting if you think of hooks as
happening "on top of" the "real" property; but that would be a
different feature, like Switft's "property observers" (willSet and
didSet). What's really happening is that we're declaring two things at
once, and giving them the same name; almost as if we'd written this:
public string $foo {
get { static $_foo; $_foo ??= 0; $_foo++; return $_foo; }
set { throw new Exception; }
}
Kotlin's "field" is kind of the equivalent of that "static $_foo"
And what happens in the following situation, how are multiple get calls
working together?
public string $fullName {
get => $this->first . ' ' . $this->last; // is this accessing the
backed value, or is it accessing via get
set($value) => $this->fullName = $value;
}
public string $first {
get => explode(' ', $this->fullName)[0], // is this accessing the
backed value, or is it accessing via get
set($value) => $value;
}
Isn't it weird that $this->propName gives different results from one get
function, compared to the other. I would say $this->prop should always
follow the same semantics as explained in the RFC (first __get/__set,
then the accessor).
Regarding returning void=null, this is something that IDE and static
analyzers already pick-up as an error. I think being stricter on that
in this RFC would actually make sense, and treat void not as null.
What would happen if a setter contained both "return 42;" and
"return;"? The latter is explicitly allowed in "void" functions, but
is also allowed in a non-void function as meaning "return null;"
return 42; // returns (int)42
return; // early return, void, same as no return
return null; // returns null
And why yield is magic, I do not get that. The word and the
expression actually expresses that something is, well, yielded.
But yielded to where? My mental model of "return to set" is that this:
public string $name { set($value) { $x = something($value); return $x
+ 1; } }
Is effectively:
private function _name_set($value) { $x = something($value); return $x
+ 1; } }
plus:
$this->name = $this->_name_set($value);
With "yield", I can't picture that simple translation; the "magic" is
whatever translates the "yield" keyword into "$this->name ="
You would picture it by explaining how it works from the source side. A
set function that contains a yield turns the set function into a
directly consumed generator. Considering the following:
public string $first {
set($value) => {
yield 'First name';
yield 'Given name';
return 'My name';
}
}
the pseudo-code from the PHP source side would look as follows.
$generator = setCall($class, 'first', $value);
foreach ($generator as $value) {
writeProperty($class, 'first', $value);
}
if ($generator->hasReturn()) {
writeProperty($class, 'first', $generator->getReturn());
}
I would file it with the type widening in the RFC: seems kind of cool,
but probably isn't worth the added complexity.
Regards,
--
Frederik Bosch
Partner
Genkgo logo
Mail: f.bo...@genkgo.nl <mailto:f.bo...@genkgo.nl>
Web: support.genkgo.com <https://support.genkgo.com>
Entrada 123
Amsterdam
+31 20 244 1920
Genkgo B.V. staat geregistreerd bij de Kamer van Koophandel onder nummer
56501153