Hi Larry Garfield,

> Request:
>
> push() and unshift() currently return void.  That's not helpful.  It would be 
> vastly more useful if they both returned $this.  Not as much for chaining, 
> but more so that you can add a value to a queue and pass it as an argument to 
> another call (often recursive, but not necessarily) in a single operation.
>
> Example: I was doing last year's Advent of Code in functional PHP, and had a 
> stack walker that looked like this:
>
> function parse(string $line, $pos = 0, array $stack = []): Result|string
> {
>     $next = $line[$pos] ?? null;
>     $head = $stack[0] ?? null;
>
>     return match ($next) {
>         // Opening brace, push an "expected" onto the stack.
>         '{' => parse($line, $pos + 1, ['}', ...$stack]),
>         '<' => parse($line, $pos + 1, ['>', ...$stack]),
>         '(' => parse($line, $pos + 1, [')', ...$stack]),
>         '[' => parse($line, $pos + 1, [']', ...$stack]),
>         '}', '>', ')', ']' => $next === $head ? parse($line, $pos + 1, 
> array_slice($stack, 1)) : $next,
>         null => count($stack) ? Result::Incomplete : Result::OK,
>     };
> }
>
> The interesting part is the ['<', ...$stack], to pass on a modified version 
> of an array-as-stack.  That's of course annoyingly slow with arrays right 
> now, and a Deque would be better, but only if it could be "modified and 
> passed" like that.  If not, it would be incompatible with single-expression 
> usages (match statements, short lambdas, etc.)
>
> Returning $this would resolve that, I think.  (Making it return a new, 
> immutable copy of the Deque would be even nicer, but I realize that's 
> probably not an argument I'm going to win at this point on this RFC.)

Technically, you still can have single-expression usages in readable/unreadable 
ways

- `[$deque->shift('value'), $deque][1]`, or
- `($deque->shift('value') ?: $deque)`, or
- `my_userland_helper_shift_and_return($deque, 'value')`

My personal preference is against making this fluent.
I'd rather expose an efficient datastructure that's consistent with the rest of 
PHP's functionality to the extent possible,
which userland can use to write their own fluent/non-fluent classes.
There's drawbacks to returning `$this`, including:

1. Inconsistency with existing APIs making remembering what does what harder. 
Barely anything in php that I remember returns $this.

   https://www.php.net/manual/en/arrayobject.append.php returns void.

   https://www.php.net/manual/en/function.array-push returns an int.
2. Inconsistency with possible new datastructures/methods

   If a `Map`/`Set` function were to be added, then methods for add/remove 
would return booleans (or the old value), not $this

3. Slight additional performance overhead for functionality I assume will be 
used relatively infrequently

   (php has to increment reference counts and opcache can't eliminate the 
opcode to decrease reference counts and possibly free the return value of 
`$deque->shift()` with the return type info being an object)
4.  Returning $this makes code easier to write at some cost to readability - 
Developers new to php or using `Collections\Deque` for the first time would not 
immediately know what the code they're reading is doing.
   (less of a problem with a good IDE, typechecker, and a typed codebase, but 
this isn't universal)
   Having it return void, `return $deque->push()` would be less common and this 
would force the meaning to be clear.

   Developers might have several guesses/assumptions based on their experience 
with other methods in php/elsewhere

   - It returns the new count (JavaScript Array.push, array_push)
   - It returns $this (Ruby)
   - It returns a lazy copy, like you'd wanted, not modifying the original
   - It's returning void and the code in question is shorthand for `return 
null`.
     (Python, C++ https://www.cplusplus.com/reference/vector/vector/push_back/ 
, offsetSet and spl push()/shift() methods)

> Also, typo:
>
> "By introducing a data structure (Deque) that's even faster and more memory 
> usage than an array for use as a double-ended queue, even more applications 
> would benefit from it. "
>
> I think you mean "less memory usage", or possibly "more memory efficient", or 
> something like that.

Thanks, I've fixed that.

Thanks,
Tyson

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

Reply via email to