Pipe not working, unexpectedly

# throws error
split("123456789", "") .|> x -> parse(Int8,x) |> x -> reshape(x, 3, 3)

# works as expected
A = split("123456789", "") .|> x -> parse(Int8,x)
reshape(A, 3, 3)

Hey guys :wave: Can someone explain me why piping does not work in the first case?

Can you share the error you get? I suspect that putting parentheses around the two first terms will help clarify what you mean.

Compare:

reshape(parse(string))

vs

reshape(parse)(string)

which will rightfully complain that reshaping the parse function doesn’t make sense.

(Also a function not working unexpectedly is normally only a problem if the function is rand)

1 Like
julia> split("123456789", "") .|> x -> parse(Int8,x) |> x -> reshape(x, 3, 3)
ERROR: MethodError: no method matching reshape(::Int8, ::Int64, ::Int64)
Closest candidates are:
  reshape(::AbstractArray, ::Int64...) at C:\Users\Dorian\.julia\juliaup\julia-1.7.2+0~x64\share\julia\base\reshapedarray.jl:116
  reshape(::AbstractArray, ::Union{Int64, AbstractUnitRange}...) at C:\Users\Dorian\.julia\juliaup\julia-1.7.2+0~x64\share\julia\base\reshapedarray.jl:110
  reshape(::AbstractArray, ::Union{Colon, Int64}...) at C:\Users\Dorian\.julia\juliaup\julia-1.7.2+0~x64\share\julia\base\reshapedarray.jl:117
Stacktrace:
  [1] (::var"#106#108")(x::Int8)
    @ Main c:\Users\Dorian\Projects\Sudoku.jl\main.jl:18
  [2] |>(x::Int8, f::var"#106#108")
    @ Base .\operators.jl:966
  [3] (::var"#105#107")(x::SubString{String})
    @ Main c:\Users\Dorian\Projects\Sudoku.jl\main.jl:18
  [4] |>(x::SubString{String}, f::var"#105#107")
    @ Base .\operators.jl:966
  [5] _broadcast_getindex_evalf
    @ .\broadcast.jl:670 [inlined]
  [6] _broadcast_getindex
    @ .\broadcast.jl:643 [inlined]
  [7] getindex
    @ .\broadcast.jl:597 [inlined]
  [8] copy
    @ .\broadcast.jl:899 [inlined]
  [9] materialize(bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(|>), Tuple{Vector{SubString{String}}, Base.RefValue{var"#105#107"}}})
    @ Base.Broadcast .\broadcast.jl:860
 [10] top-level scope
    @ c:\Users\Dorian\Projects\Sudoku.jl\main.jl:18

Guess your suspicion was correct, the code below works. I usually put brackets around my closures, but this was one case where I really did not expect it to matter! I still don’t really get why Julia tries to reshape parse :thinking:

# works
split("123456789", "") .|> (x -> parse(Int8,x)) |> (x -> reshape(x, 3, 3))

(Edit: I tried to minimally edit my title to reflect my not so great use of unexpectedly. [Nice catch btw])

Ok, it’s subtly different from what I thought but still. It tries to reshape each of the parsed Int8s into 3x3 matrices:

split(str, "") .|> x -> ( parse(Int8, x) |> y -> +(y, 3, 3) )

Now replace + by reshape.
Basically the only way the parser could know this is not what you mean is for it to know what reshape does.

1 Like

Thanks, your example is quiet clear. I always thought implicitly everything between two pipes takes precedence, but I can see how this is not always desirable!