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

make <| right associative #24153

Closed
schlichtanders opened this issue Oct 15, 2017 · 5 comments
Closed

make <| right associative #24153

schlichtanders opened this issue Oct 15, 2017 · 5 comments
Labels
needs decision A decision on this change is needed parser Language parsing and surface syntax
Milestone

Comments

@schlichtanders
Copy link

schlichtanders commented Oct 15, 2017

Dear all,
I just stumpled upon this weird thing: in julia 0.5 the operator <| is left associative.
This is a big surprise to me and hence I am issueing this here.

I wanted to define <| to be the opposite of |>, i.e. something like haskells dollar sign operator.
It already has the same operator precedence, however not the opposite associativity. For me this looks like a bug indeed, as the symbol directly suggests opposite associativity.

Others also tried to have an operator for this and came up with using for example, see https://stackoverflow.com/questions/41733532/does-julia-have-an-operator-similar-to-haskells-dollar-sign/41735969

Can this changed be still included up until julia 1.0 is out and nothing like this can be changed anymore?
that would be really great to have both |> and <| as opposites

@JeffBezanson JeffBezanson added needs decision A decision on this change is needed parser Language parsing and surface syntax labels Oct 15, 2017
@StefanKarpinski StefanKarpinski added the status:triage This should be discussed on a triage call label Oct 15, 2017
@andyferris
Copy link
Member

My gut feeling is that this is a good idea, but I do wonder if there are any other candidates for right-associativity?

Can this changed be still included up until julia 1.0 is out and nothing like this can be changed anymore?

Technically things like this could change in something like Julia v2,0, but we are hoping to minimize the need for breaking changes, or equivalently, to keep a stable line of v1.x releases going for as long as possible.

@StefanKarpinski
Copy link
Sponsor Member

StefanKarpinski commented Oct 17, 2017

Quoting @JeffBezanson in #23224 (comment):

Maybe leftward arrows should also be right-associative?

I think this is the correct answer. We should be conservative with any operator we're not sure what the behavior of it should be. We can always add them later once we've sorted it out but there's a significant chance of being stuck with unusable syntax due to mistakes like this that we can't change. Of course, this is precisely the sort of thing that femtocleaner can easily fix, but changing associativity is very much a breaking change.

@MagBad
Copy link

MagBad commented Oct 18, 2017

I've make a small test using the operator <|, defined in the link from @schlichtanders, which transforms sum ( rand ( 100000 ) ) to `sum ∘ rand <| 1000000. And using BenchmarkTools I created a primitive example.

julia>using BenchmarkTools

# The new operator
julia> f <| x = f(x)

julia> @benchmark sum  rand <| 1000000 samples=100
BenchmarkTools.Trial: 
  memory estimate:  7.63 MiB
  allocs estimate:  2
  --------------
  minimum time:     1.553 ms (0.00% GC)
  median time:      2.849 ms (0.00% GC)
  mean time:        2.495 ms (13.84% GC)
  maximum time:     4.079 ms (17.72% GC)
  --------------
  samples:          100
  evals/sample:     1

julia> @benchmark sum(rand(1000000)) samples=100
BenchmarkTools.Trial: 
  memory estimate:  7.63 MiB
  allocs estimate:  2
  --------------
  minimum time:     1.533 ms (0.00% GC)
  median time:      3.036 ms (0.00% GC)
  mean time:        2.651 ms (14.08% GC)
  maximum time:     4.250 ms (44.90% GC)
  --------------
  samples:          100
  evals/sample:     1

Using the operator with <| is a bit more elegant form my point of view. Since for you'd have to enclose the function chain and the argument separatly, e.g.

( sum  rand)(100000)

And for some reason there seams to be a small performance boost with the new operator? Still wondering about the GC percentages. Thought maybe I'm missing something.

@andyferris
Copy link
Member

For my own nefarious reasons, I've been wondering if |> could also compose the functions before calling the result?

@JeffBezanson JeffBezanson added this to the 1.0 milestone Oct 19, 2017
@JeffBezanson JeffBezanson removed the status:triage This should be discussed on a triage call label Oct 19, 2017
@MagBad
Copy link

MagBad commented Oct 19, 2017

I've been working on a prototype implementation on my forked version. I've implemented some tests for the functionality in test/operators.jl, but the broadcasting doesn't seem to work as expected.

julia> sum  sqrt .∘ rand <| 10
ERROR: MethodError: no method matching sqrt(::Array{Float64,1})
Closest candidates are:
  sqrt(::Float16) at math.jl:971
  sqrt(::Complex{Float16}) at math.jl:972
  sqrt(::BigFloat) at mpfr.jl:489
  ...
Stacktrace:
 [1] (::getfield(Base, Symbol("##57#58")){typeof(sum),typeof(sqrt)})(::Array{Float64,1}, ::Vararg{Array{Float64,1},N} where N) at ./operators.jl:985
 [2] <|(::getfield(Base, Symbol("##57#58")){getfield(Base, Symbol("##57#58")){typeof(sum),typeof(sqrt)},typeof(rand)}, ::Int64) at ./operators.jl:962

I'm on Fedora 25 an tested this with 0.6, where the following deprecation warning was prompted

julia> f <| x = f(x)
<| (generic function with 1 method)

julia> sum  sqrt .∘ rand <| 10
WARNING: sqrt{T <: Number}(x::AbstractArray{T}) is deprecated, use sqrt.(x) instead.
Stacktrace:
 [1] sqrt(::Array{Float64,1}) at ./deprecated.jl:57
 [2] #55 at ./operators.jl:884 [inlined] (repeats 2 times)
 [3] <|(::Base.##55#56{Base.##55#56{Base.#sum,Base.#sqrt},Base.Random.#rand}, ::Int64) at ./REPL[1]:1
 [4] macro expansion at ./REPL.jl:97 [inlined]
 [5] (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at ./event.jl:73
while loading no file, in expression starting on line 0
6.619412577220985

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs decision A decision on this change is needed parser Language parsing and surface syntax
Projects
None yet
Development

No branches or pull requests

5 participants