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?
f( (x, y) ) = x+y
; it only takes 1 argument and tries to iterate it for 2 elements to assign to x and y. If you annotate its argument type for dispatch, you'll have to do thisf( (x, y)::UnitRange ) = x-y
. Multiple assignment likex, y = someIterable
is called destructuring, and method argument destructuring is specifically documented in depth here: docs.julialang.org/en/v1/manual/functions/… – Tailspin