Re: [PHP-DEV] [RFC] User Defined Operator Overloads (v0.6)

2021-12-12 Thread Jordan LeDoux
Danack wrote:

> btw, I don't really care about this naming problem. My concern is that
> it's being used as a reason for introducing a special new type
> function, when it's really not a big enough problem to deserve making
> the language have special new syntax.
>
>
Danack wrote:
> I think you've taken the position that using the symbols are cool, and
> you're reasoning about how the RFC should operate from decision.

Ah, I see. That's a more fundamental objection than the technicals, I
think. It sort of implies that any arguments I provide are justifications
rather than arguments, which makes it difficult to have a productive
conversation about it. You expressed a similar concern about your efforts
to present arguments to me, which makes sense if this is your fundamental
concern.

First, let me start off by saying that I fully acknowledge and document in
the RFC that it is possible to provide a perfectly workable version of
*this* RFC without the operator keyword. I mention as much in the RFC. If
that is a true blocker for voters, I would at least consider it. However, I
do believe that's the incorrect decision. Not because it's "cool". The code
that handles the parsing of the new keyword is the only part of this RFC
that I didn't write from scratch, it was contributed by someone more
familiar with the parser. I feel like I could hardly have the "coolness" of
the work being my motivating factor when I did not in fact write that part
of the code.

But I do understand the concern. Adding complexity without reason is
foolish, particularly on a project that impacts many people and is
maintained by volunteers. As I immediately told you, I don't think your
concern is without merit, and I don't think it's something that should be
dismissed. But I clearly have (still) done a poor job communicating what I
perceive as the factors that outweigh this concern. It's not that I think
the concern is invalid or that it's small, it's that I view other things as
being an acceptable tradeoff. So I'll attempt one more time to communicate
why.

# Forwards Compatibility

Other replies have touched on this, and the RFC talks about this too, but
perhaps the language used has been skipping a couple of steps. This is, by
far, the biggest driving factor for why I believe the operator keyword is
the correct decision, so I will spend most of my time here.

There are two main kinds of forward compatibility achieved with a new
keyword that are difficult to achieve with magic methods: compatibility
with arbitrary symbol combinations, and behavior modifiers that can be
scoped only to operators. You mention that the symbols could be replaced
with their symbol names in english, which avoids the issue of misnaming the
functions. But this would still require the engine to specifically support
every symbol combination that is allowed.

Now, in this RFC I am limiting overloads to *not only* symbols which are
already used, but to a specific subset of them which are predetermined.
This is for several reasons:

1. The PHP developer community will have no direct experience with operator
overloads unless they have experience with another language such as C# or
python which supports them. Giving developers an initial set of operators
that address 90% of use cases but are limited allows the PHP developer
community time to learn and experiment with the feature while avoiding some
of the most dangerous possible misuses, such as accidentally redefining the
&& operator in a way that breaks boolean algebra.
2. This reduces the change necessary to the VM, to class entries, and to
the behavior of existing opcodes. This PR is already very large, and I
wanted to make sure that it wasn't impossible for the people who
participate here on their own time to actually consider the changes being
suggested.
3. I am already aware of several people within internals that believe any
version of this feature will result in uncontrolled chaos in PHP codebases.
I think this is false, as I do not see that kind of uncontrolled chaos in
the languages which do have this feature. However I would think that
allowing arbitrary overloads would increase that proportion.
4. This is limited to operator combinations with objects, which *ALL*
currently result in an error. That means there is no code that was working
on PHP 8.1 that will break with this included, as all such code currently
results in a fatal error. The current error is even the parent class of the
error *after* this RFC, so even the catch blocks, if they currently exist
in PHP codebases, should continue to work as before.

However, once a feature is added it is very difficult to change it. Not
only for backward compatibility reasons, but for the sheer inertia of the
massive impact that PHP has. I do not plan on ever proposing that arbitrary
symbol combinations be allowed for overloads myself. But I cannot possibly
know what internals might think of that possibility 10 years from now when
this feature has been in widespr

Re: [PHP-DEV] [RFC] User Defined Operator Overloads (v0.6)

2021-12-12 Thread Rowan Tommins

On 12/12/2021 22:01, Larry Garfield wrote:

If the list of operators is expanded by the engine, yes.  The point is that IF 
it were decided in the future to allow user-space defined operators, that would 
be considerably easier with a separate keyword.



A real-life example of this approach would be PostgreSQL, where a 
user-defined operator can be (almost) any combination of + - * / < > = ~ 
! @ # % ^ & | ` ?


It would be *possible* to have an open-ended naming scheme for these, 
such as "function __atSign_leftAngle" for the operator @> (which 
conventionally means "contains" in PostgreSQL) but it would be rather 
awkward compared to "operator &>" or "#[Operator('&>')]".



Regards,

--
Rowan Tommins
[IMSoP]

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



Re: [PHP-DEV] [RFC] User Defined Operator Overloads (v0.6)

2021-12-12 Thread Larry Garfield
On Sun, Dec 12, 2021, at 12:56 PM, Dan Ackroyd wrote:
> On Sat, 11 Dec 2021 at 17:46, Larry Garfield  wrote:
>>
>> Using symbols, however, would (with some future extension to make it 
>> extensible) allow for:
>
> I don't get how it's easier, other than being able to skip naming the
> symbol name. e.g. adding union and intersection operators
>
> function __union(...){}
> function __intersection(...){}
>
> vs
>
> operator  ∪(...){}
> operator ∩(...){}
>
> In fact, I find one of those quite a bit easier to read...

If the list of operators is expanded by the engine, yes.  The point is that IF 
it were decided in the future to allow user-space defined operators, that would 
be considerably easier with a separate keyword.  Eg:

class Matrix {
  operator dot(Matrix $other, bool $left) {
// ...
  }
}

$result = $m1 dot $m2;

Whether that is something we want to do is another question, but the operator 
keyword makes that logistically easy, while using __mul or __astrisk makes it 
logistically hard.

Using an attribute instead to bind a method to an operator, as previously 
suggested, would also have that flexibility if we ever wanted it.  There seems 
to be a lot of backpressure against using attributes for such things, though, 
and it wouldn't cleanly self-resolve the issue of keywords that make sense on 
methods being nonsensical on operators.  (public, static, etc.).  I'd probably 
be fine with it myself, but I cannot speak for others.

--Larry Garfield

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



Re: [PHP-DEV] [RFC] User Defined Operator Overloads (v0.6)

2021-12-12 Thread Dan Ackroyd
On Sat, 11 Dec 2021 at 19:13, Jordan LeDoux  wrote:
>
> I *think* that all of the things you mentioned will need similar
> updates to work correctly with this RFC even if it was done
> with plain old magic methods instead.

No, that's not true. Codesniffer and all the other tools parse magic
methods just fine. Stuff like the coverage notation for PHPUnit would
understand `@covers BigNumber::__plus` just fine.

The main piece of work each of them would need to do to support this
RFC, if it was based on magic methods, is being able to understand
that objects can work with operators:

```
$foo = new BigNumber(5);
$foo + 5; // Check that BigNumber implements the magic method __plus
```

That is far less work than having to add stuff to parse a new way to
declare functions.

Jordan LeDoux wrote:
>
> Danack wrote:
>> # "Non-Callable - Operand implementations cannot be called on an
>> instance of an object the way normal methods can."
>> I think this is just wrong, and makes the RFC unacceptable to me.
>
> First, you can still get the closure for the operator implementation
> from Reflection if you really, really need it.

Sorry, but I just find that a bizarre thing to suggest. Introducing a
new type of function that can only be called in a particular way needs
to have really strong reasons for that, not "oh you can still call it
through reflection".

I think you've taken the position that using the symbols are cool, and
you're reasoning about how the RFC should operate from decision.

I'm not sure I can make a reasonable argument against it that you
would find persuasive, but to me it's adding a non-trivial amount of
complexity, which tips the RFC from being acceptable, to not.

cheers
Dan
Ack

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



Re: [PHP-DEV] [RFC] User Defined Operator Overloads (v0.6)

2021-12-12 Thread Rowan Tommins

On 12/12/2021 18:29, Rowan Tommins wrote:

Perhaps we could use an Attribute to bind the operator to the method, which 
would also reduce the impact on tools that need to parse class definitions:

class  Collection{ #[Operator('+')]
public function  union(Collection$other,  OperandPosition$operandPos)  {}
}

An interesting extension would be to have an optional argument to the Attribute 
which binds separate methods for each direction of arguments, rather than 
exposing it as a parameter:

class  Number{ #[Operator('/', OperandPosition::LeftSide)]
public function  divideBy(Number $divisor)  {}

#[Operator('/', OperandPosition::RightSide)]
publicfunction  fractionOf(Number $dividend)  {}
} 



Sorry about the whitespace mess in the above examples; this may or may not show 
better:


class Collection{
#[Operator('+')]
public function union(Collection $other,  OperandPosition $operandPos)  {}
}

class Number{
#[Operator('/', OperandPosition::LeftSide)]
public function divideBy(Number $divisor)  {}

#[Operator('/', OperandPosition::RightSide)]
public function fractionOf(Number $dividend)  {}
}


Regards,

--
Rowan Tommins
[IMSoP]

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



Re: [PHP-DEV] [RFC] User Defined Operator Overloads (v0.6)

2021-12-12 Thread Dan Ackroyd
On Sat, 11 Dec 2021 at 17:46, Larry Garfield  wrote:
>
> Using symbols, however, would (with some future extension to make it 
> extensible) allow for:

I don't get how it's easier, other than being able to skip naming the
symbol name. e.g. adding union and intersection operators

function __union(...){}
function __intersection(...){}

vs

operator  ∪(...){}
operator ∩(...){}

In fact, I find one of those quite a bit easier to read...

Larry Garfield wrote:
> It uses effectively the same operator sigil, though.

Yes, that's what I was trying to say.

Danack wrote:
> The name of the function (e.g. __add) always refers to the symbol used
> where it is used, not what it is doing.

If the naming is taken from the sigil, then it's always appropriate.

So if operator * has the magic method __asterisk instead of __mul, it
avoids any suggestion of what the operation actually means for the
object.

btw, I don't really care about this naming problem. My concern is that
it's being used as a reason for introducing a special new type
function, when it's really not a big enough problem to deserve making
the language have special new syntax.

cheers
Dan
Ack

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



Re: [PHP-DEV] [RFC] User Defined Operator Overloads (v0.6)

2021-12-12 Thread Dan Ackroyd
On Sun, 12 Dec 2021 at 08:55, James Titcumb  wrote:
>
> The only mitigation for unnecessary complexity I can think of is to force
> overloaded operators to be "arrow functions" to encourage only minimal
> code, e.g.
>

The 'valid' use-cases for this aren't going to minimal pieces of code.

Things like a matrix object that supports multiplying by the various
things that matrices can be multiplied by won't fit into an arrow
function.

Also, I fundamentally disagree with making stuff difficult to use to
'punsish' users who want to use that feature. If you want to enforce
something like a max line length in a coding standard, or forbidding
usage of a feature, that is up to you and any code style tool you use.

> I just think the desire to use this in ways it shouldn't be
> used will be too great,

It might be an idea to add a list of bad examples to the RFC, so
people can refer to how not to use it, rather than each programming
team having to make the same mistakes.

cheers
Dan
Ack

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



Re: [PHP-DEV] [RFC] User Defined Operator Overloads (v0.6)

2021-12-12 Thread Rowan Tommins

On 12/12/2021 17:32, Larry Garfield wrote:

The only mitigation for unnecessary complexity I can think of is to force
overloaded operators to be "arrow functions" to encourage only minimal
code, e.g.

operator +(Number $other, OperandPosition $operandPos): Number => return
new Number ($this->value + $other->value);

I don't think that would be possible.  As many of the examples in the RFC show, 
there are numerous cases where an operator function/callback/thing will need 
branching logic internally.  Even if we did that, people could just sub-call to 
a single function which would be just as complex as if it were in the operator 
callback directly.



I don't know if this would actually be helpful, but you could *force* 
the operator definition to be an alias for a normal method. That would 
(at least partially) solve the "dynamic call" problem, because the 
underlying method would be available with the existing dynamic call syntax.


Perhaps we could use an Attribute to bind the operator to the method, 
which would also reduce the impact on tools that need to parse class 
definitions:


class  Collection{ #[Operator('+')]
public function  union(Collection$other,  OperandPosition$operandPos)  {}
}

An interesting extension would be to have an optional argument to the 
Attribute which binds separate methods for each direction of arguments, 
rather than exposing it as a parameter:


class  Number{ #[Operator('/', OperandPosition::LeftSide)]
public function  divideBy(Number $divisor)  {}

#[Operator('/', OperandPosition::RightSide)]
publicfunction  fractionOf(Number $dividend)  {}
}


Regards,

--
Rowan Tommins
[IMSoP]

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



Re: [PHP-DEV] [RFC] User Defined Operator Overloads (v0.6)

2021-12-12 Thread Larry Garfield
On Sun, Dec 12, 2021, at 2:55 AM, James Titcumb wrote:
> On Thu, 9 Dec 2021, 20:12 Jordan LeDoux,  wrote:
>
>>
>> RFC Link: https://wiki.php.net/rfc/user_defined_operator_overloads
>
>
> I'm not strongly opinionated on either approach (magic __add vs operator +)
> although I have a very slight preference to your propose operator + syntax,
> however despite very occasionally thinking that this would be a useful
> feature, I always start to think about all the awful ways this could be
> used, making debugging and reasoning about code harder, since unexpected
> magic behaviour can (and probably will be) introduced.
>
> The proposal is technically reasonable, pending consideration of reflection
> and so on, but I just think the desire to use this in ways it shouldn't be
> used will be too great, and we'll end up with horrendous complexity.
> Perhaps I'm too cynical.
>
> The only mitigation for unnecessary complexity I can think of is to force
> overloaded operators to be "arrow functions" to encourage only minimal
> code, e.g.
>
> operator +(Number $other, OperandPosition $operandPos): Number => return
> new Number ($this->value + $other->value);

I don't think that would be possible.  As many of the examples in the RFC show, 
there are numerous cases where an operator function/callback/thing will need 
branching logic internally.  Even if we did that, people could just sub-call to 
a single function which would be just as complex as if it were in the operator 
callback directly.

(Though I still would like to see "short functions" in the language, despite it 
having been rejected once already.)

--Larry Garfield

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



Re: [PHP-DEV] RFC [Discussion] array_column results grouping

2021-12-12 Thread Hassan Ahmed
I already added a new function `array_group`, any further
comments/thoughts will be highly appreciated.

Regards,
~Hassan

On Wed, Dec 8, 2021 at 11:35 AM Hassan Ahmed <7sno...@gmail.com> wrote:
>
> Hendra Gunawan IMHO your suggestions is not related to
> `array_group()`, you are talking about a great change in PHP as
> mentioned by Larry, since we can have `Array($input, group(),
> reducer(), mapper(), filter() . and so forth);` or even any other
> way to handle the list comprehensions. but for array_group I think
> that we should keep it to the minimal, to only group array.
>
> ~Hassan Ahmed
>
> On Wed, Dec 8, 2021 at 1:26 AM Hendra Gunawan
>  wrote:
> >
> > >
> > > And if you want to map, reduce, or filter without grouping? Then you can't
> > > really use this function. And as noted, the order in which you apply those
> > > operations may matter, and no order is necessarily more obvious or 
> > > beneficial
> >
> > You can modify it slightly if you eager to:
> >
> > array_group(
> > ...
> > null|int|string|array $index_key,
> > ...
> > ): array
> >
> > If You provide `null`, it will operate on a bare array, no grouping 
> > involved.
> > As a consequence, users have to provide `reducer` or `mapper`. So virtually,
> > You design `array_group` to swallow `array_reduce` and `array_map`. Though,
> > `array_map` is actually a different API compared to `array_reduce` or
> > `array_group`.
> >
> > Interestingly, you will get a better quality of code if you include 
> > `reducer: `
> > and `mapper: ` consistently, whatever array level you work with.
> >
> > // `array_reduce` and `array_map` alternative
> > array_group($array, null, reducer: $fnReducer);
> > array_group($array, null, mapper: $fnMapper);
> >
> > array_group($array, "level1", reducer: $fnReducer);
> > array_group($array, "level1", mapper: $fnMapper);
> > array_group($array, ["level1", "level2"], reducer: $fnReducer);
> > array_group($array, ["level1", "level2"], mapper: $fnMapper);
> >
> > I hope there is no bias between the proposed name (`array_group`) and its
> > functionality.
> >
> > >
> > > Either of these approaches would be superior to cramming more 
> > > functionality
> > > into a single-purpose function to turn it into a single-function swiss 
> > > army
> > > knife:
> >
> > Not a swiss army knife, just a penknife. AS i wrote before, it is just a
> > shortcut. If you really mind about that, we can cancel `filter` and 
> > `sorter`,
> > leaving only `reducer` and `mapper`. Thought, we can filtering and sorting
> > before `array_group`, but i don't know whether it is as accurate as 
> > embedding
> > them into `array_group` or not. If not, we have to iterate manually, do
> > filtering and/or sorting, then reducing/mapping.
> >
> > >
> > > https://wiki.php.net/rfc/comprehensions
> > > https://wiki.php.net/rfc/pipe-operator-v2
> >
> > Of course these are wonderful proposals. Yes, they are superior. To be 
> > honest,
> > I really hope they are landed in PHP. I already imagine what part of my code
> > will be replaced by them. Since I am not a C coder and totally blind about 
> > the
> > engine, I don't have my own opinion whether we lost good things or not, by 
> > not
> > adding them to PHP.
> >
> > --
> > PHP Internals - PHP Runtime Development Mailing List
> > To unsubscribe, visit: https://www.php.net/unsub.php
> >

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



Re: [PHP-DEV] [RFC] User Defined Operator Overloads (v0.6)

2021-12-12 Thread James Titcumb
On Thu, 9 Dec 2021, 20:12 Jordan LeDoux,  wrote:

>
> RFC Link: https://wiki.php.net/rfc/user_defined_operator_overloads


I'm not strongly opinionated on either approach (magic __add vs operator +)
although I have a very slight preference to your propose operator + syntax,
however despite very occasionally thinking that this would be a useful
feature, I always start to think about all the awful ways this could be
used, making debugging and reasoning about code harder, since unexpected
magic behaviour can (and probably will be) introduced.

The proposal is technically reasonable, pending consideration of reflection
and so on, but I just think the desire to use this in ways it shouldn't be
used will be too great, and we'll end up with horrendous complexity.
Perhaps I'm too cynical.

The only mitigation for unnecessary complexity I can think of is to force
overloaded operators to be "arrow functions" to encourage only minimal
code, e.g.

operator +(Number $other, OperandPosition $operandPos): Number => return
new Number ($this->value + $other->value);