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:

- The deal function, that returns the next value or
`nil`

if it’s ended. - The overall state (usually the stop condition).
- 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.

## Top comments (0)