# Pipe Operator v2

- Thread: https://externals.io/message/94599
- Original archive: https://news-web.php.net/php.internals/94599
- Started by Sara Golemon on 2016-07-20T23:42:56+00:00
- Messages: 42
- RFC: Pipe Operator (Inactive) — https://externals.io/rfc/pipe-operator.md
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/94599.md?page=2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #94599 — Sara Golemon — 2016-07-20T23:42:56+00:00

URL: https://externals.io/message/94599#94599

With the branching of 7.1, and after some reflection on the previous
feedback, I'd like to reopen discussion of the Pipe Operator RFC
https://wiki.php.net/rfc/pipe-operator which I had previously put on
hold.  I've changed much of the argument wording of the proposal, but
not the substantive feature set.  If you still feel it's unworkable,
I'd like to encourage you to respond with what you think would make it
workable (if anything).  Thanks.

-Sara

---

## #94600 — Thomas Bley — 2016-07-21T00:05:55+00:00

URL: https://externals.io/message/94599#94600 · In reply to: #94599

to me this code is perfectly readable and static code analysis is only complaining about missing semicolons at the end of the lines and short variable names:

$x = loadConfig();
$x = buildDic($x);
$x = getApp($x)
$x = getRouter($x)
$x = getDispatcher($x, $request)
$x = dispatchBusinessLogic($x, $request, new `Response()`)
$x = renderResponse($x)
$x = buildPsr7Response($x)
$response =emit($x);

I'm not sure if there is a ORM or database library out there which constructs SQL queries with non-oop calls, maybe you can give a real-world example.

Regards
Thomas


Sara Golemon wrote on 21.07.2016 01:42:

> With the branching of 7.1, and after some reflection on the previous
> feedback, I'd like to reopen discussion of the Pipe Operator RFC
> https://wiki.php.net/rfc/pipe-operator which I had previously put on
> hold.  I've changed much of the argument wording of the proposal, but
> not the substantive feature set.  If you still feel it's unworkable,
> I'd like to encourage you to respond with what you think would make it
> workable (if anything).  Thanks.
> 
> -Sara

---

## #94601 — Yasuo Ohgaki — 2016-07-21T02:35:05+00:00

URL: https://externals.io/message/94599#94601 · In reply to: #94600

Hi Thomas,


> to me this code is perfectly readable and static code analysis is only complaining about missing semicolons at the end of the lines and short variable names:
>
> $x = loadConfig();
> $x = buildDic($x);
> $x = getApp($x)
> $x = getRouter($x)
> $x = getDispatcher($x, $request)
> $x = dispatchBusinessLogic($x, $request, new `Response()`)
> $x = renderResponse($x)
> $x = buildPsr7Response($x)
> $response =emit($x);
>

I agree the example code is readable, but it makes me feel the
language is a little obsolete.

Many coding standards, if not most, require to have meaningful
variable names even for temp variables.

$response = loadConfig()
   |> buildDic($$)
   |> getApp($$)
   |> getRouter($$)
   |> getDispatcher($$, $request)
   |> dispatchBusinessLogic($$, $request, new `Response()`)
   |> renderResponse($$)
   |> buildPsr7Response($$)
   |> emit($$);


Nice, clean, readable and explicit. i.e. Don't have convert $x is
return value from previous call in programmer's head.

> I'm not sure if there is a ORM or database library out there which constructs SQL queries with non-oop calls, maybe you can give a real-world example.

F# supports function pipelining by |> operator

https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/functions-%5bfsharp%5d#function-composition-and-pipelining

It differs a little, but real world function pipelining examples could
be found in F#/OCaml codes.

Regards,

--
Yasuo Ohgaki
yohgaki@ohgaki.net

---

## #94603 — Larry Garfield — 2016-07-21T03:50:31+00:00

URL: https://externals.io/message/94599#94603 · In reply to: #94599

> With the branching of 7.1, and after some reflection on the previous
> feedback, I'd like to reopen discussion of the Pipe Operator RFC
> https://wiki.php.net/rfc/pipe-operator which I had previously put on
> hold.  I've changed much of the argument wording of the proposal, but
> not the substantive feature set.  If you still feel it's unworkable,
> I'd like to encourage you to respond with what you think would make it
> workable (if anything).  Thanks.
>
> -Sara


I am still generally in favor of this proposal.  Especially when dealing 
with nested array functions this operator would be a big boon to 
readability.


However, the introduction discusses fluent chained methods of objects, 
and states " This RFC aims to improve code readability by bringing 
fluent expressions to functional and OOP libraries not originally 
designed for the task."  The examples, however, all seem to be centered 
around procedural calls.  (A static method call is the same thing as a 
procedural function call in this respect.)  When dealing with methods on 
an object, it seems it wouldn't offer much.


This other recent discussion/proposal for a "Cascade" operator seems 
like it would handle the OOP/method case much better:


http://news.php.net/php.internals/94466


Note: I am not suggesting one is a substitute for the other; rather, 
that they are complementary by addressing different parts of the problem 
space, and the Pipe RFC should likely not emphasize OOP usage potential 
as I see not a great deal there.  I am still in favor of it, but let's 
not over-state its use cases.


PS: I am very disappointed that you chose to name the $$ token 
T_PIPE_VARIABLE and not T_BLINGBLING.


--Larry Garfield

---

## #94604 — Sara Golemon — 2016-07-21T04:29:18+00:00

URL: https://externals.io/message/94599#94604 · In reply to: #94601

> 
> to me this code is perfectly readable and static code analysis is only complaining about missing semicolons at the end of the lines and short variable names:
>
> $x = loadConfig();
> $x = buildDic($x);
> $x = getApp($x)
> $x = getRouter($x)
> $x = getDispatcher($x, $request)
> $x = dispatchBusinessLogic($x, $request, new `Response()`)
> $x = renderResponse($x)
> $x = buildPsr7Response($x)
> $response =emit($x);
>
A proper static analyzer would also not that $x is continuously
changing types, another heave code smell.

> I'm not sure if there is a ORM or database library out there which constructs
> SQL queries with non-oop calls, maybe you can give a real-world example.
>
The third example in the RFC (FBShipIt) shows this exact operator in a
real-world usage in "php-like" code.

-Sara

---

## #94605 — Sara Golemon — 2016-07-21T04:37:31+00:00

URL: https://externals.io/message/94599#94605 · In reply to: #94603

> I am still generally in favor of this proposal.  Especially when dealing
> with nested array functions this operator would be a big boon to
> readability.
>
That's honestly my 90% use-case as well.  array_merge and array_filter
in particular.

> However, the introduction discusses fluent chained methods of objects, and
> states " This RFC aims to improve code readability by bringing fluent
> expressions to functional and OOP libraries not originally designed for the
> task."  The examples, however, all seem to be centered around procedural
> calls.  (A static method call is the same thing as a procedural function
> call in this respect.)  When dealing with methods on an object, it seems it
> wouldn't offer much.
>
In this context, I'd argue instance method calls aren't much different
from static method calls either, but I wanted to avoid too many
abstract/contrived examples.

I suppose one might do something like:

 return $this->loadConfig()
    |> $arg->useConfig($$)
    |> $this->loadUser($$)
    |> array_merge($$, $this->userDefaults);

But the PSR7 example is already contrived as it is.

> This other recent discussion/proposal for a "Cascade" operator seems like it
> would handle the OOP/method case much better:
>
> http://news.php.net/php.internals/94466
>
> Note: I am not suggesting one is a substitute for the other; rather, that
> they are complementary by addressing different parts of the problem space,
> and the Pipe RFC should likely not emphasize OOP usage potential as I see
> not a great deal there.  I am still in favor of it, but let's not over-state
> its use cases.
>
Fair enough.  They certainly complement one another and I wouldn't
argue either is a one-job-fits-all solution.  I wasn't trying to
emphasize OOP usage so much as include it as applicable.  I think we
might actually be agreeing in principle even if we're diverging in our
word choices. :)


> PS: I am very disappointed that you chose to name the $$ token
> T_PIPE_VARIABLE and not T_BLINGBLING.
>
I leave the silly token names to Ze'ev/Andi (T_PAAMAYIM_NEKUDOTAYIM)
and Davey (T_SPACESHIP).

I am nothing if not entirely serious and professional. ;p

-Sara

P.S. - I'm totes going to make that a secondary voting choice now.
Name the token, 50% majority wins.

---

## #94606 — Stefan Neufeind — 2016-07-21T05:59:59+00:00

URL: https://externals.io/message/94599#94606 · In reply to: #94605

> 

[...]

>  return $this->loadConfig()
>     |> $arg->useConfig($$)
>     |> $this->loadUser($$)
>     |> array_merge($$, $this->userDefaults);
> 
> But the PSR7 example is already contrived as it is.
> 
> > […]
> Fair enough.  They certainly complement one another and I wouldn't
> argue either is a one-job-fits-all solution.

[...]

Hi,

Would joining the two be an option?
If $$ is in the parameter-list, use that as the position for the
parameter. If not, use the parameter as first argument?


Kind regards,
 Stefan

---

## #94611 — David Rodrigues — 2016-07-21T12:39:13+00:00

URL: https://externals.io/message/94599#94611 · In reply to: #94603

This is a great idea in general, but I think that this kind of
operator is not the ideal (expect for $$ that seems very good).

Some possibilities to think about:

|> (as suggested) seems strange and not very clear, mainly in linear calls
--> can be too long, but can make more sense or continuing, but can
confuse with simple ->
$> seems like terminal, but can tell like "keep this root-variable and
run it", bad for linear too
<- is short, maybe can tells "call it and return to root-variable", in
linear can be confused with "minus" minus operation ($x<-a())
=> is short, but can be confused why array syntax, but good for linear
.. (like Dart) is short, but can be confused why a (double?) concat,
not seems PHP in general (but still a good option)

Another option is make calls without define an operator, the problem
is that can be not clear or then cause break changes (very bad for
linear).
Or defining a new keyword, but it can be exhaustive or reduce readability.

Should be think about the linear readability too, for instance:
$object->a()->b()->c() vs. $object|>a()|>b()|>c().

Examples: http://pastebin.com/rguUSxDr

It can works to avoid matroska (as initial suggestion) but for objects too.
PHP should identify if this operator is used over object or other type
(that allows the use of $$).
The problem is it can be confused: are you executing an object method
or another function with the object?
Like in: $clockObject |> setHour(12) |> is_string($$). 'is_string' is
from Clock or PHP native function?

Example: http://pastebin.com/t79kjaHQ

---

## #94613 — Rowan Collins — 2016-07-21T13:34:15+00:00

URL: https://externals.io/message/94599#94613 · In reply to: #94611

> This is a great idea in general, but I think that this kind of
> operator is not the ideal (expect for $$ that seems very good).
>
> Some possibilities to think about:
>
> |> (as suggested) seems strange and not very clear, mainly in linear calls
[...]
> Should be think about the linear readability too, for instance:
> $object->a()->b()->c() vs. $object|>a()|>b()|>c().

I think it's quite clear, personally, particularly if you just add a bit 
of whitespace:

$thing |> a($$) |> b($$) |> c($$)

The |> looks kind of like a triangle pointing to the next pipe.



> It can works to avoid matroska (as initial suggestion) but for objects too.
> PHP should identify if this operator is used over object or other type
> (that allows the use of $$).
> The problem is it can be confused: are you executing an object method
> or another function with the object?
> Like in: $clockObject |> setHour(12) |> is_string($$). 'is_string' is
> from Clock or PHP native function?

I think you may be confusing this with the other, somewhat 
complementary, proposal of a "method cascade" operator. Since this 
operator always takes the result of one expression as the input to the 
next, the equivalent for object methods already exists: ->

Your example wouldn't do anything much, because there's no $$ in 
setHour(12), but:

$clockObject -> setHour(12) |> is_string($$)

would be equivalent to:

is_string( $clockObject -> setHour(12) )


That said, if there's a possibility we'll have both features, we need to 
think about how the operators will look next to each other, and how easy 
it will be to pick the right one.

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #94614 — Rowan Collins — 2016-07-21T13:59:46+00:00

URL: https://externals.io/message/94599#94614 · In reply to: #94599

> With the branching of 7.1, and after some reflection on the previous
> feedback, I'd like to reopen discussion of the Pipe Operator RFC
> https://wiki.php.net/rfc/pipe-operator which I had previously put on
> hold.  I've changed much of the argument wording of the proposal, but
> not the substantive feature set.  If you still feel it's unworkable,
> I'd like to encourage you to respond with what you think would make it
> workable (if anything).  Thanks.

It looks like the examples are all still function calls. Could you 
clarify what expressions would be acceptable on the right-hand side?

In particular, can I assign to a variable at the end of the pipe?

foo() |> bar($$) |> $result = $$;

As discussed before, I think pipes would be most useful if values could 
"exit on the right". For which I would also like to be able to do this:

foo() |> bar($$) |> return $$;

(Or, as discussed, special syntax for one or both of these.)

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #94620 — Sara Golemon — 2016-07-21T21:28:12+00:00

URL: https://externals.io/message/94599#94620 · In reply to: #94614

> 
> > […]
>
> It looks like the examples are all still function calls. Could you clarify
> what expressions would be acceptable on the right-hand side?
>
Any non-terminal expression.

> In particular, can I assign to a variable at the end of the pipe?
>
> foo() |> bar($$) |> $result = $$;
>
Sure.  ($result = $$) is an expression which returns the assigned
value, so it's a valid non-terminal.

$alsoResult = foo() |> bar($$) |> $result = $$;
var_dump($alsoResult === $result); // bool(true)

> As discussed before, I think pipes would be most useful if values could
> "exit on the right". For which I would also like to be able to do this:
>
> foo() |> bar($$) |> return $$;
>
Are you picturing the return statement returning from the current
function? Or "returning" from the current pipe chain?

I think you mean the former, in which case I'd ask how that'd better/worse than:

return foo() |> bar($$);

> (Or, as discussed, special syntax for one or both of these.)
>
As above, I don't think special syntax adds anything for either of these cases.

-Sara

---

## #94621 — Rowan Collins — 2016-07-21T21:56:45+00:00

URL: https://externals.io/message/94599#94621 · In reply to: #94620

> Are you picturing the return statement returning from the current
> function? Or "returning" from the current pipe chain?
>
> I think you mean the former, in which case I'd ask how that'd better/worse than:
>
> return foo() |> bar($$);


I do indeed mean returning from the current function. I went into more 
detail (perhaps too much!) on the previous thread, but the basic premise 
is the pipe operator gives you code that reads left to right. Adding an 
element where you have to jump back to the beginning of the expression 
feels like it defeats that.

You picked an example with a very short pipeline, and the "return" is 
fairly obvious; but then "return bar(foo());" is not a great candidate 
for using the operator in the first place. Take a longer example:

return loadConfig()
    |> buildDic($$)
    |> getApp($$)
    |> getRouter($$)
    |> getDispatcher($$, $request)
    |> dispatchBusinessLogic($$, $request, new `Response()`)
    |> renderResponse($$)
    |> buildPsr7Response($$)
    |> emit($$);


If you read through that pipeline, you get down to emit($$), and then 
have to scan back up to figure out where result of that is going to end 
up. Compare:

loadConfig()
    |> buildDic($$)
    |> getApp($$)
    |> getRouter($$)
    |> getDispatcher($$, $request)
    |> dispatchBusinessLogic($$, $request, new `Response()`)
    |> renderResponse($$)
    |> buildPsr7Response($$)
    |> emit($$)
    |> return $$;


Here you can read through all the steps in order, right up to the last 
action, which is returning the resulting value.

Even the name "pipe" is suggesting that something goes in one end, and 
comes out the other, so having the output pop out next to the input just 
feels weird.

Regards,

-- 
Rowan Collins
[IMSoP]

---

## #94624 — Sara Golemon — 2016-07-22T05:52:26+00:00

URL: https://externals.io/message/94599#94624 · In reply to: #94621

> 
> > […]
>
> I do indeed mean returning from the current function. I went into more
> detail (perhaps too much!) on the previous thread, but the basic premise is
> the pipe operator gives you code that reads left to right. Adding an element
> where you have to jump back to the beginning of the expression feels like it
> defeats that.
>
Ah! I understand your point now.  Indeed, in terms of code-scan,
there's something of a whiplash effect going on. Now I understand the
motivation behind $> assignment and/or using a terminal like `return
$$` at the end.

Adding in support for some terminals (like return) could make sense,
it's an exception to a rule, but it's a reasonable looking one (at
first glance, anyway).

The assign to var at the end however, is something I'd rather handle
with the following:

foo() |> bar($$) |> $baz = qux($$);

Which is both legal with the syntax as-is, and entirely readable
without adding an extra operator.

-Sara

---

## #94633 — David Rodrigues — 2016-07-22T15:05:16+00:00

URL: https://externals.io/message/94599#94633 · In reply to: #94624

It's possible to use the tilde ~ easyly on keyboards?
For on BR/ABNT2 is easy. So maybe use ~> as operator could be fine,
instead of the triangle |>, and linear sounds good too, like:
$string~>escape($$)~>dump($$);

It's used currently on PHP for a bitwise operation (not), so I think
that the usage are not a problem in general.
Too will not have a conflict, because ~> no make any sense to PHP today.

2016-07-22 2:52 GMT-03:00 Sara Golemon <pollita@php.net>:
> 
> > […]
> Ah! I understand your point now.  Indeed, in terms of code-scan,
> there's something of a whiplash effect going on. Now I understand the
> motivation behind $> assignment and/or using a terminal like `return
> $$` at the end.
>
> Adding in support for some terminals (like return) could make sense,
> it's an exception to a rule, but it's a reasonable looking one (at
> first glance, anyway).
>
> The assign to var at the end however, is something I'd rather handle
> with the following:
>
> foo() |> bar($$) |> $baz = qux($$);
>
> Which is both legal with the syntax as-is, and entirely readable
> without adding an extra operator.
>
> -Sara
>
> --
> 
> 
>



-- 
David Rodrigues

---

## #94636 — Larry Garfield — 2016-07-22T15:54:31+00:00

URL: https://externals.io/message/94599#94636 · In reply to: #94605

> > […]
> In this context, I'd argue instance method calls aren't much different
> from static method calls either, but I wanted to avoid too many
> abstract/contrived examples.
> 
> I suppose one might do something like:
> 
>  return $this->loadConfig()
>     |> $arg->useConfig($$)
>     |> $this->loadUser($$)
>     |> array_merge($$, $this->userDefaults);
> 
> But the PSR7 example is already contrived as it is.
> 
> > […]
> Fair enough.  They certainly complement one another and I wouldn't
> argue either is a one-job-fits-all solution.  I wasn't trying to
> emphasize OOP usage so much as include it as applicable.  I think we
> might actually be agreeing in principle even if we're diverging in our
> word choices. :)

I agree.  I'm entirely on board with the feature; more just critiquing
the RFC intro text, which mentions OOP fluency as a use case, which I
think is an over-reach.  It's a useful enough feature even without
talking about that, and it seems we agree that the syntax when used with
methods is a bit awkward.

> P.S. - I'm totes going to make that a secondary voting choice now.
> Name the token, 50% majority wins.

:-)

--Larry Garfield

---

## #94643 — Rasmus Schultz — 2016-07-23T11:15:31+00:00

URL: https://externals.io/message/94599#94643 · In reply to: #94636

FWIW, I've read the manual page for the Hack page, and the RFC, a couple of
times now, and I simply don't understand it.

Are most PHP developers going to understand this feature, the meaning of
$$, and when/how to use this?

Are they going to be able to read code written in this way?

To your knowledge, are there any other languages where this feature is
found, or is it another one of those exotic features currently found in
Hack and nowhere else? (I know a bunch of languages, and this feature
doesn't ring any bells.)

How does this feature compare with the cascade operator more commonly found
in other languages?

I mean, maybe it's just me, because I'm familiar with the cascade operator
from other languages - but it seems simpler, more intuitive, easier to pick
up, and appears to solve most of the same problems? If so, perhaps it would
be right to consider the cascade operator as an alternative to this feature.

I know that Hack may be closer in nature to PHP than some other languages,
but if someone is familiar with both, likely they're not coming from Hack
and moving to PHP, they're likely moving from PHP to Hack, so language
similarity might not be the best argument for referencing Hack on this
point, as opposed to referencing other languages...

It seems to me, the main difference between the pipe operator and a cascade
operator, is the anonymous context variable $$ created by the pipe operator
- I think, partially, this is what makes those expression hard to read; the
context changes (or does it?) along the way, but the (nameless) symbol used
to reference those objects, in the same expression, are identical.

Rather than writing extremely long expressions, as demonstrated in the RFC,
I think, personally, if this feature were introduced, I'd lean more on
intermediary variables, with names, that clarify the meaning - referencing
a bunch of intermediaries with a nameless variable doesn't help readability
at all, in my opinion.

In contrast, I have no issue reading expressions with the cascade operator;
again, maybe that's just because I'm familiar with that operator from other
languages, but I don't think the nameless $$ variable helps readability or
understanding.

Just my two cents.


On Fri, Jul 22, 2016 at 5:54 PM, Larry Garfield <larry@garfieldtech.com>
wrote:

> 
>
> > […]
> and
> > […]
> for the
> > […]
> procedural
> > […]
> function
> > […]
> seems it
> > […]
> like it
> > […]
> that
> > […]
> space,
> > […]
> see
> > […]
> over-state
> > […]
>
> I agree.  I'm entirely on board with the feature; more just critiquing
> the RFC intro text, which mentions OOP fluency as a use case, which I
> think is an over-reach.  It's a useful enough feature even without
> talking about that, and it seems we agree that the syntax when used with
> methods is a bit awkward.
>
> > […]
>
> :-)
>
> --Larry Garfield

---

## #94644 — Rowan Collins — 2016-07-23T14:40:14+00:00

URL: https://externals.io/message/94599#94644 · In reply to: #94643

> I mean, maybe it's just me, because I'm familiar with the cascade operator
> from other languages - but it seems simpler, more intuitive, easier to pick
> up, and appears to solve most of the same problems? If so, perhaps it would
> be right to consider the cascade operator as an alternative to this feature.

They're not really the same thing at all; in some ways they're actually 
opposites. The cascade operator is a way of discarding the result of an 
object-oriented expression, and reusing the same context repeatedly. The 
pipe operator is a way of capturing the result of a procedural 
expression, and passing it forward to the next expression.


> It seems to me, the main difference between the pipe operator and a cascade
> operator, is the anonymous context variable $$ created by the pipe operator
> - I think, partially, this is what makes those expression hard to read; the
> context changes (or does it?) along the way, but the (nameless) symbol used
> to reference those objects, in the same expression, are identical.

Yes, the $$ means "result of last expression". In essence, it's a bit 
like Perl's $_ variable, except that it doesn't exist outside the pipe 
syntax. It has to exist to say where you're going to use that result in 
the next expression.

In the cascade operator, you don't need a notation for it, because the 
context is always on the left of the operator:

$foo
     ->>setBar(1) // context is $foo->...
     ->>setBar(2); // context is still $foo->...


But again, this isn't the primary difference between the operators; the 
difference is that one is a way of discarding results, the other is a 
way of carrying results forward.

Regards,

-- 
Rowan Collins
[IMSoP]

---

## #94648 — Rowan Collins — 2016-07-23T15:15:09+00:00

URL: https://externals.io/message/94599#94648 · In reply to: #94624

> Ah! I understand your point now.  Indeed, in terms of code-scan,
> there's something of a whiplash effect going on. Now I understand the
> motivation behind $> assignment and/or using a terminal like `return
> $$` at the end.
>
> Adding in support for some terminals (like return) could make sense,
> it's an exception to a rule, but it's a reasonable looking one (at
> first glance, anyway).

Glad it makes sense. :) I realise "return $$" would have to have some 
special handling, but it would feel more natural to me. I guess the only 
concern is what happens when a pipeline has a return terminal and is 
used in expression context:

$foo = bar() |> baz($$) |> return $$;
// theoretically translates to this invalid PHP:
$foo = return baz(bar());

I'm not sure how easily the compiler would be able to pick up that 
that's an illegal construction.


I was going to say that "yield" would be worth considering at the same 
time, but presumably that's already legal, because yield can appear as 
an expression (to receive variables sent into a co-routine).

It's a shame neither "echo" nor "print" is useful for getting $$ out to 
screen and leaving it unchanged (echo doesn't work in expression context 
at all; print doesn't have a useful return value).


> The assign to var at the end however, is something I'd rather handle
> with the following:
>
> foo() |> bar($$) |> $baz = qux($$);
>
> Which is both legal with the syntax as-is, and entirely readable
> without adding an extra operator.

Yes, on reflection I think "|> $foo = $$" is probably easier to follow 
than extra syntax. I quite like the idea of a whole language where data 
always flows left-to-right, but we're used to that being what assignment 
looks like.

It might be worth coming up with some examples to add to the RFC where 
$$ is used in an expression other than a function call, because I wasn't 
entirely sure when I read it if that was even allowed. It might also 
clear up some of the confusion around this being anything to do with OO.

Off the top of my head, how about some maths:

$foo * $bar
     |> 2 ** $$
     |> sin($$ + 1)
     |> $$ / 20
     |> $result = $$;

Compiles to:

$result = sin((2 ** ($foo * $bar)) + 1) / 20;

Or:

$temp = $foo * $bar;
$temp = 2 ** $temp;
$temp = sin($temp + 1);
$result = $temp / 20;

Regards,

-- 
Rowan Collins
[IMSoP]

---

## #94656 — Stanislav Malyshev — 2016-07-23T20:11:47+00:00

URL: https://externals.io/message/94599#94656 · In reply to: #94601

Hi!

> > […]
> 
> I agree the example code is readable, but it makes me feel the
> language is a little obsolete.

This is a mindset that I feel to be objectionable and take issue with.
The idea that we have to constantly invent new syntax to replace working
old one, just because old is somehow "obsolete", even though new
syntax's only advantage is doing things slightly differently - it seems
to me an exactly wrong idea. It may be exciting to invent new syntaxes -
but for an industry programmer that has other priorities, like code
stability, compatibility, maintainability, etc. "new" is not a positive
things unless it gives them measurable or at least perceivable
improvement on these qualities.

Existing syntax is not "obsolete" and works completely well. New syntax
invents new magic variables (thing that never existed in PHP before,
adding a whole new conceptual level to PHP mental model)  and a new way
of doing the same thing that is already perfectly doable right now with
exactly the same effort. I personally strongly object to such changes.

There is a lot of ways in which PHP needs improvement, but right now I
think inventing more syntax tricks in not one of them. Even in syntax
department, PHP has areas where we could use improvement (e.g. to name
named arguments as one) but this one doesn't seem to do much but doing
the same thing in a shiny new way. Read: less comprehensible for people
not watching "latest new 20 syntaxes PHP invented in the next version",
more things to learn to read PHP code, more things to maintain, more
complexity for the language that once was supposed to be accessible to
beginners.
This is the price of all innovation, but sometimes benefits are much
greater and the price is completely warranted. I do not feel this is the
case here.
-- 
Stas Malyshev
smalyshev@gmail.com

---

## #94658 — Sara Golemon — 2016-07-23T20:46:18+00:00

URL: https://externals.io/message/94599#94658 · In reply to: #94643

> FWIW, I've read the manual page for the Hack page, and the RFC, a couple of
> times now, and I simply don't understand it.
>
Perhaps the documentation needs clarifying then.

> Are most PHP developers going to understand this feature, the meaning of
> $$, and when/how to use this?
>
Yes.  PHP developers are excellent at Google and StackOverflow.

> Are they going to be able to read code written in this way?
>
Yes.

> To your knowledge, are there any other languages where this feature is
> found, or is it another one of those exotic features currently found in
> Hack and nowhere else? (I know a bunch of languages, and this feature
> doesn't ring any bells.)
>
Elixir, F#, Swift (via library extension), ISTR a few others when I
was researching a few months ago, but can't recall them offhand.

> How does this feature compare with the cascade operator more commonly found
> in other languages?
>
To turn your previous question around, what languages?

I see them complementing one another, serving different goals and
solving different problems.  I suppose you could ask how this compares
with short ternaries, coalesce, or bitwise xor, and the question will
make as much sense.

> I mean, maybe it's just me, because I'm familiar with the cascade operator
> from other languages - but it seems simpler, more intuitive, easier to pick
> up, and appears to solve most of the same problems? If so, perhaps it would
> be right to consider the cascade operator as an alternative to this feature.
>
I would rather consider them both since they solve different problems
in different ways.

> I know that Hack may be closer in nature to PHP than some other languages,
> but if someone is familiar with both, likely they're not coming from Hack
> and moving to PHP, they're likely moving from PHP to Hack, so language
> similarity might not be the best argument for referencing Hack on this
> point, as opposed to referencing other languages...
>
Fair point, I'll add mentioned of the above languages to the RFC.

> It seems to me, the main difference between the pipe operator and a cascade
> operator, is the anonymous context variable $$ created by the pipe operator
> - I think, partially, this is what makes those expression hard to read; the
> context changes (or does it?) along the way, but the (nameless) symbol used
> to reference those objects, in the same expression, are identical.
>
It's also what makes the cascade operator unable to solve all the
problems which the pipe operator is capable of solving.  Cascade
applies to a very narrow band of instance method calls.  Pipe applies
best to static methods and procedural functions (which some
applicability to methods).  The flexibility of being able to place
that lhs element in an arbitrary location is what makes it powerful.

> Rather than writing extremely long expressions, as demonstrated in the RFC,
> I think, personally, if this feature were introduced, I'd lean more on
> intermediary variables, with names, that clarify the meaning - referencing
> a bunch of intermediaries with a nameless variable doesn't help readability
> at all, in my opinion.
>
The RFC states why this may not be a preferred course.  How do we
know, at a glance, that these well named intermediates are/aren't used
later in the scope?  What happens to destructor ordering when the
variable lives till the end of the function? How does this impact
optimization potential?

> In contrast, I have no issue reading expressions with the cascade operator;
> again, maybe that's just because I'm familiar with that operator from other
> languages, but I don't think the nameless $$ variable helps readability or
> understanding.
>
You keep acting as if pipe vs cascade is even a competition.  It's
not.  They're different solutions to different problems which require
different approaches.

-Sara

---

## #94659 — Sara Golemon — 2016-07-23T20:49:47+00:00

URL: https://externals.io/message/94599#94659 · In reply to: #94648

> Glad it makes sense. :) I realise "return $$" would have to have some
> special handling, but it would feel more natural to me. I guess the only
> concern is what happens when a pipeline has a return terminal and is used in
> expression context:
>
> $foo = bar() |> baz($$) |> return $$;
> // theoretically translates to this invalid PHP:
> $foo = return baz(bar());
>
> I'm not sure how easily the compiler would be able to pick up that that's an
> illegal construction.
>
Right, which is where I'm hesitant to go down that road.

> I was going to say that "yield" would be worth considering at the same time,
> but presumably that's already legal, because yield can appear as an
> expression (to receive variables sent into a co-routine).
>
Yep.  Perfectly valid as-is, so a non-issue.

> It's a shame neither "echo" nor "print" is useful for getting $$ out to
> screen and leaving it unchanged (echo doesn't work in expression context at
> all; print doesn't have a useful return value).
>
Yeah, those pegs really don't fit into this hole...

> It might be worth coming up with some examples to add to the RFC where $$ is
> used in an expression other than a function call, because I wasn't entirely
> sure when I read it if that was even allowed. It might also clear up some of
> the confusion around this being anything to do with OO.
>
> Off the top of my head, how about some maths:
>
> $foo * $bar
>     |> 2 ** $$
>     |> sin($$ + 1)
>     |> $$ / 20
>     |> $result = $$;
>
> Compiles to:
>
> $result = sin((2 ** ($foo * $bar)) + 1) / 20;
>
> Or:
>
> $temp = $foo * $bar;
> $temp = 2 ** $temp;
> $temp = sin($temp + 1);
> $result = $temp / 20;
>
Fair point, I took those as a given, but they should be added. (And
yes, they're valid).

-Sara

---

## #94660 — Sara Golemon — 2016-07-23T20:54:28+00:00

URL: https://externals.io/message/94599#94660 · In reply to: #94656

> There is a lot of ways in which PHP needs improvement, but right now I
> think inventing more syntax tricks in not one of them. Even in syntax
> department, PHP has areas where we could use improvement (e.g. to name
> named arguments as one) but this one doesn't seem to do much but doing
> the same thing in a shiny new way. Read: less comprehensible for people
> not watching "latest new 20 syntaxes PHP invented in the next version",
> more things to learn to read PHP code, more things to maintain, more
> complexity for the language that once was supposed to be accessible to
> beginners.
> This is the price of all innovation, but sometimes benefits are much
> greater and the price is completely warranted. I do not feel this is the
> case here.
>
I just want to make sure you know that I 100% respect your feelings on
this RFC.  I can't comprehensively argue against them, so I won't try.
I'll only say that I don't expect to see |> in rampant use in the next
two years, maybe not in five.  But that's okay, because that feature
will (I hope) be there for private codebases soon, and public
codebases later, and I believe it will make code more readable.

-Sara

---

## #94706 — bjorn.x.larsson@telia.com — 2016-07-25T14:52:09+00:00

URL: https://externals.io/message/94599#94706 · In reply to: #94633

Den 2016-07-22 kl. 17:05, skrev David Rodrigues:

> It's possible to use the tilde ~ easyly on keyboards?
> For on BR/ABNT2 is easy. So maybe use ~> as operator could be fine,
> instead of the triangle |>, and linear sounds good too, like:
> $string~>escape($$)~>dump($$);
>
> It's used currently on PHP for a bitwise operation (not), so I think
> that the usage are not a problem in general.
> Too will not have a conflict, because ~> no make any sense to PHP today.
There was an RFC proposing that operator for short closures, see:
- https://wiki.php.net/rfc/short_closures

Recall that the operator was a bit controversial due to
e.g. japanese keyboard. Personally I liked the proposal
and I think the "pipe" sign fit well into an pipe operator:)

Regards //Björn Larsson

---

## #97864 — Joe Watkins — 2017-01-19T05:55:45+00:00

URL: https://externals.io/message/94599#97864 · In reply to: #94706

Morning Sara,

This has generated some very decent discussion.

It seems like time to put this to a vote, could you maybe find some time to
do that please ?

Alternatively, if  there are outstanding issues that are stopping this
going to a vote, could we know what they are, and maybe your plan to
resolve them ?

Cheers
Joe

On Mon, Jul 25, 2016 at 3:52 PM, Björn Larsson <bjorn.x.larsson@telia.com>
wrote:

> Den 2016-07-22 kl. 17:05, skrev David Rodrigues:
>
> It's possible to use the tilde ~ easyly on keyboards?
> > […]
> There was an RFC proposing that operator for short closures, see:
> - https://wiki.php.net/rfc/short_closures
>
> Recall that the operator was a bit controversial due to
> e.g. japanese keyboard. Personally I liked the proposal
> and I think the "pipe" sign fit well into an pipe operator:)
>
> Regards //Björn Larsson

---

## #97868 — Yasuo Ohgaki — 2017-01-19T10:24:20+00:00

URL: https://externals.io/message/94599#97868 · In reply to: #94706

On Mon, Jul 25, 2016 at 11:52 PM, Björn Larsson <bjorn.x.larsson@telia.com>
wrote:

> Den 2016-07-22 kl. 17:05, skrev David Rodrigues:
>
> It's possible to use the tilde ~ easyly on keyboards?
> > […]
> There was an RFC proposing that operator for short closures, see:
> - https://wiki.php.net/rfc/short_closures
>
> Recall that the operator was a bit controversial due to
> e.g. japanese keyboard. Personally I liked the proposal
> and I think the "pipe" sign fit well into an pipe operator:)


I'm surprised someone noticed Japanese "~" char issue.
We have "~" char issue, but it would not be problem for programmers.

I guess you mentioned this issue.
https://ja.wikipedia.org/wiki/%E6%B3%A2%E3%83%80%E3%83%83%E3%82%B7%E3%83%A5
http://qiita.com/kasei-san/items/3ce2249f0a1c1af1cbd2
They are written in Japanese. Please use google translate or similar.

Wrongly configured keyboard could be another problem. We may ignore such
environment.

Regards,

--
Yasuo Ohgaki
yohgaki@ohgaki.net

---

Next page: https://externals.io/message/94599.md?page=2
