Hi internals!
https://wiki.php.net/rfc/operator_overloading_gmp
This RFC proposes to add operator overloading for INTERNAL classes.
Furthermore it exemplarily implements the new API for GMP.
Thanks,
Nikita
Hi internals!
https://wiki.php.net/rfc/operator_overloading_gmp
This RFC proposes to add operator overloading for INTERNAL classes.
Furthermore it exemplarily implements the new API for GMP.
IMO the proposal B is quite reasonable change, but the proposal A (i.e. the operator overloading part) is definitely an overkill.
A simple benchmark should demonstrate that using GMP for basic arithmetic would kill performance in quite a brutal way.
--
Wbr,
Antony Dovgal
http://pinba.org - realtime profiling for PHP
Hi internals!
https://wiki.php.net/rfc/operator_overloading_gmp
This RFC proposes to add operator overloading for INTERNAL classes.
Furthermore it exemplarily implements the new API for GMP.IMO the proposal B is quite reasonable change, but the proposal A (i.e. the
operator overloading part) is definitely an overkill.
A simple benchmark should demonstrate that using GMP for basic arithmetic
would kill performance in quite a brutal way.
Right, the difficulty here is to use it for large numbers only. It
reduces the impact for standard ranges but do not totally suppress it.
Cheers,
Pierre
@pierrejoye | http://www.libgd.org
Hi internals!
https://wiki.php.net/rfc/**operator_overloading_gmphttps://wiki.php.net/rfc/operator_overloading_gmp
This RFC proposes to add operator overloading for INTERNAL classes.
Furthermore it exemplarily implements the new API for GMP.IMO the proposal B is quite reasonable change, but the proposal A (i.e.
the operator overloading part) is definitely an overkill.
A simple benchmark should demonstrate that using GMP for basic arithmetic
would kill performance in quite a brutal way.
I think this is a misunderstanding. I do not suggest to use GMP for all
arithmetic and also do not suggest to auto-promote to GMP for large numbers.
The operator overloading only comes into play if one of the operands is
already a GMP instance.
Regarding performance: The addition of the operator overloading does have a
measurable impact on performance. The switch of GMP from resources to
objects also does not show any clear change either way. What does become
faster is if a gmp function gets a non-gmp argument and needs to cast it to
GMP (this is faster because now only the mpz_t instance is created and not
a full resource). Obviously when the overloaded operators are used rather
than the functions it's faster too.
Nikita
I think this is a misunderstanding. I do not suggest to use GMP for all
arithmetic and also do not suggest to auto-promote to GMP for large numbers.The operator overloading only comes into play if one of the operands is
already a GMP instance.Regarding performance: The addition of the operator overloading does have
a measurable impact on performance.
Ooops, that was a typo. I wanted to say "does NOT have a measurable impact
on performance".
The switch of GMP from resources to objects also does not show any clear
change either way. What does become faster is if a gmp function gets a
non-gmp argument and needs to cast it to GMP (this is faster because now
only the mpz_t instance is created and not a full resource). Obviously when
the overloaded operators are used rather than the functions it's faster too.
I tweaked the implementation a bit and now it seems to be faster in any
case. I added some numbers in
https://wiki.php.net/rfc/operator_overloading_gmp#performance
Nikita
Are we ignoring the ZEND_IS_SMALLER issue?
if ($gmp > 123) { ... }
There's no ZEND_IS_GREATER opcode, so it gets quietly turned into:
if (123 < $gmp) { ... }
Which will be confusing.
I dealt with this in operator by having the user apply a patch before
building:
https://github.com/php/pecl-php-operator/blob/master/compare-greater-5.1.2.diff
If we're going to bake this into ZE, then we should just add
ZEND_IS_GREATER(_OR_EQUAL) opcode.
-Sara
On Sun, May 12, 2013 at 7:50 PM, Antony Dovgal tony@daylessday.org
wrote:Hi internals!
https://wiki.php.net/rfc/**operator_overloading_gmp<
https://wiki.php.net/rfc/operator_overloading_gmp>This RFC proposes to add operator overloading for INTERNAL classes.
Furthermore it exemplarily implements the new API for GMP.IMO the proposal B is quite reasonable change, but the proposal A (i.e.
the operator overloading part) is definitely an overkill.
A simple benchmark should demonstrate that using GMP for basic arithmetic
would kill performance in quite a brutal way.I think this is a misunderstanding. I do not suggest to use GMP for all
arithmetic and also do not suggest to auto-promote to GMP for large
numbers.The operator overloading only comes into play if one of the operands is
already a GMP instance.Regarding performance: The addition of the operator overloading does have a
measurable impact on performance. The switch of GMP from resources to
objects also does not show any clear change either way. What does become
faster is if a gmp function gets a non-gmp argument and needs to cast it to
GMP (this is faster because now only the mpz_t instance is created and not
a full resource). Obviously when the overloaded operators are used rather
than the functions it's faster too.Nikita
Are we ignoring the ZEND_IS_SMALLER issue?
Not ignoring it :) It's mentioned in one sentence: "The operators >, >=, [...]
are indirectly supported by the following compiler transformations: [...]"
if ($gmp > 123) { ... }
There's no ZEND_IS_GREATER opcode, so it gets quietly turned into:
if (123 < $gmp) { ... }
Which will be confusing.
Why would this be confusing? I'd agree if this happened in userland (people
could wonder why the operators are swapped), but internally we are already
dealing with this anyway. E.g. when you implement compare_objects you have
to be aware of this (to understand stuff like the return 1 trick).
I dealt with this in operator by having the user apply a patch before
building:
https://github.com/php/pecl-php-operator/blob/master/compare-greater-5.1.2.diffIf we're going to bake this into ZE, then we should just add
ZEND_IS_GREATER(_OR_EQUAL) opcode.
Not sure this is really necessary, but I have no problem with doing that
either.
Nikita
Hi!
Why would this be confusing? I'd agree if this happened in userland (people
could wonder why the operators are swapped), but internally we are already
dealing with this anyway. E.g. when you implement compare_objects you have
to be aware of this (to understand stuff like the return 1 trick).
Your code suggests (even though RFC never says it) that the left operand
defines the comparison. However, for the switched operations, the right
operand would then define the comparison. It is pretty confusing, IMO.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Why would this be confusing? I'd agree if this happened in userland
(people
could wonder why the operators are swapped), but internally we are
already
dealing with this anyway. E.g. when you implement compare_objects you
have
to be aware of this (to understand stuff like the return 1 trick).Your code suggests (even though RFC never says it) that the left operand
defines the comparison. However, for the switched operations, the right
operand would then define the comparison. It is pretty confusing, IMO.This. I see in zend_object_do_operation that op1 (LHS) has priority, but
if it's not an object, then op2(RHS) gets the chance to handle it. So it
works fine in the simple case of (Object and Non-Object), but if you have
two different Objects, both implementing operator overloading in
potentially different ways then the precedence order matters more. By
having a separate opcode for GREATER, the user can explicitly state who
they want to get precedence.
I realize I'm potentially trying to solve a problem which doesn't exist,
but separating out smaller/greater is a fairly trivial change, so I'd
rather we did it now and avoid potential fail.
-Sara
Hi Nikita,
The patch looks quite good.
However, it must slow down each comparison operator (even if it compares
two integers).
I would suggest overloading of CMP operator instead of separate <, <=, ==,
!=, >, >=.
Also it may make sense to think about overloading of unary operators to
provide a solid decision.
In case you think about user-level operator overloading in the future (that
may make sense :) it would be better to design them all together.
Thanks. Dmitry.
Hi internals!
https://wiki.php.net/rfc/operator_overloading_gmp
This RFC proposes to add operator overloading for INTERNAL classes.
Furthermore it exemplarily implements the new API for GMP.Thanks,
Nikita
Hi Nikita,
The patch looks quite good.
However, it must slow down each comparison operator (even if it compares
two integers).
In most cases it shouldn't, as the comparisons usually go through the
fast_is_*functions, which have special handling for integers and doubles.
is_equal_function itself for example is only used in the implementation of
ZEND_CASE (why? shouldn't we use the fast one here too?) and stuff like
array_search.
I would suggest overloading of CMP operator instead of separate <, <=, ==,
!=, >, >=.
But yeah, that sounds like a better solution. The advantages I see:
a) It will automatically work with sorting functions (and other stuff using
compare_function). This is a pretty big plus.
b) You don't have to implement the same (or similar) code for four (or six)
operators.
c) It (at least partially) also solves the concerns raised by Sara.
Would need an additional object handler though (as compare_objects works
only on objects, so it's currently not possible to support something like
$gmp == 0).
Nikita
Hi,
Hi Nikita,
The patch looks quite good.
However, it must slow down each comparison operator (even if it compares
two integers).In most cases it shouldn't, as the comparisons usually go through the
fast_is_*functions, which have special handling for integers and doubles.
is_equal_function itself for example is only used in the implementation of
ZEND_CASE (why? shouldn't we use the fast one here too?) and stuff like
array_search.
Ahh, you are right :)
I would suggest overloading of CMP operator instead of separate <, <=, ==,
!=, >, >=.
But yeah, that sounds like a better solution. The advantages I see:
a) It will automatically work with sorting functions (and other stuff
using compare_function). This is a pretty big plus.
b) You don't have to implement the same (or similar) code for four (or
six) operators.
c) It (at least partially) also solves the concerns raised by Sara.
I'm glad, you are agree :)
Would need an additional object handler though (as compare_objects works
only on objects, so it's currently not possible to support something like
$gmp == 0).
Or may be we may introduce additional opcode (or even pseudo-opcode)
ZEND_CMP to do it in the same way.
Also it may be better to use a table of callbacks for each overloaded
operand instead of single one that need to do switch anyway.
Thanks. Dmitry.
Nikita
Would need an additional object handler though (as compare_objects works
only on objects, so it's currently not possible to support something like
$gmp == 0).Or may be we may introduce additional opcode (or even pseudo-opcode)
ZEND_CMP to do it in the same way.
I implemented it with a separate handler for now (
https://github.com/nikic/php-src/commit/208442f84afd7ccd8e2dce8138c0950719a2e031),
but I'm also okay with moving it into do_operation. Not sure if it's a good
idea to add pseudo opcodes though.
Nikita
Hi Nikita,
I didn't get why do we need separate zend_std_compare() function.
May be I just didn't look careful :)
It would be great to look into the patch between master and current of your
branch.
It would be more clear than internal patches.
Thanks. Dmitry.
Would need an additional object handler though (as compare_objects
works only on objects, so it's currently not possible to support something
like $gmp == 0).Or may be we may introduce additional opcode (or even pseudo-opcode)
ZEND_CMP to do it in the same way.I implemented it with a separate handler for now (
https://github.com/nikic/php-src/commit/208442f84afd7ccd8e2dce8138c0950719a2e031),
but I'm also okay with moving it into do_operation. Not sure if it's a good
idea to add pseudo opcodes though.Nikita
Hi Nikita,
I didn't get why do we need separate zend_std_compare() function.
May be I just didn't look careful :)
Good point, that was not really necessary. I moved the code back into
compare_function.
It would be great to look into the patch between master and current of
your branch.
You can find a diff between master and my branch on the PR:
https://github.com/php/php-src/pull/342/files
The relevant diff for the compare handler is here:
https://github.com/php/php-src/pull/342/files#L2R1581
Nikita
Hi Nikita,
Few final notes:
-
I wouldn't change zend_object_compare_t into
zend_object_compare_objects_t. It would be better to name the new function
as zend_object_compare_zvals_t. (It's just for better backward
compatibility) -
Increment and decrement operators in PHP may have different semantic than
+=1, but I it's probably OK to use ADD/SUB for them. -
In some cases you insert call to zend_object_do_operation into the most
probable path (e.g. in mod_function). This would cause at lease 2
additional comparisons and may be conditional jumps. I think it would be
better to check for most probable operand types first...
I didn't look into GMP part.
Thanks. Dmitry.
Hi Nikita,
I didn't get why do we need separate zend_std_compare() function.
May be I just didn't look careful :)Good point, that was not really necessary. I moved the code back into
compare_function.It would be great to look into the patch between master and current of
your branch.You can find a diff between master and my branch on the PR:
https://github.com/php/php-src/pull/342/files
The relevant diff for the compare handler is here:
https://github.com/php/php-src/pull/342/files#L2R1581Nikita
Hi Nikita,
Few final notes:
- I wouldn't change zend_object_compare_t into
zend_object_compare_objects_t. It would be better to name the new function
as zend_object_compare_zvals_t. (It's just for better backward
compatibility)
Done. Should I also call the handler itself compare_zvals then or can that
stay as just compare?
- Increment and decrement operators in PHP may have different semantic than
+=1, but I it's probably OK to use ADD/SUB for them.
I think we should just introduce this once a use case comes up.
- In some cases you insert call to zend_object_do_operation into the most
probable path (e.g. in mod_function). This would cause at lease 2
additional comparisons and may be conditional jumps. I think it would be
better to check for most probable operand types first...
For $a % $b the most common cases are already handled by fast_mod_function.
mod_function is only directly called when doing $a %= $b. But in any case,
I'm not sure how I could test the more probable cases first, as the next
thing the code does is call convert_to_long. Of course I could copy the
code from fast_mod_function in there, but that doesn't sounds like a good
idea.
I think the only operation that could really be a performance concern is
concat_function, because that's a common operation without a fast_ variant.
But even in that case I could not measure a difference in runtime (taking
averages on 100M concatenations).
Also it may be better to use a table of callbacks for each overloaded
operand instead of single one that need to do switch anyway.
What would be the benefits? Better performance? Imho using a switch is
handier when implementing the operators, because it requires less
boilerplate code (no need to repeat function signature, variables, shared
code etc).
Also it may make sense to think about overloading of unary operators to
provide a solid decision.
You mean being able to overload unary + and - directly rather than the
current 0+$a / 0-$a transformation? I can see that this might be useful,
but not sure it's worth it (would have to introduce new opcodes for that).
I'd do the same as with the increment/decrement operators here: Only
implement them once there is a specific use case.
In case you think about user-level operator overloading in the future (that
may make sense :) it would be better to design them all together.
I was thinking about that too, but from the previous discussions on the
topic I figured that there is zero chance for having that in PHP :/
Thanks for the feedback!
Nikita
Hi Nikita,
Thanks for function renaming.
I'm agree about INC/DEC and unary operators (!, ~) implementation.
A single callback for all operators may not be always good, because classes
may overload not all but only few operators,
but technically it doesn't make any problems, so let keep it as is.
According to fast-path execution, I would really like to not introduce the
additional checks.
Especially for concat_function I would change it in the following way:
if (Z_TYPE_P(op1) != IS_STRING) {
if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, do_operation))
{
return Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_CONCAT, result, op1,
op2 TSRMLS_CC);
}
zend_make_printable_zval(op1, &op1_copy, &use_copy1);
}
if (Z_TYPE_P(op2) != IS_STRING) {
if (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_HANDLER_P(op2, do_operation))
{
return Z_OBJ_HANDLER_P(op2, do_operation)(ZEND_CONCAT, result, op1,
op2 TSRMLS_CC);
} zend_make_printable_zval(op2, &op2_copy, &use_copy2);
}
And in similar way for mod, shift, etc
if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, do_operation))
{
return Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_MOD, result, op1, op2
TSRMLS_CC);
}
zendi_convert_to_long(op1, op1_copy, result);
}
op1_lval = Z_LVAL_P(op1);
if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
if (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_HANDLER_P(op2, do_operation))
{
return Z_OBJ_HANDLER_P(op2, do_operation)(ZEND_MOD, result, op1, op2
TSRMLS_CC);
} zendi_convert_to_long(op2, op2_copy, result);
}
I think this is the last technical issue :)
Thanks. Dmitry.
Hi Nikita,
Few final notes:
- I wouldn't change zend_object_compare_t into
zend_object_compare_objects_t. It would be better to name the new function
as zend_object_compare_zvals_t. (It's just for better backward
compatibility)Done. Should I also call the handler itself compare_zvals then or can that
stay as just compare?
- Increment and decrement operators in PHP may have different semantic
than +=1, but I it's probably OK to use ADD/SUB for them.
I think we should just introduce this once a use case comes up.
- In some cases you insert call to zend_object_do_operation into the most
probable path (e.g. in mod_function). This would cause at lease 2
additional comparisons and may be conditional jumps. I think it would be
better to check for most probable operand types first...For $a % $b the most common cases are already handled by
fast_mod_function. mod_function is only directly called when doing $a %=
$b. But in any case, I'm not sure how I could test the more probable cases
first, as the next thing the code does is call convert_to_long. Of course I
could copy the code from fast_mod_function in there, but that doesn't
sounds like a good idea.I think the only operation that could really be a performance concern is
concat_function, because that's a common operation without a fast_ variant.
But even in that case I could not measure a difference in runtime (taking
averages on 100M concatenations).Also it may be better to use a table of callbacks for each overloaded
operand instead of single one that need to do switch anyway.What would be the benefits? Better performance? Imho using a switch is
handier when implementing the operators, because it requires less
boilerplate code (no need to repeat function signature, variables, shared
code etc).Also it may make sense to think about overloading of unary operators to
provide a solid decision.You mean being able to overload unary + and - directly rather than the
current 0+$a / 0-$a transformation? I can see that this might be useful,
but not sure it's worth it (would have to introduce new opcodes for that).
I'd do the same as with the increment/decrement operators here: Only
implement them once there is a specific use case.In case you think about user-level operator overloading in the future
(that may make sense :) it would be better to design them all together.
I was thinking about that too, but from the previous discussions on the
topic I figured that there is zero chance for having that in PHP :/Thanks for the feedback!
Nikita
According to fast-path execution, I would really like to not introduce the
additional checks.
Especially for concat_function I would change it in the following way:if (Z_TYPE_P(op1) != IS_STRING) {
if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, do_operation)) {
return Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_CONCAT, result, op1, op2 TSRMLS_CC);
}
zend_make_printable_zval(op1, &op1_copy, &use_copy1);
}
if (Z_TYPE_P(op2) != IS_STRING) {
if (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_HANDLER_P(op2, do_operation)) {
return Z_OBJ_HANDLER_P(op2, do_operation)(ZEND_CONCAT, result, op1, op2 TSRMLS_CC);
} zend_make_printable_zval(op2, &op2_copy, &use_copy2);
}And in similar way for mod, shift, etc
if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, do_operation)) {
return Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_MOD, result, op1, op2 TSRMLS_CC);
}
zendi_convert_to_long(op1, op1_copy, result);
}
op1_lval = Z_LVAL_P(op1);
if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {if (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_HANDLER_P(op2, do_operation)) {
return Z_OBJ_HANDLER_P(op2, do_operation)(ZEND_MOD, result, op1, op2 TSRMLS_CC);
} zendi_convert_to_long(op2, op2_copy, result);
}
I now added checks to make sure that the overloading code is never in the
fast path. As an example see mod_function:
https://github.com/php/php-src/pull/342/files#L2R1034
I had to use if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG)
checks instead of individual checks as in your examples, otherwise the code
would behave differently (with no fallback to the normal code if FAILURE is
returned and also if the second operand is an object then the first one
would already be cast to long).
If there is no more feedback on the RFC, then I'll start voting in a day or
two.
Nikita
Hi!
If there is no more feedback on the RFC, then I'll start voting in a day or
two.
I would suggest splitting this RFC into two - the operator overloading
one and the GMP one. Converting GMP to objects has little to do with
overloading (even if needed for GMP to benefit from it) so I think it
would be better to treat them separately.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
On Fri, Jun 7, 2013 at 8:16 PM, Stas Malyshev smalyshev@sugarcrm.comwrote:
Hi!
If there is no more feedback on the RFC, then I'll start voting in a day
or
two.I would suggest splitting this RFC into two - the operator overloading
one and the GMP one. Converting GMP to objects has little to do with
overloading (even if needed for GMP to benefit from it) so I think it
would be better to treat them separately.
My main interest here is improving the usability of GMP - the operator
overloading is just a means to that goal. With that in mind, I think it
makes little sense to land just the addition of overloading, but leave the
GMP changes out. That's why I'm doing them both in one :) Hope that makes
some sense ^^
Nikita
Hi!
My main interest here is improving the usability of GMP - the operator
overloading is just a means to that goal. With that in mind, I think it
I understand that, but operator overloading is not the GMP-only change.
It is a change deep in the core of the engine, and as such should be
considered as generic engine change. If you did it confined to GMP
module, it would be different.
makes little sense to land just the addition of overloading, but leave
the GMP changes out. That's why I'm doing them both in one :) Hope that
makes some sense ^^
I'm sorry, but I disagree. GMP is one thing, and big core changes -
introducing operator overloading - is another. GMP refactoring by itself
is rather narrow thing, most PHP users don't even use GMP and don't need
it. However, introducing operator overloading for objects in PHP is a
huge thing with big implications for the future.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
On Sat, Jun 8, 2013 at 9:49 PM, Stas Malyshev smalyshev@sugarcrm.comwrote:
Hi!
My main interest here is improving the usability of GMP - the operator
overloading is just a means to that goal. With that in mind, I think itI understand that, but operator overloading is not the GMP-only change.
It is a change deep in the core of the engine, and as such should be
considered as generic engine change. If you did it confined to GMP
module, it would be different.makes little sense to land just the addition of overloading, but leave
the GMP changes out. That's why I'm doing them both in one :) Hope that
makes some sense ^^I'm sorry, but I disagree. GMP is one thing, and big core changes -
introducing operator overloading - is another. GMP refactoring by itself
is rather narrow thing, most PHP users don't even use GMP and don't need
it. However, introducing operator overloading for objects in PHP is a
huge thing with big implications for the future.
Not disagreeing with any of that, but I don't really understand how
splitting one document into two changes anything about what you say. What
would make sense though is having two separate votes for the two parts.
Would that be sufficient for you?
Thanks,
Nikita
-----Original Message-----
From: Nikita Popov [mailto:nikita.ppv@gmail.com]
Sent: Friday, June 07, 2013 8:15 PM
To: Dmitry Stogov
Cc: PHP internals
Subject: Re: [PHP-DEV] [RFC] Internal operator overloading and GMP
improvementsIf there is no more feedback on the RFC, then I'll start voting in a day
or two.
I would add that the purpose of this feature would be exclusive to
extensions that implement mathematical concepts, where the operators are
well defined. In other words, arbitrary precision math, vectors,
matrices, etc. - yes; Incrementing or decrementing a picture object to
change the white balance - no.
Zeev
I would add that the purpose of this feature would be exclusive to
extensions that implement mathematical concepts, where the operators are
well defined. In other words, arbitrary precision math, vectors,
matrices, etc. - yes; Incrementing or decrementing a picture object to
change the white balance - no.
This seems like common sense... But just to be sure I added a note (and
your example) at the end of the
https://wiki.php.net/rfc/operator_overloading_gmp#applications_of_operator_overloadingsection
:)
Nikita
It wouldn’t have been the first time that something that seems common
sense, suddenly becomes controversial a few years later J Better safe than
sorry.
I made some changes to the phrasing of the final paragraph in this section
(please review and make sure you’re good with it) – I think the list you
added is great.
Thanks,
Zeev
From: Nikita Popov [mailto:nikita.ppv@gmail.com]
Sent: Saturday, June 08, 2013 3:54 PM
To: Zeev Suraski
Cc: Dmitry Stogov; PHP internals
Subject: Re: [PHP-DEV] [RFC] Internal operator overloading and GMP
improvements
I would add that the purpose of this feature would be exclusive to
extensions that implement mathematical concepts, where the operators are
well defined. In other words, arbitrary precision math, vectors,
matrices, etc. - yes; Incrementing or decrementing a picture object to
change the white balance - no.
This seems like common sense... But just to be sure I added a note (and
your example) at the end of the
https://wiki.php.net/rfc/operator_overloading_gmp#applications_of_operator_overloadingsection
:)
Nikita
It wouldn’t have been the first time that something that seems common
sense, suddenly becomes controversial a few years later J Better safe
than sorry.I made some changes to the phrasing of the final paragraph in this section
(please review and make sure you’re good with it) – I think the list you
added is great.
Looks good. One question though, what do you mean by "cumulativity" in that
context?
Nikita
What I meant by cumulativity in that context is really commutativity J
Fixed (and also added transitivity).
In other words, operands that are commutative in PHP (like addition,
multiplication, etc.) – one should not overload for domains where they’re
not commutative.
Zeev
From: Nikita Popov [mailto:nikita.ppv@gmail.com]
Sent: Sunday, June 09, 2013 4:20 PM
To: Zeev Suraski
Cc: PHP internals
Subject: Re: [PHP-DEV] [RFC] Internal operator overloading and GMP
improvements
It wouldn’t have been the first time that something that seems common
sense, suddenly becomes controversial a few years later J Better safe than
sorry.
I made some changes to the phrasing of the final paragraph in this section
(please review and make sure you’re good with it) – I think the list you
added is great.
Looks good. One question though, what do you mean by "cumulativity" in that
context?
Nikita
What I meant by cumulativity in that context is really commutativity J
Fixed (and also added transitivity).In other words, operands that are commutative in PHP (like addition,
multiplication, etc.) – one should not overload for domains where they’re
not commutative.Zeev
Why? For example matrix multiplication is not commutative, but I would
still consider writing $matrixA * $matrixB a valid application of
overloading. Non-commutative multiplication operations aren't uncommon
(that's why a mathematical ring only requires the addition operator to be
commutative).
The same also applies the other way around: For example PHP's default +
operator is not commutative (when used on arrays) and both + and * are
non-associative and non-distributive (floating point arithmetic), but you'd
probably still expect those properties from an overloaded +/- operator.
That's why I'm not sure it makes sense to have "too strict" definitions for
what is a valid overload and what isn't. I think "limited to cases where
there are clear definitions to the behavior of all overloaded operators"
and "should be for mathematical use cases only" are enough as guidelines :)
Thanks,
Nikita
From: Nikita Popov [mailto:nikita.ppv@gmail.com]
Sent: Sunday, June 09, 2013 5:15 PM
To: Zeev Suraski
Cc: PHP internals
Subject: Re: [PHP-DEV] [RFC] Internal operator overloading and GMP
improvements
What I meant by cumulativity in that context is really commutativity ☺
Fixed (and also added transitivity).In other words, operands that are commutative in PHP (like addition,
multiplication, etc.) – one should not overload for domains where they’re
not commutative.Why?
Mostly because I don't want us to have to worry about this when implementing
the engine. It might side effects on optimizations that are valid when
dealing with standard values - but not when dealing with these complex
values. That said, you brought up a couple of examples where we already
have different behaviors for $a+$b and $b+$a, so this point might be moot
(mostly referring to the array part, I have a harder time accepting the
floating point assertion although I understand why you're saying it...)
That's why I'm not sure it makes sense to have "too strict" definitions
for what is a valid overload and what isn't. I think "limited to cases
where there are clear definitions to > the behavior of all overloaded
operators" and "should be for mathematical use cases only" are enough as
guidelines :)
I guess I can live with that (if nobody has any other additional thoughts on
what we might be missing here). I can say that I mostly heard horror
stories about operator overloading from my old C++ days - which is why I
want us to do our best to avoid creating the same pitfalls in PHP. I do
think that clear extension-level operator overloading support can be quite
useful in some cases though (like gmp/bcmath).
Zeev