JuliaDynamics / ResumableFunctions.jl

C# style generators a.k.a. semi-coroutines for Julia.
Other
158 stars 19 forks source link

nested resumable function calls don't seem to work #105

Closed brianguenter closed 4 hours ago

brianguenter commented 5 hours ago

Nested resumable functions don't work the way I expected. The documentation doesn't have examples so it's not clear if this feature is even supported.

Minimal Working Example

using ResumableFunctions

@resumable function f1(n)
       for i in 1:n
       @yield i
       end
       end

@resumable function f2(n)
       for i in 1:n
       @yield f1(i)
       end
       end

When execute for val in f2(10) println(val) end expected to get

1
1
2
1
2
3
...

Instead got this:

var"##f1_FSMI#378"{Int64, Int64, UnitRange{Int64}, Int64}(0x00, 1, 100356, 0:0, 2865024254976)
var"##f1_FSMI#378"{Int64, Int64, UnitRange{Int64}, Int64}(0x00, 2, 559109, 1:8, 2862929218160)
var"##f1_FSMI#378"{Int64, Int64, UnitRange{Int64}, Int64}(0x00, 3, 559109, 2:8, 140717541655296)
var"##f1_FSMI#378"{Int64, Int64, UnitRange{Int64}, Int64}(0x00, 4, 559108, 0:0, 2863778627632)
var"##f1_FSMI#378"{Int64, Int64, UnitRange{Int64}, Int64}(0x00, 5, 559109, 2:8, 2862929219504)
var"##f1_FSMI#378"{Int64, Int64, UnitRange{Int64}, Int64}(0x00, 6, 1083396, 0:0, 2862929220400)
var"##f1_FSMI#378"{Int64, Int64, UnitRange{Int64}, Int64}(0x00, 7, 563204, 2:2, 2863778634640)
var"##f1_FSMI#378"{Int64, Int64, UnitRange{Int64}, Int64}(0x00, 8, 559109, 1:8, 140718125976085)
var"##f1_FSMI#378"{Int64, Int64, UnitRange{Int64}, Int64}(0x00, 9, 563204, 2:2, 2863778775680)
var"##f1_FSMI#378"{Int64, Int64, UnitRange{Int64}, Int64}(0x00, 10, 563204, 2:2, 2863847320400)

Package versions

(jl_WYdO8p) pkg> st
Status `C:\Users\seatt\AppData\Local\Temp\jl_WYdO8p\Project.toml`
  [c5292f4c] ResumableFunctions v0.6.10
)
Krastanov commented 4 hours ago

Use @yieldfrom not @yield to nest them. I.e. you do not want to yield the entire iterator, rather you want each iteration to be its own yield.

julia> @resumable function f1(n)
           for i in 1:n
              @yield i
           end
       end
f1 (generic function with 1 method)

julia> @resumable function f2(n)
           for i in 1:n
              @yieldfrom f1(i)
           end
       end
f2 (generic function with 1 method)

julia> collect(f2(5))
15-element Vector{Any}:
 1
 1
 2
 1
 2

Check this post stackoverflow post: https://stackoverflow.com/questions/9708902/in-practice-what-are-the-main-uses-for-the-yield-from-syntax-in-python-3-3