trad trad - 5 months ago 20
Javascript Question

Why does the function signature differ between array_map and array_filter/array_reduce?

array_map
asks for the
$array
input as the last parameter(s).
array_filter
and
array_reduce
take
$array
input as the first parameter. As a contrasting example, when you call map, filter or reduce on an array in JavaScript, the callback function signatures look like

(current, index, array) => {…}


Array.prototype.reduce
takes the carryover value as the first parameter, but it is still impossible to mix up the parameters' order in the JavaScript methods.

I know that PHP isn't functionally-oriented, but I'm wondering what the design decisions were leading to the signatures for
array_map
etc.

Does
array_map
take an array as the last parameter simply because you can feed as many arrays as you want (variadic)? Does the ability to feed an arbitrary number of arrays through the callback function of
array_map
outweigh having more uniform function signatures?

EDIT/ Comment:

from Wikipedia, this puts in perspective just how long PHP has been evolving:


'Early PHP was not intended to be a new programming language, and grew
organically, with Lerdorf noting in retrospect: "I don’t know how to
stop it, there was never any intent to write a programming language
[…] I have absolutely no idea how to write a programming language, I
just kept adding the next logical step on the way." A development team
began to form and, after months of work and beta testing, officially
released PHP/FI 2 in November 1997. The fact that PHP was not
originally designed but instead was developed organically has led to
inconsistent naming of functions and inconsistent ordering of their
parameters.
In some cases, the function names were chosen to match the
lower-level libraries which PHP was "wrapping", while in some very
early versions of PHP the length of the function names was used
internally as a hash function, so names were chosen to improve the
distribution of hash values.'

Answer

Does array_map take an array as the last parameter simply because you can feed as many arrays as you want (variadic)?

Yes; only the last parameter in a method signature can be variadic.

Does the ability to feed an arbitrary number of arrays through the callback function of array_map outweigh having more uniform function signatures?

Essentially, this is asking if array_map should accept multiple arrays. There are good use cases for allowing for calling array_map with multiple arrays; below is an example from the PHP array_map guide that I've slightly modified:

<?php
function showLanguages($n, $s, $g)
{
    return("The number $n is called $s in Spanish and $g in German.");
}

$a = array(1, 2, 3, 4, 5);
$b = array("uno", "dos", "tres", "cuatro", "cinco");
$c = array("eins", "zwei", "drei", "vier", "funf");

$d = array_map("showLanguages", $a, $b, $c);
print_r($d);

What if array_map were changed to have a multidimensional array as the first argument? While it would technically make the function signatures more uniform, it would actually add some additional problems.

The underlying code would not only have to validate that the first argument is an array, it would have to validate that it's an array of arrays. That would make it essentially be a different kind of parameter than just an array, so it would still be a different method signature than the other array_* methods.

If you really wanted to have the callback as the last argument, you could use a modified function that removes the last element, move it to the first argument, then call array_map on that. You would lose all type-hinting, though, so it'd be harder to use.

/*
 * Accepts a variable number of arrays as the first N arguments, takes a callback as the last argument
 */
function map()
{
    $args = func_get_args();

    $callback = array_pop($args);

    array_unshift($args, $callback);

    return call_user_func_array("array_map", $args);
}
Comments