Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this rewrite to a Julia do block break when the lambda works?

I have this lambda style function call

foldr((l,r) -> r+1, "12345"; init=0)

which Julia happily computes as 5. Rewriting it to the do style looks like

foldr("12345"; init=0) do (l,r)   # I also tried ((l,r),) and just tup
    # l,r = tup   # and then destructure here
    r+1
end

As far as I understood, these two should be equivalent. Unfortunately, Julia 1.7.0-rc3 doesn't agree with me:

ERROR: MethodError: no method matching (::var"#36#37")(::Char, ::Int64)
Closest candidates are:
(::var"#36#37")(::Any) at REPL[25]:2
Stacktrace:
[1] FlipArgs
@ ./reduce.jl:196 [inlined]
[2] BottomRF
@ ./reduce.jl:81 [inlined]
[3] _foldl_impl(op::Base.BottomRF{Base.FlipArgs{var"#36#37"}}, init::Int64, itr::Base.Iterators.Reverse{String})
@ Base ./reduce.jl:58
[4] foldl_impl(op::Base.BottomRF{Base.FlipArgs{var"#36#37"}}, nt::Int64, itr::Base.Iterators.Reverse{String})
@ Base ./reduce.jl:48
[5] mapfoldr_impl(f::Function, op::Function, nt::Int64, itr::String)
@ Base ./reduce.jl:186
[6] #mapfoldr#246
@ ./reduce.jl:205 [inlined]
[7] #foldr#247
@ ./reduce.jl:224 [inlined]
[8] top-level scope
@ REPL[25]:1

Why does the first form work but the second not? Can it be made to work?

like image 847
primfaktor Avatar asked Dec 15 '21 20:12

primfaktor


1 Answers

Parentheses are not needed here:

julia> foldr("12345"; init=0) do l, r
           r+1
       end
5

if you write (l, r) after do it means you are passing one argument that has two elements that should be assigned to l and r respectively, e.g.:

julia> foreach([1:2, 3:4, 5:6]) do (x,y)
       @show x
       @show y
       end
x = 1
y = 2
x = 3
y = 4
x = 5
y = 6

See the Julia Manual for an additional explanation of this rule.

like image 117
Bogumił Kamiński Avatar answered Sep 30 '22 16:09

Bogumił Kamiński