On 17/05/2016 18:46, Sara Golemon wrote:
On Tue, May 17, 2016 at 4:14 AM, Rowan Collins > <rowan.coll...@gmail.com> wrote: >> On 17/05/2016 11:55, Jesse
Schalken wrote: $id |> >> StringList::decode($$) |> array_replace($$,
$replace) |> >> StringList::encode($$) |> $id; >> >> >> Sara, what do
you think of this tweak, and my subsequent suggestion >> that the pipe
should only be usable as a *statement*, not an >> *expression*? >> > I'm
not strictly against it, but I'm not a huge fan. Primarily, > it's the
statement-only restriction that bothers me since (apart > from control
flow structures), most constructs in PHP are > expressions, not
statements, and this feature naturally fits in the > composable
expressions category, not the top-level statement > category.
A perfectly reasonable position. I guess my counter-argument would be
that this is a kind of control flow, a "do-this and-then do-this". But
mostly the suggestion to restrict was to have one right way of laying
things out, rather than allowing people to make it even harder to follow
by mixing nesting with pipes, for instance.
From an implementation standpoint, I'm fairly confident that the > patch would be much more complex as a result of enforcing that >
statement-only requirement.
Ah, I did wonder if that would be the case, and I don't think it would
be worth pushing in that complexity.
Meanwhile, if we remove the statement-only requirement, then using > "simple-variable" as a signal to switch to expression termination, >
then we introduce a whole class of bug where a user fat-fingers the > $$
token in what SHOULD be another link in a chain expression, but > it's
not detectable as an error because a simple-var is valid. > > And one
more counter-example: > > $x |> foo($$) |> $y[$$];
My original suggestion was to have a different token for the terminating
assignment, such as "|=>" (looks a bit prettier than "|>="). That would
get rid of any such ambiguity.
If we keep the pipe as an expression, I guess the assignment can return
its value like a plain "=" would; so:
$foo
|> operation($$)
|=> $foo;
would be extra sugar for:
$foo
|> operation($$)
|> $foo = $$;
Incidentally, the RFC would benefit from a couple of examples of using
something other than a function call as the RHS of the "|> "
And you could even use it mid-pipe, as a kind of "tee":
buildRequest() // (basically the first part of the previous example here)
|> validate($$)
|> convertToCommand($$)
|=> $command
|> execute($$)
|> convertToViewModel($$)
|> render($$)
|> convertToHttpResponse($$)
|> emit($$)
|=> $response;
$command
|> censorCommand($$)
|> logEvent($$);
The other special case that's trickier to incorporate if the pipe acts
as an expression is returning from a function. I presume "return $$"
would be an error, unless it's given special status, which is a shame...
scandir($arg)
|> array_filter($$, function($x) { return $x !== '.' && $x != '..'; })
|> array_map(function ($x) use ($arg) { return $arg . '/' . $x; }, $$)
|> getFileArg($$)
|> array_merge($ret, $$)
|> return $$
You mention in the RFC that the source of the data going through the
chain is "clear and unambiguous"; I think it would be great if the
*destination* of the data were equally clear. For instance, a subtle
edit to your example:
($ret = scandir($arg)
|> array_filter($$, function($x) { return $x !== '.' && $x != '..'; })
|> array_map(function ($x) use ($arg) { return $arg . '/' . $x; }, $$))
|> getFileArg($$)
|> array_merge($ret, $$)
|> $output->append($$);
At a glance, what would you expect in $ret after that code runs?
I guess this falls close to the "stopping people writing horrible code"
fallacy, but what I'm interested in is what the good code should look like:
scandir($arg)
|> array_filter($$, function($x) { return $x !== '.' && $x != '..'; })
|> array_map(function ($x) use ($arg) { return $arg . '/' . $x; }, $$)
|=> $ret
|> getFileArg($$)
|> array_merge($ret, $$)
|> $output->append($$);
Regards,
--
Rowan Collins
[IMSoP]
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php