Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: add !> pipe-like operator #35770

Closed
wants to merge 1 commit into from

Conversation

Roger-luo
Copy link
Contributor

@Roger-luo Roger-luo commented May 6, 2020

This is probably related to #25233 and #34340 but simpler I guess. and I think this is quite consistent with Julia's own naming convention. But I'm not sure if this would cause ambiguity. Currently |> will return a function due to the method !(f::Function) = (xs...)->!f(xs...), but I feel this is quite duplicated with < anyways.

TL;DR

Currently, we only have one pipe operator, and the |> is overloaded in Base to be a sugar for function calls. However, in the case that a callable object has side effects, the developers will not be able to force their users to name the variable name with a postfix !, thus the side effect will not be explicit. One option is to not define the callable method for the object, but instead, define !> operator if the pipe is used more often in the API

Example

Originally assume we have an object defined as following

abstract type AbstractMyObject end

struct MyObject <: AbstractMyObject
   # blabla
end

apply!(r, x::MyObject) = # mutates r

since there could be a few different kinds of this object MyObject1, MyObject2, and they may take different properties, we can easily have a chain of these calls but with side effect. So it's natural to define

|>(r, x::MyObject) = apply!(r, x)

and let users write

r |> x1 |> x2 |> x3

where x1, x2, x3 are instances of MyObject or other subtypes of AbstractMyObject. However, this API drops the ! on the pipe operator, so if we have !>, we can just define

!>(r, x::MyObject) = apply!(r, x)

and users will have to write

r !> x1 !> x2 !> x3

which is way more explicit.

Use cases

This idea is motivated by the blocks defined in Yao. Each block in Yao defines a quantum gate/circuit that acts on a quantum register. However, by the non-cloning theorem, one is not allowed to copy the register by physics law, thus all the operations on the register will and have to be in place. And it is very natural to let users use pipe operator to define a long quantum circuit, e.g r |> H |> H |> H |> X |> Y etc. I think it'd be nice if we could use !> instead of |>. The implicit side effect API is currently a few of our users complain about making it easier to write bugs, but we cannot easily drop this pipe API since it plays a key role in our API and really simplifies a lot things.

I think @GiggleLiu also has some use cases in reversible programming, not sure if @tkf has any comments, I came across from your reply on discourse. and in case if anyone is interested on discourse post: https://discourse.julialang.org/t/parse-pip-operator-for-side-effect-calls/38857/6

@tkf
Copy link
Member

tkf commented May 6, 2020

Thanks for the write-up. I think switching pure/mutating behavior of the function/callable based on the pipe operator is a good motivating example.

But I think this is a dup of #34344 so I think it's better to merge the effort there. In #34344, |>> was suggested as the name of this function. I suggested |!> in #34340 for this.

@Roger-luo
Copy link
Contributor Author

Oh I didn't notice |!> is proposed already. It's exactly what I'm looking for. I'll join the other issue/PR then. Closing this.

@Roger-luo Roger-luo closed this May 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants