Re: [PHP-DEV] RFC: Stop to automatically cast numeric-string to int when using them as array-key

2022-01-05 Thread James Titcumb
On Wed, 29 Dec 2021, 15:42 Vincent Langlet, 
wrote:

>
> I recently discovered that an array was automatically casting
> numeric-string keys to int if it was possible.
>

Having had to track down bugs numerous times over the years, I completely
agree this is unexpected behaviour, and would be in favour of it being
amended. It is quite a BC break indeed, and both Orklah (Psalm) and Ondrej
Mirtes (PHP Stan) agree that the issue is that it's a difficult issue to
identify with static analysis (see
https://twitter.com/OndrejMirtes/status/1478971968636567552 for some
thoughts).

As always with type juggling related discussions in PHP, I expect any RFC
to be contentious and heavily discussed ;)

I expect the main detractors would be the BC breaks, and people might not
think the BC break is worth the pain.

Just thinking out loud, being able to identify an array type might be a way
forward here (using "syntax" already in use by static analysis tools in
docblocks, for familiarity), e.g.

private array $property;

This might "turn off" the automatic type juggling behaviour, for example.
If the existing strict_types=1 mode is on, this might fail:

$this->property[3] = "hi";

If strict_types=0 or not declared, the key would be cast to a string.

That said, I know there has been contentious discussion on this and the
related topic of generics multiple times, so don't really want to stir up a
hornet's nest there.

Great idea, and I'd love to see this fixed, given the countless hours I've
wasted trying to track down bugs that are a result of this. But I fear that
this would be a difficult one to push through the RFC process, sadly. I
hope I'm proven wrong though!

Thanks
James

>


Re: [PHP-DEV] RFC: Trait expects interface

2022-01-05 Thread David Gebler
On Wed, Jan 5, 2022 at 11:05 PM Larry Garfield 
wrote:

> On Wed, Jan 5, 2022, at 2:35 PM, Chase Peeler wrote:
>
> For point 2, that's mainly useful as a way to signal to other developers
> "hey, this trait has all but one method of the LoggerInterface, that's how
> you'd use it", and to signal static analyzers and refactoring tools the
> same thing so that they can be auto-updated if you tweak the interface.  I
> can see a use for point 2, and it would make my life a bit easier, but it's
> overall not high priority.
>
>
I think existing constructs provide 99% of this benefit anyway.

interface I { public function hello(); }
abstract class A implements I { abstract public function hello(); }
trait T { public function hello() { echo 'hello'; } }
class C extends A { use T; }
// or alternatively
class D implements I { use T; }
// or
abstract class E implements I { use T; }
class F extends E { ... }

$c = new C;
$c->hello(); // $c is instanceof I
$d = new D;
$d->hello(); // $d is instanceof I
$f = new F;
$f->hello(); // $f is instanceof I

It's not quite as neat as directly having a way of annotating T to say it
implements I, but it does the job insofar as your IDE and tools should be
able to immediately pick up a change in interface I is not fulfilled by
anything relying on trait T to be of type I, either directly or by
inheritance.

The remaining 1% of benefit could probably be achieved just by naming
convention:

interface LoggerInterface { ... }
trait LoggerInterface_FileLogger { ... }

But I still think both goals would be better achieved with something like:

interface LoggerInterface {
default public function error(string $message) {
$this->logger->log('error', $message);
}
}

in the manner of Java...no idea how easy or not it would be for someone a
little more experienced than me working on PHP core to do this though.

- David


> --Larry Garfield
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>


Re: [PHP-DEV] RFC: Trait expects interface

2022-01-05 Thread Larry Garfield
On Wed, Jan 5, 2022, at 2:35 PM, Chase Peeler wrote:

> First, I'm someone that mainly uses traits to implement the functionality
> defined in an interface. I think that's one of the best uses for them.
> However, I'm personally not a huge fan of overly restrictive things. For
> instance, while there are definitely some use cases for them, I need a
> REALLY good reason to justify making a property/method private instead of
> protected, or making a class final.

I am much the same.

> As such, I think this would be better if it didn't throw a fatal error.
> When you make it optional, however, I think you are left with something
> that can be handled with an attribute just as well as a new keyword:
> #[Expects('MyInterface')]
> trait foo { }
>
> However, there might be value in generating a notice/warning, and I think
> that would require a keyword, correct? (Not that up to speed on
> annotations). Another option might be two support two new keywords:
> requires and expects. The former would throw an error if the interface
> isn't implemented while the latter will throw a warning/notice/nothing.
>
> Another option (and I haven't thought about this one enough to decide if I
> like it) would be to have the expected interface automatically implemented
> in the using class. This would allow the trait to be written under the
> assumption it has access to the methods defined in the interface, and will
> then throw an error if any of the methods are not implemented in the using
> class:
>
> interface foo {
>   function a();
>   function b();
> }
>
> trait bar expects foo {
>function c(){
>return $this->a() + $this->b();
>}
> }
>
> class baz {
>   use foo;
> }
>
> The above would throw an error since a() and b() are never implemented and
> baz is implementing the foo interface. You can currently get the same
> behavior if you define a() and b() as abstract in the trait. However, this
> doesn't give you the added benefit of utilizing the interface automatically
> within the type system. The more I think about it, the less I like this
> idea, since it doesn't require that much additional work to make the code
> clearer by explicitly implementing the interface on the class if you want
> it implemented. However, I'll go ahead and leave it here because it might
> help generate some other ideas.

I... still don't see any use in this annotation.  

Stepping back and ignoring the syntax for a moment, there's two different 
things here:

1. "This trait expects to be used in a class that has these other methods on 
it".
2. "This trait mostly/fully fulfills interface X, because it has methods a, b, 
and c."

For point 1, we already have that.  It's called abstract methods in traits.  
This is a solved problem that requires no further resolution.  At best it would 
be a shorthand to copying a few methods from an interface into the trait and 
sticking "abstract" in front of them.  I really don't see a need for that.

For point 2, that's mainly useful as a way to signal to other developers "hey, 
this trait has all but one method of the LoggerInterface, that's how you'd use 
it", and to signal static analyzers and refactoring tools the same thing so 
that they can be auto-updated if you tweak the interface.  I can see a use for 
point 2, and it would make my life a bit easier, but it's overall not high 
priority.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [VOTE] User Defined Operator Overloads

2022-01-05 Thread Chase Peeler
On Wed, Jan 5, 2022 at 3:24 PM Andreas Hennings  wrote:

> On Wed, 5 Jan 2022 at 20:11, Jordan LeDoux 
> wrote:
> >
> >
> >
> > On Wed, Jan 5, 2022 at 6:33 AM Andreas Hennings 
> wrote:
> >>
> >> Hello Jordan,
> >> do you have any thoughts about these symmetric/left/right modifiers,
> >> to get rid of the $operandPos parameter?
> >>
> >> To me, the parameter could be the kind of thing where in hindsight we
> >> ask "why?".
> >>
> >> Also, can we drop the "public" modifier, if we do a new version of the
> RFC?
> >>
> >> Cheers
> >> Andreas
> >
> >
> > It's a totally different design concept (symmetric/left/right) and I've
> been going over the design implications before I responded. For instance,
> wouldn't this be a special case of method overloading? You're overloading
> according to a modifier, not the typing, but there is that to contend with.
> If someone defined `symmetric operator +` and `left operator +` which would
> be used? (My feeling is left as its more specific.)
>
> You would not be allowed to provide both on the same class.
>
> A class can provide either no operator, or the left operator, or the
> right operator, or both.
> A "symmetric" operator is a shortcut to providing both left and right,
> but using the same implementation.
> A class with a "symmetric" operator cannot also have a "left" or
> "right" version of the same operator - this would be the same as two
> methods with the same name.
> However, if the parent class has a "symmetric" operator, you _can_
> override the "left" and/or "right" version in the subclass. In that
> case, if the subclass provides "left", then the parent "symmetric"
> implementation would only be used for the "right" direction.
>
> I am writing "right" and "left" here, but perhaps "normal" and
> "inverted" would be less ambiguous.
> Also, perhaps instead of "symmetric" we could write "left right".
>
> Perhaps this code will clarify:
>
> class C {
>   symmetric operator * (int $other) {..}
>   # left operator * (int $other) {..} // -> Error, already defined.
>   left operator - (int $other) {..}
>   right operator - (int $other) {..}
>   left operator / (float $other) {..}
>   left operator % (D $other) {..}
> }
>
> class D {
>   right operator % (C $other) {..}
> }
>
> (new C()) * 5; // -> symmetric operator *
> 5 * (new C());  // -> symmetric operator *
> (new C()) - 5;  // -> left operator -
> 5 - (new C());  // -> right operator -
> (new C()) / 5;  // -> left operator /
> 5 / (new C());  // -> Error, no operator provided.
>
> (new C()) % (new D());  // -> left operator % provided by C.
> (new D()) % (new C());  // -> Error, not supported.
>
> This means, the "right operator" will only ever be called if the left
> side does not provide a "left operator".
>
> Basically this is not so different from your RFC.
> Just instead of having to do a "if ($operandPos ===
> OperandPosition::LeftSide) {..}" inside an implementation, we are
> providing two separate implementations.
>
>
> > How would they be stored within the zend_class_entry? Since they would
> technically have the same name, something would need to happen for them to
> not be in the function table.
>
> The right and left version would need to be distinguished somehow
> internally.
> I would say "left" is the default, and "right" has a modifier to its name.
> Perhaps for symmetric operators, we could store two distinct entries
> internally, if that makes things easier.
>
>
If nothing else symmetric could be handled by having the compiler replace
it with left/right version that executes the same code


> >
> > The public modifier is not required (as stated in the RFC), you can just
> add it if you want. Are you asking for `public operator` to produce a
> compile error?
>
> That would be the idea.
> Perhaps others will disagree.
> Allowing the "public" introduces a meaningless choice that people can
> argue about in their code style, and have pointless git commits where
> they add or remove the modifier based on preference.
> Of course the same could be said about "public" in interface methods.
>
>
I personally don't like it when I don't have a consistent look to my code.
One of the things that bother me is code like:
function foo(){}
protected function bar(){}
function baz(){}

I want everything to have a visibility indicator for visual consistency.
That's why I always use public in my interface methods as well. So, even
though it won't cause confusion if omitted for an operator, since it can
only be public, I still think it should be allowed.


> -- Andreas
>
> >
> > Jordan
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>

-- 
Chase Peeler
chasepee...@gmail.com


Re: [PHP-DEV] RFC: Trait expects interface

2022-01-05 Thread Chase Peeler
On Wed, Jan 5, 2022 at 2:17 PM David Gebler  wrote:

> On Tue, Jan 4, 2022 at 10:35 PM Kirill Nesmeyanov  wrote:
>
> > How relevant do you think this idea/proposal is? And what possible
> > problems or solutions will this entail in the future?
> >
>
> I'm not convinced there's a reasonable need for it. The very nature of
> finding yourself in a situation where you want any class using a trait to
> also require other things outside the trait kind of suggests you really
> want to be using interfaces or abstract classes anyway.
>
> There is a similar concept for what I think you're trying to achieve in
> Java, though, which could also be useful in PHP if it was feasible within
> the engine - the ability to provide a default method implementation on
> interfaces themselves.
>
> Short of that, we can already effectively get there with the tools we have;
> an abstract class can use a trait and define abstract or concrete methods,
> and in doing so can implement one or more interfaces. Obviously traits can
> also declare abstract methods but I assume it's the identity/type aspect of
> an interface you want here which isn't satisfied by that approach.
>
> Also worth noting, although I can't say I'm familiar with the mechanics of
> traits in PHP's implementation, my understanding has always been that
> they're effectively compiler-level copy and paste in to a class so I'm not
> sure what interfaces are implemented by the class (or conversely allowing a
> trait to implement an interface) would be readily achievable.
>
> That's my two cents, good luck with whatever you're trying to do anyway.
>
> - David
>
>
> > --
> > Kirill Nesmeyanov
>

First, I'm someone that mainly uses traits to implement the functionality
defined in an interface. I think that's one of the best uses for them.
However, I'm personally not a huge fan of overly restrictive things. For
instance, while there are definitely some use cases for them, I need a
REALLY good reason to justify making a property/method private instead of
protected, or making a class final.

As such, I think this would be better if it didn't throw a fatal error.
When you make it optional, however, I think you are left with something
that can be handled with an attribute just as well as a new keyword:
#[Expects('MyInterface')]
trait foo { }

However, there might be value in generating a notice/warning, and I think
that would require a keyword, correct? (Not that up to speed on
annotations). Another option might be two support two new keywords:
requires and expects. The former would throw an error if the interface
isn't implemented while the latter will throw a warning/notice/nothing.

Another option (and I haven't thought about this one enough to decide if I
like it) would be to have the expected interface automatically implemented
in the using class. This would allow the trait to be written under the
assumption it has access to the methods defined in the interface, and will
then throw an error if any of the methods are not implemented in the using
class:

interface foo {
  function a();
  function b();
}

trait bar expects foo {
   function c(){
   return $this->a() + $this->b();
   }
}

class baz {
  use foo;
}

The above would throw an error since a() and b() are never implemented and
baz is implementing the foo interface. You can currently get the same
behavior if you define a() and b() as abstract in the trait. However, this
doesn't give you the added benefit of utilizing the interface automatically
within the type system. The more I think about it, the less I like this
idea, since it doesn't require that much additional work to make the code
clearer by explicitly implementing the interface on the class if you want
it implemented. However, I'll go ahead and leave it here because it might
help generate some other ideas.

-- 
Chase Peeler
chasepee...@gmail.com


Re: [PHP-DEV] [VOTE] User Defined Operator Overloads

2022-01-05 Thread Andreas Hennings
On Wed, 5 Jan 2022 at 20:11, Jordan LeDoux  wrote:
>
>
>
> On Wed, Jan 5, 2022 at 6:33 AM Andreas Hennings  wrote:
>>
>> Hello Jordan,
>> do you have any thoughts about these symmetric/left/right modifiers,
>> to get rid of the $operandPos parameter?
>>
>> To me, the parameter could be the kind of thing where in hindsight we
>> ask "why?".
>>
>> Also, can we drop the "public" modifier, if we do a new version of the RFC?
>>
>> Cheers
>> Andreas
>
>
> It's a totally different design concept (symmetric/left/right) and I've been 
> going over the design implications before I responded. For instance, wouldn't 
> this be a special case of method overloading? You're overloading according to 
> a modifier, not the typing, but there is that to contend with. If someone 
> defined `symmetric operator +` and `left operator +` which would be used? (My 
> feeling is left as its more specific.)

You would not be allowed to provide both on the same class.

A class can provide either no operator, or the left operator, or the
right operator, or both.
A "symmetric" operator is a shortcut to providing both left and right,
but using the same implementation.
A class with a "symmetric" operator cannot also have a "left" or
"right" version of the same operator - this would be the same as two
methods with the same name.
However, if the parent class has a "symmetric" operator, you _can_
override the "left" and/or "right" version in the subclass. In that
case, if the subclass provides "left", then the parent "symmetric"
implementation would only be used for the "right" direction.

I am writing "right" and "left" here, but perhaps "normal" and
"inverted" would be less ambiguous.
Also, perhaps instead of "symmetric" we could write "left right".

Perhaps this code will clarify:

class C {
  symmetric operator * (int $other) {..}
  # left operator * (int $other) {..} // -> Error, already defined.
  left operator - (int $other) {..}
  right operator - (int $other) {..}
  left operator / (float $other) {..}
  left operator % (D $other) {..}
}

class D {
  right operator % (C $other) {..}
}

(new C()) * 5; // -> symmetric operator *
5 * (new C());  // -> symmetric operator *
(new C()) - 5;  // -> left operator -
5 - (new C());  // -> right operator -
(new C()) / 5;  // -> left operator /
5 / (new C());  // -> Error, no operator provided.

(new C()) % (new D());  // -> left operator % provided by C.
(new D()) % (new C());  // -> Error, not supported.

This means, the "right operator" will only ever be called if the left
side does not provide a "left operator".

Basically this is not so different from your RFC.
Just instead of having to do a "if ($operandPos ===
OperandPosition::LeftSide) {..}" inside an implementation, we are
providing two separate implementations.


> How would they be stored within the zend_class_entry? Since they would 
> technically have the same name, something would need to happen for them to 
> not be in the function table.

The right and left version would need to be distinguished somehow internally.
I would say "left" is the default, and "right" has a modifier to its name.
Perhaps for symmetric operators, we could store two distinct entries
internally, if that makes things easier.

>
> The public modifier is not required (as stated in the RFC), you can just add 
> it if you want. Are you asking for `public operator` to produce a compile 
> error?

That would be the idea.
Perhaps others will disagree.
Allowing the "public" introduces a meaningless choice that people can
argue about in their code style, and have pointless git commits where
they add or remove the modifier based on preference.
Of course the same could be said about "public" in interface methods.

-- Andreas

>
> Jordan

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] RFC: Trait expects interface

2022-01-05 Thread David Gebler
On Tue, Jan 4, 2022 at 10:35 PM Kirill Nesmeyanov  wrote:

> How relevant do you think this idea/proposal is? And what possible
> problems or solutions will this entail in the future?
>

I'm not convinced there's a reasonable need for it. The very nature of
finding yourself in a situation where you want any class using a trait to
also require other things outside the trait kind of suggests you really
want to be using interfaces or abstract classes anyway.

There is a similar concept for what I think you're trying to achieve in
Java, though, which could also be useful in PHP if it was feasible within
the engine - the ability to provide a default method implementation on
interfaces themselves.

Short of that, we can already effectively get there with the tools we have;
an abstract class can use a trait and define abstract or concrete methods,
and in doing so can implement one or more interfaces. Obviously traits can
also declare abstract methods but I assume it's the identity/type aspect of
an interface you want here which isn't satisfied by that approach.

Also worth noting, although I can't say I'm familiar with the mechanics of
traits in PHP's implementation, my understanding has always been that
they're effectively compiler-level copy and paste in to a class so I'm not
sure what interfaces are implemented by the class (or conversely allowing a
trait to implement an interface) would be readily achievable.

That's my two cents, good luck with whatever you're trying to do anyway.

- David


> --
> Kirill Nesmeyanov


Re: [PHP-DEV] [VOTE] User Defined Operator Overloads

2022-01-05 Thread Jordan LeDoux
On Wed, Jan 5, 2022 at 6:33 AM Andreas Hennings  wrote:

> Hello Jordan,
> do you have any thoughts about these symmetric/left/right modifiers,
> to get rid of the $operandPos parameter?
>
> To me, the parameter could be the kind of thing where in hindsight we
> ask "why?".
>
> Also, can we drop the "public" modifier, if we do a new version of the RFC?
>
> Cheers
> Andreas
>

It's a totally different design concept (symmetric/left/right) and I've
been going over the design implications before I responded. For instance,
wouldn't this be a special case of method overloading? You're overloading
according to a modifier, not the typing, but there is that to contend with.
If someone defined `symmetric operator +` and `left operator +` which would
be used? (My feeling is left as its more specific.) How would they be
stored within the zend_class_entry? Since they would technically have the
same name, something would need to happen for them to not be in the
function table.

The public modifier is not required (as stated in the RFC), you can just
add it if you want. Are you asking for `public operator` to produce a
compile error?

Jordan


Re: [PHP-DEV] RFC: Trait expects interface

2022-01-05 Thread Rowan Tommins

On 04/01/2022 22:35, Kirill Nesmeyanov wrote:

Since «traits» are often an indicator of not very good code and many may not 
use them quite correctly, for example, as helpers, I suggest adding support for 
the `expects` keyword to indicate that the trait is part of the code 
decomposition taking into account ISP.



Hi Kirill,

I'm a little confused what problem this is trying to solve - in what way 
does using a trait in the "wrong" inheritance hierarchy constitute "abuse"?



On 04/01/2022 23:10, Bruce Weirdan wrote:

Prior art: @psalm-require-extends and @psalm-require-implements Psalm
annotations:https://psalm.dev/docs/annotating_code/supported_annotations/#psalm-require-extends


... and on 05/01/2022 12:36, Saif Eddin Gmati wrote:

ref:https://docs.hhvm.com/hack/traits-and-interfaces/trait-and-interface-requirements



The examples in both of these cases appear to be using the requirements 
primarily as short-hand for listing abstract methods in the trait.


For instance:

interface FooInterface {
 public function doFoo();
}
trait SillyFooTrait {
    require implements FooInterface;
    public function doFooTwice() {
    $this->doFoo();
    $this->doFoo();
   }
}

Is essentially equivalent to:

trait SillyFooTrait {
    abstract public function doFoo();
    public function doFooTwice() {
    $this->doFoo();
    $this->doFoo();
   }
}


In other words, the requirement is there because it is actually a 
requirement for the trait to work correctly, not because of some 
perceived "correct" use of the trait. This doesn't seem to match your 
reasoning for proposing the syntax, so maybe I'm missing something?



Regards,

--
Rowan Tommins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [VOTE] User Defined Operator Overloads

2022-01-05 Thread Andreas Hennings
Hello Jordan,
do you have any thoughts about these symmetric/left/right modifiers,
to get rid of the $operandPos parameter?

To me, the parameter could be the kind of thing where in hindsight we
ask "why?".

Also, can we drop the "public" modifier, if we do a new version of the RFC?

Cheers
Andreas


On Tue, 4 Jan 2022 at 00:27, Andreas Hennings  wrote:
>
> Hello Jordan,
>
> I have another note about the RFC.
> (I am not sure what's the policy, if we should continue _all_
> discussion here or go back to the RFC thread. Hope it's ok here.)
>
> OperandPosition::LeftSide
> OperandPosition::RightSide
>
> I wonder if this is the best way to model this.
> Especially, it does not account for the case where an operator only
> works in one direction, or the allowed operand type is dependent on
> the direction.
> E.g., (Money / float) is ok, but (float / Money) probably not supported.
> Or if it is supported, then the return type will be quite different.
> You can throw an exception, but this is not useful for static analysis.
>
> An alternative syntax with a few more keywords:
>
> abstract class Money {
>   symmetric operator * (float|int $other): Money;  // Commutative.
>   left operator / (float|int $other): Money;  // Only $a / $b allowed,
> $b / $a not possible.
>   left operator - (Money $other): Money;  // $a - $b
>   right operator - (Money $other): Money;  // $b - $a
> }
>
> Btw, in the Matrix example from the RFC, under "When will $operandPos
> be useful?", the $operandPos is not really useful, because it will
> always pick the default $a - $b version.
> The same applies to "-" operator in my Money example, because $other
> already implements the operator.
>
> The $operandPos is only needed if the left operand does _not_
> implement the operator. Which is the case e.g. for complex numbers, or
> the Number class from the RFC example.
>
> I am trying to think of cases where ($a  $b) would have a
> different type than ($b  $a), but I can't think of any.
> Or rather, for any case that I could think of, the mirror operator
> could simply be provided by $b.
>
> I am not married to the modifier names, e.g. it could be "symmetric"
> or "commutative" or something else.
> For left/right perhaps I prefer to talk about the "default direction"
> vs the "flipped direction", not sure how this could be turned into
> keywords.
> If we don't like more keywords, perhaps something like "!operator" for
> the flipped version?
>
> Cheers
> Andreas
>
> On Mon, 3 Jan 2022 at 01:14, Jordan LeDoux  wrote:
> >
> > Hello internals,
> >
> > I've opened voting on
> > https://wiki.php.net/rfc/user_defined_operator_overloads. The voting will
> > close on 2022-01-17.
> >
> > To review past discussions on this RFC and the feature in general, please
> > refer to:
> >
> > - https://externals.io/message/116611 | Current RFC discussion
> > - https://externals.io/message/115764 | Initial RFC discussion
> > - https://externals.io/message/115648 | Pre-RFC discussion and fact-finding
> >
> > Jordan

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [VOTE] User Defined Operator Overloads

2022-01-05 Thread Andreas Leathley

On 05.01.22 10:42, Jordan LeDoux wrote:

I suppose the alternative would be to withdraw the RFC
now that a wider variety of voters are providing feedback than the other
three threads.


I would let the vote go on, as there are still many voters who have not
voted on this yet, giving the proposal more exposure and also giving you
a more complete feedback about the outcome. And if this RFC has less
voters in total when it ends than other RFCs, that could also be good to
know. There have been quite a few big PHP features which failed in the
first attempt, but then easily passed in a later attempt after more
discussions and changes.

Also, your hint about the operator keyword decision and on what that is
based on might offer more avenues to change some minds - personally, I
would be interested to read a blog article about this (even if it is
quite lengthy, and even though I don't have a vote and am not designing
languages), and linking that in an RFC could then be some helpful
background for some people, even if not everyone reads it. And such an
article might be interesting to people outside of PHP.

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [VOTE] User Defined Operator Overloads

2022-01-05 Thread Andreas Heigl

Hey Jordan.

On 05.01.22 10:42, Jordan LeDoux wrote:

On Tue, Jan 4, 2022 at 10:50 PM Pierre Joye  wrote:



I hesitated too, however I think we can't escape this feature. Like it
was for the annotation, we need to find a compromise.

Your points are valid so I wonder if the RFC could be modified and get
to the point we could reach that compromise. There will be the
oppositions for the features as a whole, however I am optimistic about
our abilities to get there this time rather than wait yet again a few
years for something we know we will have anyway.



I will certainly be making changes before bringing this RFC back if it is
rejected. What exactly those changes are I am not certain yet, but the
feedback I receive here from voters will obviously have a large impact on
that. As i mentioned elsewhere, swapping to a magic method syntax would be
about 2-3 hours of work, I could do that very quickly. But I don't want to
make a change like that after the voting has started, so any such changes
will have to wait. I suppose the alternative would be to withdraw the RFC
now that a wider variety of voters are providing feedback than the other
three threads.


I'd rather not see more magic being introduced. That would for me be a 
reason to vote against the RFC. No matter what it does.


Just my 0.02 €

Cheers

Andreas
--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+


OpenPGP_0xA8D5437ECE724FE5.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] [VOTE] User Defined Operator Overloads

2022-01-05 Thread Jordan LeDoux
On Tue, Jan 4, 2022 at 10:50 PM Pierre Joye  wrote:

>
> I hesitated too, however I think we can't escape this feature. Like it
> was for the annotation, we need to find a compromise.
>
> Your points are valid so I wonder if the RFC could be modified and get
> to the point we could reach that compromise. There will be the
> oppositions for the features as a whole, however I am optimistic about
> our abilities to get there this time rather than wait yet again a few
> years for something we know we will have anyway.
>

I will certainly be making changes before bringing this RFC back if it is
rejected. What exactly those changes are I am not certain yet, but the
feedback I receive here from voters will obviously have a large impact on
that. As i mentioned elsewhere, swapping to a magic method syntax would be
about 2-3 hours of work, I could do that very quickly. But I don't want to
make a change like that after the voting has started, so any such changes
will have to wait. I suppose the alternative would be to withdraw the RFC
now that a wider variety of voters are providing feedback than the other
three threads.

Jordan


Re: [PHP-DEV] [VOTE] User Defined Operator Overloads

2022-01-05 Thread Jordan LeDoux
On Wed, Jan 5, 2022 at 12:26 AM Aleksander Machniak  wrote:

>
> - what is the performance impact?
>

Each operator evaluation is very slightly better than the equivalent
function call, since the VM call chain is very slightly simpler, but for
most purposes you can think of the performance as being the same as a
method call. This is quite a bit slower than most operator evaluations
(which are lightning fast compared to function calls), however this *only*
affects *objects* used with operators, which currently always result in a
fatal error. So in that sense, there is no performance impact.


> - why "[public] operator" and not "operator function"?
>

As many people in this thread have pointed out, it's possible for less
experienced developers to do something truly devious with this (the same
way that they can with __get, __set, or __toString). I wanted to avoid
using the function keyword at all, because I wanted the code itself to
mentally prepare the programmer to treat these differently than arbitrary
functions. As I mentioned in a previous email, some will view this as
wishy-washy, but that decision was done after consulting a specialist that
I know in the field of Human Centered Design (the field of designing
technology so that it is used correctly by design alone). That is, in
truth, my largest reason for wanting the operator keyword, but it's also
something that I invested nearly two months of study and consultation into.
That makes it difficult for me to correctly convey that understanding to
other people here via email, so I have mostly restricted my arguments to
other things. I find myself in the odd position of not really being able to
dump all of the research I did here for everyone else, because frankly, no
one on this list *should* need to invest a week of studying to understand
an RFC.

So unfortunately, my best argument in favor of this is one I can't really
make, but that *is* the reason that I went this route.


> - what about precedence, i.e. what happens with $a + $b * $c? there's no
> clear answer
>

Precedence is handled by the compiler and how it handles the opcodes.
That's independent of any of the changes in this RFC, since the opcodes for
all the operators are the same with or without operator overloads. So the
precedence will be the same if $a, $b, and $c are ints or objects, even if
we later (for some reason) changed the precedence of the operators.


> - why not allow the tilde operator to be used in a different context?,
> e.g. in PostgreSQL it is used as a regular expression match, e.g.
>$a ~ '^[a-z]+$'
>

This would involve changing the opcode evaluation itself, instead of just
implementing a do_operation handler in zend_class_entry. It would introduce
much more surface for buggy behavior and be a great deal of additional
effort for that single operator.


> - the Implied Operators table does not mention ~= operation.
>

The ~= operator does not exist in PHP because the ~ operator is a unary
operator in PHP (bitwise not).

See:

- https://www.php.net/manual/en/language.operators.assignment.php
- https://3v4l.org/N9OYF


> - I don't like the Reflection API changes
>

Please suggest changes then. It seems probable this will not pass in this
incarnation, so knowing what things to improve before bringing it back
would be helpful.

Jordan


Re: [PHP-DEV] [VOTE] User Defined Operator Overloads

2022-01-05 Thread Aleksander Machniak

On 03.01.2022 01:13, Jordan LeDoux wrote:

https://wiki.php.net/rfc/user_defined_operator_overloads. The voting will
close on 2022-01-17.


- what is the performance impact?
- why "[public] operator" and not "operator function"?
- what about precedence, i.e. what happens with $a + $b * $c? there's no 
clear answer
- why not allow the tilde operator to be used in a different context?, 
e.g. in PostgreSQL it is used as a regular expression match, e.g.

  $a ~ '^[a-z]+$'
- the Implied Operators table does not mention ~= operation.
- I don't like the Reflection API changes

--
Aleksander Machniak
Kolab Groupware Developer[https://kolab.org]
Roundcube Webmail Developer  [https://roundcube.net]

PGP: 19359DC1 # Blog: https://kolabian.wordpress.com

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php