## DEV Community

Montegasppα Cacilhας

Posted on

# Lua & MoonScript Iterators

2017, the year after the Brazil’s democracy death, was one of my more fruitful years (the more at all was 2008), so I decided to transcript some of that year’s posts back.

I’m starting with a compilation of two posts ¹ ² about interators in MoonScript.

### Lua standard iterator

The Lua’s standard approach is a function that returns multiple values:

1. The deal function, that returns the next value or `nil` if it’s ended.
2. The overall state (usually the stop condition).
3. The initial value.

For instance, the Collatz Conjecture can be implemented as follows:

``````collatz = => _collatz, 1, @*2
``````

The initial value is dobled to allow the first step to return it; the loop ends when the state reaches one (`1`).

The deal function (`_collatz`) must accept the stop condition (`1`) and the last value. Using the MoonScript’s `self`, we can omit the first argument:

``````_collatz = (last) =>
return if last == @
switch last % 2
when 0
last / 2
when 1
last * 3 + 1
``````

Then it already works in `mooni`:

``````moon> print x for x in collatz 10
10
5
16
8
4
2
1
moon>
``````

### Closures

We can solve this problem by using closures too.

For that, we need to write a factory that returns only the deal function, but with no arguments.

``````collatz = (value) ->
value *= 2
->
return if value == 1
switch value % 2
when 0
value /= 2
when 1
value = value * 3 + 1
value
``````

This new function holding a closure (the `value` variable) behaves exactly like the `collatz` implemented using the standard iterator, but in one single block.

### Coroutines

The more powerful resource in Lua is the coroutine.

Coroutines allow yielding results while it keeps running the concurrent routine.

Collatz Conjecture using coroutine is:

``````_collatz = (value using coroutine) ->
import wrap, yield from coroutine
wrap ->
while value != 1
yield value
switch value % 2
when 0
value /= 2
when 1
value = value * 3 + 1
1
``````

And also:

``````moon> print x for x in collatz 10
10
5
16
8
4
2
1
moon>
``````

### Fibonacci

Let’s implement two approaches of Fibonacci numbers.

Using the standard iterator, we simply don’t need to know the last result, we can manage it inside a mutable state – it’s possible to implement it in only one function using `unpack`:

``````fib = (n) -> unpack {
-- Deal function
=>
return if @n == 0 -- stop
@a, @b, @n = @b, @a+@b, @n-1
@a                -- step

-- Initial state
{a: 0, b: 1, :n}
}
``````

And this works fine:

``````moon> print i for i in fib 10
1
1
2
3
5
8
13
21
34
55
``````

Now Fibonacci numbers using coroutine:

``````fib = (n using coroutine) ->
import wrap, yield from coroutine
wrap ->
a, b = 0, 1
for _ = 1, n
a, b = b, a+b
yield a
``````

The both approaches are performative, ’cause they use double accumulator to run a linear procedure.

Original post in Kodumaro.