JuliaFolds / Transducers.jl

Efficient transducers for Julia
https://juliafolds.github.io/Transducers.jl/dev/
MIT License
432 stars 24 forks source link

Recursive transducers cannot be inferred #443

Open jakobnissen opened 3 years ago

jakobnissen commented 3 years ago

Everyone's favorite fibonacci example:

function fib(n)
    n < 2 && return n
    n |> Map(n -> fib(n-1) + fib(n-2)) |> first
end

Here, the result of first infers to Any. This basically prevents you from using recursive functions in transducers.

tkf commented 3 years ago

Apparently, ... |> Map(f) |> first is handled by the slow fallback path of transducer-to-iterator-transform conversion. So, it's not going to perform well. Maybe I should throw an error here since it is not guaranteed to be O(1).

By the way, isn't (n::Number) |> Map(f) |> first equivalent to just f(n) since a number is a singleton collection in Julia? I guess I'm a bit puzzled about what you wanted to do in the example of the OP. Corecursion or sth? If you want to define a stream of Fibonacci numbers, check out https://github.com/JuliaFolds/FGenerators.jl

jakobnissen commented 3 years ago

In some other code, I was puzzled to find a recursive transducer infer to Any. Indeed, the example in this issue is just as simple as possible, to show the failure of inference.