C# has a convenient way to create iterators using the yield return
statement. The package ResumableFunctions
provides the same functionality for the Julia language by introducing the @resumable
and the @yield
macros. These macros can be used to replace the Task
switching functions produce
and consume
which were deprecated in Julia v0.6. Channels
are the preferred way for inter-task communication in julia v0.6+, but their performance is subpar for iterator applications. See the benchmarks section below.
ResumableFunctions
is a registered package and can be installed by running:
using Pkg
Pkg.add("ResumableFunctions")
using ResumableFunctions
@resumable function fibonnaci(n::Int) :: Int
a = 0
b = 1
for i in 1:n
@yield a
a, b = b, a+b
end
end
for fib in fibonnaci(10)
println(fib)
end
The following block is the result of running julia --project=. benchmark/benchmarks.jl
on a computer with the processor: Intel(R) Core(TM) i5-5300U CPU @ 2.30GHz
. Julia version 1.1.1 was used.
Direct:
49.724 ns (0 allocations: 0 bytes)
ResumableFunctions:
10.230 μs (281 allocations: 8.83 KiB)
Channels csize=0:
305.877 μs (465 allocations: 8.84 KiB)
Channels csize=1:
504.438 μs (379 allocations: 7.33 KiB)
Channels csize=20:
87.889 μs (206 allocations: 5.06 KiB)
Channels csize=100:
67.911 μs (198 allocations: 6.44 KiB)
Closure:
2.437 μs (83 allocations: 1.31 KiB)
Closure optimised:
245.676 ns (3 allocations: 64 bytes)
Closure statemachine:
40.149 ns (0 allocations: 0 bytes)
Iteration protocol:
63.635 ns (0 allocations: 0 bytes)
- Ben Lauwens, Royal Military Academy, Brussels, Belgium.
- To discuss problems or feature requests, file an issue. For bugs, please include as much information as possible, including operating system, julia version, and version of MacroTools.
- To contribute, make a pull request. Contributions should include tests for any new features/bug fixes.
-
2019: v0.5.1
- inference problem solved: force iterator next value to be of type
Union
ofTuple
andNothing
.
- inference problem solved: force iterator next value to be of type
-
2019: v0.5.0 is Julia v1.2 compatible
-
2018: v0.4.2 prepare for Julia v1.1
- better inference caused a problem;).
- iterator with a specified
rtype
is fixed.
-
2018: v0.4.0 is Julia v1.0 compatible.
-
2018: v0.3.1 uses the new iteration protocol.
- the new iteration protocol is used for a
@resumable function
based iterator. - the
for
loop transformation implements also the new iteration protocol.
- the new iteration protocol is used for a
-
2018: v0.3 is Julia v0.7 compatible.
- introduction of
let
block to allow variables not te be persisted between@resumable function
calls (EXPERIMENTAL). - the
eltype
of a@resumable function
based iterator is its return type if specified, otherwiseAny
.
- introduction of
-
2018: v0.2 the iterator now behaves as a Python generator: only values that are explicitely yielded are generated; the return value is ignored and a warning is generated.
-
2017: v0.1 initial release that is Julia v0.6 compatible:
- Introduction of the
@resumable
and the@yield
macros. - A
@resumable function
generates a type that implements the iterator interface. - Parametric
@resumable functions
are supported.
- Introduction of the
- In a
try
block only top level@yield
statements are allowed. - In a
finally
block a@yield
statement is not allowed. - An anonymous function can not contain a
@yield
statement.