Skip to content

Add corresponding functions for basic operators #2738

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from

Conversation

hikari-no-yume
Copy link
Contributor

@hikari-no-yume hikari-no-yume commented Sep 5, 2017

Draft RFC: https://wiki.php.net/rfc/operator_functions

For every operator in PHP that operates only on expressions (full list below), this patch adds a corresponding function in the root namespace. This means you can then pass those operators by name to higher-order functions (or even call them directly if you're weird), e.g.:

// negate all the things
$negatives = array_map('-', $positives);
// build your own array_sum()
$sum = array_reduce($terms, '+', 0);
// Like regular sort()
$sorted = usort($unsorted, '<=>');
// please help i'm trapped in the wrong language how do i escape back to lisp
$distance = sqrt('+'('**'('-'($x1, $x2), 2), '**'('-'($y1, $y2), 2)));

These examples aren't that exciting, of course, but they demonstrate the idea: having all the basic operators be functions means you can pass them to higher-order functions.

This becomes particularly useful if you have a partial application primitive (alas PHP doesn't have one built-in right now, but you can write your own), as then you can do more complex things, e.g.:

// square all the things
$squared = array_map(partialApply('**', 2), $terms);
// select only the positive numbers
$positiveSubset = array_filters($numbers, partialApply('>', 0));

And of course that becomes more useful still if you have a function composition primitive.

Operators in the current patch:

+ - * / % ** & | ^ ~ << >> == === != <> !== < > <= >= <=> && and || or xor ! .

Possibly notable omissions:

[] ->

Also, none of the assignment operators (+= etc) are included, though given references exist they could be added.

@lstrojny
Copy link
Contributor

lstrojny commented Sep 5, 2017

OMG yes. So much yes.

@hikari-no-yume
Copy link
Contributor Author

hikari-no-yume commented Sep 5, 2017

Test failure unrelated to patch, I think.

@nikic nikic added the RFC label Sep 5, 2017
@laruence
Copy link
Member

laruence commented Sep 6, 2017

I like this idea... :)

just I don't like codes like:

+(1, 2);
-(3, 1)
<=>(3, 4)

could we forbid them being called directly?

@timurib
Copy link
Contributor

timurib commented Sep 6, 2017

@laruence Why forbid? Just suppose we need to invoke a dynamic expressions. A simple "calculator" for example. Currently we should write something like this:

// just for example, don't do it:
function calculate(string $func, float ...$args)
{
    if (count($args) === 1 && ($func === '+' || $func === '-')) {
        return eval($func . $args[0]);
        
    } elseif (in_array($func, '+', '-', '*', '/')) {
        return eval(join($func, $args));
        
    } elseif (...) {
        // And a bunch of other special cases...
        
    } else {
        return $func(...$args);
    }
}

If we have the unified syntax for regular functions and operators then code above can be written much easier:

function calculate(string $func, float ...$args)
{
    return $func(...$args);
}

This feature may be useful for template engines, code generation, DSL parsers, preprocessors, etc.

@hikari-no-yume
Copy link
Contributor Author

@laruence Some kind of hack could be added to the Zend Engine to prevent calling these functions directly, but I don't see the benefit. All other functions can be called directly, and there might end up being a case where this is useful.

@laruence
Copy link
Member

laruence commented Sep 6, 2017

hmm, fair enough... then I have no problem . thanks

@laruence
Copy link
Member

laruence commented Sep 6, 2017

@hikari-no-yume please also update ext/opcache/Optimizer/zend_func_info.c if possible.

@hikari-no-yume
Copy link
Contributor Author

@laruence Okay, I'll do that. While you're around: do you see any problem with moving these functions into Zend from ext/standard?

@laruence
Copy link
Member

laruence commented Sep 6, 2017

I feel ext/standard is more suitable, for standard builtin functions, no need in Zend..

@hikari-no-yume
Copy link
Contributor Author

Of course, but ext/standard already contains a huge number of functions, and since all these new functions are thin wrappers around stuff in zend_operators.c anyway, it would be nice to keep everything in one place.

@nikic
Copy link
Member

nikic commented Sep 6, 2017

Please do not define PHP functions in zend_operators.c. If you want to move these into Zend/ they should go into zend_builtin_functions.c. The fact that ZEND_NAMED_FUNCTION is not yet defined there should have been a hint that this code does not belong there ;)

@hikari-no-yume
Copy link
Contributor Author

hikari-no-yume commented Sep 6, 2017

@nikic I did wonder about that; fair enough, I'll move it :)

@hikari-no-yume hikari-no-yume force-pushed the operator_functions branch 3 times, most recently from 8bbb104 to 0f3a68b Compare September 6, 2017 19:42
@ghost
Copy link

ghost commented Dec 10, 2017

@laruence Why not rename them rather than restrict? "operator_bitwise_and" has a lot more readability than "&" which can be confused with "&&". Also, "&&" and "and" are then same "zend_operator_boolean_and", so why define twice?

Adding 1-3 character functions just pollutes the global scope and makes possible to write confusing things like $a = (+(1,2)+2--(1,2)), which is equal to $a = (1+2+2-(1-2));

With a rewite, that could be $a = operator_add(1,2) + 2 - operator_subtract(1,2)

@cmb69
Copy link
Member

cmb69 commented Mar 30, 2021

@hikari-no-yume, are you planning to pursue the RFC?

@hikari-no-yume
Copy link
Contributor Author

@cmb69 I could revive it, though now that short functions are in the language, it seems less likely to succeed. I guess I should ask if anyone still cares.

@hikari-no-yume
Copy link
Contributor Author

Going to close this for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants