Morning Internals,
Please review the following RFC:
https://wiki.php.net/rfc/lexical-anon
A look at the patch from those of you that do that would be good :)
Cheers
Joe
> Morning Internals,
>
> Please review the following RFC:
>
> https://wiki.php.net/rfc/lexical-anon
>
> A look at the patch from those of you that do that would be good :)
>
Hey Joe,
The syntax and semantics proposed in this RFC don't sit quite well with me.
Especially the fact that a use($foo) on the class is then used as
$this->foo in methods is non-intuitive to me, as it differs from how the
same syntax behaves on closures. I'd like to suggest an alternative syntax:
$foo = 42;
return new class {
private $bar = $foo;
public function getBar() { return $this->bar; }
}
That is, allow properties inside the anonymous class to be initialized
based on values from the surrounding scope. This is more explicit (clearly
shows that a property is being created), it allows explicit control over
the visibility and, depending on implementation, might be more flexible
with regards to the values it accepts. It probably doesn't make sense to
restrict this to specific expressions, so all of
return new class {
private $a = $var;
private $b = $obj->prop;
private $d = $obj->prop ?? 'default';
// ...
}
could be fine.
Thanks,
Nikita
Morning Internals,
Please review the following RFC: https://wiki.php.net/rfc/lexical-anon A look at the patch from those of you that do that would be good :)
Hey Joe,
The syntax and semantics proposed in this RFC don't sit quite well with me.
Especially the fact that a use($foo) on the class is then used as
$this->foo in methods is non-intuitive to me, as it differs from how the
same syntax behaves on closures. I'd like to suggest an alternative syntax:$foo = 42;
return new class {
private $bar = $foo;
public function getBar() { return $this->bar; }
}That is, allow properties inside the anonymous class to be initialized
based on values from the surrounding scope. This is more explicit (clearly
shows that a property is being created), it allows explicit control over
the visibility and, depending on implementation, might be more flexible
with regards to the values it accepts. It probably doesn't make sense to
restrict this to specific expressions, so all ofreturn new class {
private $a = $var;
private $b = $obj->prop;
private $d = $obj->prop ?? 'default';
// ...
}could be fine.
I could not express better than you, so big +1 for your proposal so far.
Morning Internals,
Please review the following RFC: https://wiki.php.net/rfc/lexical-anon A look at the patch from those of you that do that would be good :)
Hey Joe,
The syntax and semantics proposed in this RFC don't sit quite well with me.
Especially the fact that a use($foo) on the class is then used as
$this->foo in methods is non-intuitive to me, as it differs from how the
same syntax behaves on closures. I'd like to suggest an alternative syntax:$foo = 42;
return new class {
private $bar = $foo;
public function getBar() { return $this->bar; }
}
This syntax is definitely better, less magic and more powerful.
That is, allow properties inside the anonymous class to be initialized
based on values from the surrounding scope. This is more explicit (clearly
shows that a property is being created), it allows explicit control over
the visibility and, depending on implementation, might be more flexible
with regards to the values it accepts. It probably doesn't make sense to
restrict this to specific expressions, so all ofreturn new class {
private $a = $var;
private $b = $obj->prop;
private $d = $obj->prop ?? 'default';
// ...
}could be fine.
Is this for anonymous classes only?
Only for property default values or something else?
Also, instead of lexical scoping, we may use generic approach.
return new class<A=&$var,B=$obj->prop,C=$obj->prop ?? 'default'> {
private $a = A;
private $b = B;
private $d = C;
};
But good design of generics would take a lot of ...
Thanks. Dmitry.
Thanks,
Nikita
Nikita Popov wrote on 19/04/2016 15:18:
I'd like to suggest an alternative syntax:
$foo = 42;
return new class {
private $bar = $foo;
public function getBar() { return $this->bar; }
}That is, allow properties inside the anonymous class to be initialized
based on values from the surrounding scope.
The problem with this is that it violates PHP's normal scoping rules,
because the variable is crossing scopes "uninvited". It makes it more
explicit where the variable is going to, but hides where it is coming
from.
Perhaps a Trait-like syntax might work?
$foo = 42;
return new class {
use $foo as private $bar;
public function getBar() { return $this->bar; }
}
This makes it clear both that $foo is being imported from somewhere, and
that it is being saved to a particular private member.
Regards,
Rowan Collins
[IMSoP]
Hi Nikita,
I was thinking some more about your suggestion:
Nikita Popov wrote on 19/04/2016 15:18:
$foo = 42;
return new class {
private $bar = $foo;
public function getBar() { return $this->bar; }
}
If we allowed this, would it make sense to also allow it in named
classes? This is currently illegal [https://3v4l.org/Kp0ep]:
$foo = 42;
class X {
private $bar = $foo;
public function getBar() { return $this->bar; }
}
It probably doesn't make sense to
restrict this to specific expressions, so all ofreturn new class {
private $a = $var;
private $b = $obj->prop;
private $d = $obj->prop ?? 'default';
// ...
}could be fine.
We don't allow importing expressions into closures, nor are any of those
property initialisations valid in the definitions of named classes, so I
think allowing them here would be odd.
Regards,
Rowan Collins
[IMSoP]
JavaScript/ES6:
function foo(bar) {
return new class {
myBar = bar;
getBar() {
return this.myBar;
}
}();
}
console.log(foo('hello').getBar()); // "hello"
(You can actually reference outer symbols anywhere in the definition of a
JS class, so I could have used "bar" directly in "getBar" without going
through a property.)
> On Tue, Apr 19, 2016 at 3:31 PM, Joe Watkins
> wrote:
>
> > Morning Internals,
> >
> > Please review the following RFC:
> >
> > https://wiki.php.net/rfc/lexical-anon
> >
> > A look at the patch from those of you that do that would be good :)
> >
>
> Hey Joe,
>
> The syntax and semantics proposed in this RFC don't sit quite well with me.
> Especially the fact that a use($foo) on the class is then used as
> $this->foo in methods is non-intuitive to me, as it differs from how the
> same syntax behaves on closures. I'd like to suggest an alternative syntax:
>
> $foo = 42;
> return new class {
> private $bar = $foo;
> public function getBar() { return $this->bar; }
> }
>
> That is, allow properties inside the anonymous class to be initialized
> based on values from the surrounding scope. This is more explicit (clearly
> shows that a property is being created), it allows explicit control over
> the visibility and, depending on implementation, might be more flexible
> with regards to the values it accepts. It probably doesn't make sense to
> restrict this to specific expressions, so all of
>
> return new class {
> private $a = $var;
> private $b = $obj->prop;
> private $d = $obj->prop ?? 'default';
> // ...
> }
>
> could be fine.
>
> Thanks,
> Nikita
That implementation is totally and utterly wrong, it's so obvious this
morning ... I'm almost embarrassed.
I must say that of all the suggestions made so far for syntax, I still
prefer use().
While the idea to allow symbols and expressions is very cool, it will
create so much confusion that an anonymous class can do things like set
objects as member properties but other classes can't.
The syntax also looks absolutely terrible when it comes to refs:
class {
public $thing = &$this->thing;
}
This is almost literally *backwards*.
All of the solutions suggested so far also create rather a lot of
repetition for anything that isn't example code.
Anyway, the implementation is broken, let's come back to this discussion
later on, please.
Cheers
Joe
On Wed, Apr 20, 2016 at 4:54 AM, Jesse Schalken
wrote:
> I'm not sure it matters, but there is some precedent for this in
> JavaScript/ES6:
>
> function foo(bar) {
> return new class {
> myBar = bar;
>
> getBar() {
> return this.myBar;
> }
> }();
> }
>
> console.log(foo('hello').getBar()); // "hello"
>
>
> (You can actually reference outer symbols anywhere in the definition of a
> JS class, so I could have used "bar" directly in "getBar" without going
> through a property.)
>
>
> On Wed, Apr 20, 2016 at 12:18 AM, Nikita Popov
> wrote:
>
>> On Tue, Apr 19, 2016 at 3:31 PM, Joe Watkins
>> wrote:
>>
>> > Morning Internals,
>> >
>> > Please review the following RFC:
>> >
>> > https://wiki.php.net/rfc/lexical-anon
>> >
>> > A look at the patch from those of you that do that would be good :)
>> >
>>
>> Hey Joe,
>>
>> The syntax and semantics proposed in this RFC don't sit quite well with
>> me.
>> Especially the fact that a use($foo) on the class is then used as
>> $this->foo in methods is non-intuitive to me, as it differs from how the
>> same syntax behaves on closures. I'd like to suggest an alternative
>> syntax:
>>
>> $foo = 42;
>> return new class {
>> private $bar = $foo;
>> public function getBar() { return $this->bar; }
>> }
>>
>> That is, allow properties inside the anonymous class to be initialized
>> based on values from the surrounding scope. This is more explicit (clearly
>> shows that a property is being created), it allows explicit control over
>> the visibility and, depending on implementation, might be more flexible
>> with regards to the values it accepts. It probably doesn't make sense to
>> restrict this to specific expressions, so all of
>>
>> return new class {
>> private $a = $var;
>> private $b = $obj->prop;
>> private $d = $obj->prop ?? 'default';
>> // ...
>> }
>>
>> could be fine.
>>
>> Thanks,
>> Nikita
Cheers
Joe
> Can we just halt this conversation for a few days.
>
> That implementation is totally and utterly wrong, it's so obvious this
> morning ... I'm almost embarrassed.
>
> I must say that of all the suggestions made so far for syntax, I still
> prefer use().
>
> While the idea to allow symbols and expressions is very cool, it will
> create so much confusion that an anonymous class can do things like set
> objects as member properties but other classes can't.
>
> The syntax also looks absolutely terrible when it comes to refs:
>
> class {
> public $thing = &$this->thing;
> }
>
> This is almost literally *backwards*.
>
> All of the solutions suggested so far also create rather a lot of
> repetition for anything that isn't example code.
>
> Anyway, the implementation is broken, let's come back to this discussion
> later on, please.
>
> Cheers
> Joe
>
> On Wed, Apr 20, 2016 at 4:54 AM, Jesse Schalken
> wrote:
>
>> I'm not sure it matters, but there is some precedent for this in
>> JavaScript/ES6:
>>
>> function foo(bar) {
>> return new class {
>> myBar = bar;
>>
>> getBar() {
>> return this.myBar;
>> }
>> }();
>> }
>>
>> console.log(foo('hello').getBar()); // "hello"
>>
>>
>> (You can actually reference outer symbols anywhere in the definition of a
>> JS class, so I could have used "bar" directly in "getBar" without going
>> through a property.)
>>
>>
>> On Wed, Apr 20, 2016 at 12:18 AM, Nikita Popov
>> wrote:
>>
>>> On Tue, Apr 19, 2016 at 3:31 PM, Joe Watkins
>>> wrote:
>>>
>>> > Morning Internals,
>>> >
>>> > Please review the following RFC:
>>> >
>>> > https://wiki.php.net/rfc/lexical-anon
>>> >
>>> > A look at the patch from those of you that do that would be good :)
>>> >
>>>
>>> Hey Joe,
>>>
>>> The syntax and semantics proposed in this RFC don't sit quite well with
>>> me.
>>> Especially the fact that a use($foo) on the class is then used as
>>> $this->foo in methods is non-intuitive to me, as it differs from how the
>>> same syntax behaves on closures. I'd like to suggest an alternative
>>> syntax:
>>>
>>> $foo = 42;
>>> return new class {
>>> private $bar = $foo;
>>> public function getBar() { return $this->bar; }
>>> }
>>>
>>> That is, allow properties inside the anonymous class to be initialized
>>> based on values from the surrounding scope. This is more explicit
>>> (clearly
>>> shows that a property is being created), it allows explicit control over
>>> the visibility and, depending on implementation, might be more flexible
>>> with regards to the values it accepts. It probably doesn't make sense to
>>> restrict this to specific expressions, so all of
>>>
>>> return new class {
>>> private $a = $var;
>>> private $b = $obj->prop;
>>> private $d = $obj->prop ?? 'default';
>>> // ...
>>> }
>>>
>>> could be fine.
>>>
>>> Thanks,
>>> Nikita
Hi everyone,
having worked a bit with anonymous classes these days, the current
boilerplate is really high to inject some local context into them.
So big +1 from me for the target.
On the proposed syntax, I really prefer Nikita's proposal:
return new class {
private $a = $var; private $b = $obj->prop; private $d = $obj->prop ?? 'default'; // ...
}
The "functional equivalent" wording in the RFC has a big drawback: it looks
like the parent constructor is overridden, which would be a really nasty
side effect. It may not be the case in the implementation, but the the RFC
needs to be clarified IMHO.
If we were to need more closure-like syntax, we may even use "use" like
this:
return new class use ($var, $obj) {
private $a = $var;
private $b = $obj->prop;
private $d = $obj->prop ?? 'default';
// ...
}
I really hope this new syntax (which ever raises the consensus) can be
ready soon :)
Nicolas