Remix.run Logo
gbalduzzi 8 days ago

I like it.

I really believe the thing PHP needs the most is a rework of string / array functions to make them more consistent and chain able. Now they are at least chainable.

I'm not a fan of the ... syntax though, especially when mixed in the same chain with the spread operator

account42 7 days ago | parent | next [-]

The syntax could be improved by allowing you to omit the (...) part entirely for single argument functions and using currying for functions that need additional arguments. So you would end up with something like:

  $result = $arr
      |> select_column('tags')         // Gets an array of arrays
      |> fn($x) => array_merge(...$x)  // Flatten into one big array
      |> array_unique                  // Remove duplicates
      |> array_value                   // Reindex the array.
noduerme 8 days ago | parent | prev | next [-]

Agree, the ... syntax feels confusing when each fn($x) in the example uses $x as the name of its argument.

My initial instinct would be to write like this:

`$result = $arr

    |> fn($arr) => array_column($arr, 'tags') // Gets an array of arrays

    |> fn($cols) => array_merge(...$cols)`
Which makes me wonder how this handles scope. I'd imagine the interior of some chained function can't reference the input $arr, right? Does it allow pass by reference?
cess11 8 days ago | parent | next [-]

You can do

     function ($parameter) use ($data) { ... }
to capture stuff from the local environment.

Edit: And you can pass by reference:

   > $stuff = [1]
   = [
       1,
     ]

   > $fn = function ($par) use (&$stuff) { $stuff[] = $par; }
   = Closure($par) {#3980 …2}

   > $fn(2)
   = null

   > $stuff
   = [
       1,
       2,
     ]

Never done it in practice, though, not sure if there are any footguns besides the obvious hazards in remote mutation.
noduerme 5 days ago | parent [-]

idk if it counts as an obvious hazard, but being able to modify the original input by reference within a chain of piped functions definitely makes it a lot harder to reason about what that sequence might be doing. Particularly since we assume that arrays are passed by reference anyway unless the function you're calling is making a shallow copy of their elements.

My feeling is that this makes the code less legible. I'd rather write 5 lines of code that mutate an object or return a copy than do a pipe this way. I'm sort of not excited to start running into examples of this in the wild.

Einenlum 8 days ago | parent | prev [-]

You can write it this way. The parameter name is arbitrary. And no, to my knowledge you can't access the var from the previous scope

colecut 8 days ago | parent | prev [-]

PHP string / array functions are consistent.

string functions use (haystack, needle) and array functions use (needle, haystack)

because that's the way the underlying C libraries also worked

Einenlum 8 days ago | parent | next [-]

They're not though.

array_filter takes (arr, callback)

https://www.php.net/manual/en/function.array-filter.php

array_map takes (callback, arr)

https://www.php.net/manual/en/function.array-map.php

goykasi 7 days ago | parent | next [-]

array_map is variadic. It is actually (callback, ...arr)

One function works against a single element, whereas the other works against multiple. In that case, the parameter order is more meaningful. You can use array_walk if you want (arr, callback), but that only works against a single array -- similarly to array_filter.

exasperaited 8 days ago | parent | prev [-]

This is "english-sentence-order-consistent", as it goes.

Array filter is "filter this array with this function".

Array map is "map this function over this array".

But I agree any replacement function should be consistent with Haskell.

eurleif 8 days ago | parent | next [-]

One can construct English sentences in the opposite order. There is no singular "English sentence order".

"Filter for this function in this array"

"Map over this array with this function"

goykasi 7 days ago | parent | next [-]

But thats not correct. array_map is variadic. So it should actually be "Map over these arrays with this function."

When you use the correct verbiage, the parameter order makes sense.

exasperaited 8 days ago | parent | prev [-]

Right, but these are both more unwieldy.

One filters something with something else, in the real world. Filter water with a mesh etc.

And (in maths, at least) one maps something onto something else. (And less commonly one maps an area onto paper etc.)

Just because you can make your two sentences does not make them natural word order.

quietbritishjim 7 days ago | parent | next [-]

> And (in maths, at least) one maps something onto something else.

Yes, but that's the opposite of what you said earlier. You might map x onto 2*x, for example. Or, if you're talking about a collection, you might map the integers 0..10 on to double their value. Data first, then the way you're manipulating it. I'm a mathematician and this is what makes sense to me.

I would only say "map this function..." if the function itself is being manipulated somehow (mapped onto some other value).

hnlmorg 8 days ago | parent | prev [-]

When you consider that PHP is used by hundreds of thousands of non-native English speakers, I don’t really think you can make a legitimate claim that “English sentence order” trumps “consistent argument ordering”.

There’s enough viral videos online of how even neighbouring European counties order common sentences differently. Even little things like reading the time (half past the previous hour vs half to the next hour) and counting is written differently in different languages.

So modelling the order of parameters based on English vernacular doesn’t make a whole lot of sense for programming languages used by programmers of all nationalities.

7 days ago | parent | next [-]
[deleted]
exasperaited 7 days ago | parent | prev [-]

> When you consider that PHP is used by hundreds of thousands of non-native English speakers, I don’t really think you can make a legitimate claim that “English sentence order” trumps “consistent argument ordering”.

Well that’s good, because I didn’t.

8 days ago | parent | prev [-]
[deleted]
Y-bar 8 days ago | parent | prev | next [-]

> because that's the way the underlying C libraries also worked

I feel like this is a weak defence of the internally inconsistent behaviour. As someone who has been programming with PHP for over twenty years now, most of them professionally, I still cannot remember the needle/haystack order in these functions, I thank intellisense for keeping me sane here.

As evident with this pipe operator, or with for example Attributes, PHP does not need to religiously follow the C way of doing things, so why not improve it instead of dismissing it as "it is the way it is because that is the way it was"?

chuckadams 7 days ago | parent [-]

It's not so much a defense as it is an explanation of the historical origins. Even the creator of the language doesn't defend the inconsistencies and admits that they were a mistake. PHP also takes backward compatibility pretty seriously and doesn't rearrange things for consistency's sake alone.

account42 7 days ago | parent | prev | next [-]

So they are consistent because they are consistently inconsistent??

There isn't a good reason for PHP to have inherited C's issues here.

goykasi 7 days ago | parent [-]

In the early days of PHP, it relied heavily on wrapping the underlying C libraries and preserving their naming conventions.

https://news-web.php.net/php.internals/70950

gbalduzzi 7 days ago | parent [-]

And that was fine in the early days, absolutely.

We are not in the early days though, and in many other aspects PHP evolved greatly.

goykasi 7 days ago | parent [-]

What are the benefits? Code completion, AI agents, etc will handle it for you. No one's life is falling apart because the param ordering is more similar to C than a blog article complaining about it decade ago. Php devs have had up 30 years to learn the difference. Are C devs complaining about this?

If we want to change the param order of str/array functions for php, I think we should start with fixing the C libraries. That seems like a better starting point. The impact will certainly be more beneficial to even more developers than just php.

gbalduzzi 7 days ago | parent [-]

Because it would be more predictable, easier to memorize, less verbose, easier to use for developers coming from other modern languages and more comfortable to work with.

The fact that they are chaotic since 30 years ago is not a valid reason for keeping them chaotic right now.

Also, I'm not even arguing they should change the existing functions, that would break all existing code for almost no reason.

I think they should "simply" support methods on primitives, and implement the main ones in a chainable way:

"test string"->trim()->upper()->limit(100);

[0,1,2]->filter(fn ($n) => $n % 2 === 0)->map(fn($n) => $n * 2);

I would love this so much

gbalduzzi 7 days ago | parent | prev [-]

`strlen`, `strncmp` and `strtolower` but `str_split` and `str_contains`.

How it that consistent?