# ANN: ResumableFunctions

**URL:** https://discourse.julialang.org/t/ann-resumablefunctions/5711
**Category:** Community
**Tags:** package, announcement
**Created:** [September 4, 2017, 11:47am UTC](https://discourse.julialang.org/t/ann-resumablefunctions/5711 "2017-09-04T11:47:09Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![BenLauwens](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/benlauwens/32/2051_2.png) [@BenLauwens](https://discourse.julialang.org/u/BenLauwens)
#### Post date: [September 4, 2017, 11:47am UTC](https://discourse.julialang.org/t/ann-resumablefunctions/5711/1 "2017-09-04T11:47:09Z")

</div>

Hi

C# has a convenient way to create iterators using the `yield return` statement. The package [ResumableFunctions](https://github.com/BenLauwens/ResumableFunctions.jl.git) 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.

```julia
using ResumableFunctions

@resumable function fibonnaci(n::Int)
  a = 0
  b = 1
  for i in 1:n-1
    @yield a
    a, b = b, a+b
  end
  a
end

for fib in fibonnaci(10)
  println(fib)
end

```

Enjoy!

Ben

---

<div class="post-metadata">

### Author: ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)
#### Post date: [September 5, 2017, 2:55pm UTC](https://discourse.julialang.org/t/ann-resumablefunctions/5711/4 "2017-09-05T14:55:19Z")

</div>

I apologize for being late to the ResumableFunctions vs PyGen party, but for me, the only time I really needed PyGen (because there is no other simple alternative) is when making recursive generators, basically traversing tree-like structures without having to generate it all a priori. So I tested the following pieces of codes in Julia using PyGen and ResumableFunctions and in Python and here are the results:

```julia
a = [[1,2,3],[4,5,6]]
@resumable function g(x)
	if isa(x,Number)
		@yield x
	else
		for i in x
			for j in g(i)
				@yield j
			end
		end
	end
end

for i in g(a)
	println(i)
end

#=
1
false
2
false
3
false
nothing
4
false
5
false
6
false
nothing
nothing
=#

a = [[1,2,3],[4,5,6]]
@pygen function f(x)
	if isa(x,Number)
		yield(x)
	else
		for i in x
			for j in f(i)
				yield(j)
			end
		end
	end
end

for i in f(a)
	println(i)
end

#=
1
2
3
4
5
6
=#

import numbers
a = [[1,2,3],[4,5,6]]
def f(x):
	if isinstance(x, numbers.Number):
		yield x
	else:
		for i in x:
			for j in f(i):
				yield j

for i in f(a):
	print i

"""
1
2
3
4
5
6
"""

```

Clearly `ResumableFunctions` generates extra entries not in the other 2, can that be treated?

---

<div class="post-metadata">

### Author: ![BenLauwens](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/benlauwens/32/2051_2.png) [@BenLauwens](https://discourse.julialang.org/u/BenLauwens)
#### Post date: [September 6, 2017, 7:46am UTC](https://discourse.julialang.org/t/ann-resumablefunctions/5711/5 "2017-09-06T07:46:19Z")

</div>

Hi @mohamed82008

I can explain the behaviour:

- the extra `false` entries are a side effect of the transformation of a `for` loop in a `while` loop
- the extra `nothing` is the normal return of the function (this is also the default behaviour in C#)

Can you open an issue in the `ResumableFunctions` repository?  
The first one can be directly solved. The second one I have to look at the `Iterator` interface to see if I can fix it.

This is really a very nice use case and I hope I can find a solution;)

Ben

---

<div class="post-metadata">

### Author: ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)
#### Post date: [September 6, 2017, 11:05pm UTC](https://discourse.julialang.org/t/ann-resumablefunctions/5711/6 "2017-09-06T23:05:48Z")

</div>

Interesting, I will open an issue then. Thanks for your effort btw, that’s an awesome piece of work!

---

<div class="post-metadata">

### Author: ![BenLauwens](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/benlauwens/32/2051_2.png) [@BenLauwens](https://discourse.julialang.org/u/BenLauwens)
#### Post date: [September 8, 2017, 10:40pm UTC](https://discourse.julialang.org/t/ann-resumablefunctions/5711/7 "2017-09-08T22:40:52Z")

</div>

A complete explanation of this weird but logical behaviour can be found in this [issue](https://github.com/BenLauwens/ResumableFunctions.jl/issues/2).  
The correct sequence can be created by 3 minor modifications:

```julia
using ResumableFunctions

@resumable function g(x)
    if isa(x,Number)
        return x # If x is a number the @resumable function is only called once
    else
        for i in x
            for j in g(i)
                j == nothing || @yield j # No explicit return is defined, so we have to eliminate the default returns
            end
        end
    end
end

a = [[1,2,3],[4,5,6]]

for i in g(a)
    i==nothing || println(i) # Eliminate the default return
end

```

---

<div class="post-metadata">

### Author: ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)
#### Post date: [September 9, 2017, 7:48am UTC](https://discourse.julialang.org/t/ann-resumablefunctions/5711/8 "2017-09-09T07:48:27Z")

</div>

Cool, thanks!
