|>=, piping update operator

Using SymPy.jl for a little bit I ended up wanting to do something like this

using SymPy
@syms x y
x = cos(y)^2 + sin(y)^2
x |>= simplify

i.e. using a piped updating operator. Could this be possible, and if not, why?

Chain.jl is close

x = @chain begin 
    cos(y)^2 + sin(y)^2
    simplify 
end
1 Like

Thanks, though I’m not really trying to find a workaround, writing x=simplify(x) is not so much effort after all. I was wondering what keeps this syntactic sugar from being there.

It seems like it would be possible — it is currently a syntax error, so adding it would be non-breaking.

1 Like

Visually, I am a bit concerned. The |> operator suggests that information is travelling toward the r.h.s. of the operator—bit in this constellation |>= would actually update the l.h.s.

It might by more readable if instead of the pipe operator it was using an “apply to” / “mutate” operator

True, it’s easy to write that. I understand you speculating about a syntax change, but it’s still worth emphasizing how useful a macro might be here.

julia> macro update(x,y)
           esc(update_helper(x, y))
       end;

julia> function update_helper(x, y)
           quote
           $x = $y($x)
           end
       end;

julia> foo(x) = x + 100;

julia> t = 100;

julia> @update t foo
200

julia> t
200

I agree that does seem unintuitive, more so than the other updating operators. It seemed like a natural thing to try. I don’t think another unicode symbol would fix this though.

Yes, I thought about that also, although I don’t think I would use that very often.

I mostly use |> only in Jupyter notebooks or the REPL during development. To be able to just add an equal sign and move one would be great for this. A macro, although nicer, is as cumbersome as writing x=foo(x).

Would a simplify! be a more conventional alternative here?

using SymPy
@syms x y
x = cos(y)^2 + sin(y)^2
x |> simplify!
2 Likes

How about something like this?

using SymPy
@syms x y
x = cos(y)^2 + sin(y)^2
x <!|> simplify

Just to illustrate my point about the arrow direction being a useful visual cue

Yes, that would indeed be nice for my example. But more generally this is not practical, as not many scalar functions are mutating.

This somehow reminds me too much of an inner product notation. And the ! is also used to negate boolean operations, so it’s a bit distracting there.

I dont think the notation is confusing — the operation is quite confusing here. x is both the argument and the target of the assignment. It’s not trivial to express that concisely because it combines two distinct operations

From a mathematical point these updating operators don’t really make sense, I agree. What you’re saying is that any updating operator is kind of weird?

If I accept the concept of updating operators and compare again

x = x * y
x *= y

x = x |> sin
x |>= sin

I don’t find it so illogical.

1 Like

I think what makes it odd is that |>(x, y) is different from +(x, y) and *(x, y) because its second argument is a function. (Plus the implied directionality from the arrow which + and * dont have.)

The operator you are proposing x |>= sin, effectively applies sin to x in-place — but its pointing from x to sin.

Here is another idea that doesn’t have any arrow:

x °= sin
1 Like

In R magrittr they have assignment operator %<>%, so something like <|> is not completely unheard of. But generally people do not like to use it, since it can be rather confusing.

2 Likes

What prevents you from just tacking |> simplify onto the first expression?

2 Likes

It’s not necessarily restricted to this simple example, where of course nothing would keep me from just reevaluating x = cos(y)^2 + sin(y)^2 |> simplify. I’m more interested in the case where you wouldn’t want to redo a calculation and overwrite x by the function call. Maybe I should’ve not make the example so explicit. It’s really meant more general.

Maybe the application of this is niche enough so as not be relevant to many people. It didn’t seem to have caught on in other languages…