DEV Community

Cover image for Moonscript Iteration
Montegasppα Cacilhας
Montegasppα Cacilhας

Posted on • Updated on

Moonscript Iteration

Moonscript is an interesting imperative weakly-typed programming language with some functional spice.

The Moonscript code compiles into Lua, much more verbose. This provides Moonscript with all Lua features, including coroutines and iterators.

We’re gonna look at three different approaches to implement iterations in Moonscript henceforth.

Standard Lua iteration

The standard iterator consists of three parameters: a step function, the context (usually used as stop condition), and the initial state.

The step function, in turn, must take two parameters, the context (stop condition) and the previous state, returning the next state.

For instance, we’re using the Collatz conjecture.

The Collatz conjecture’s step function might be:

_collatz = (stop, prev) ->
    return if prev == stop
    switch prev % 2
        when 0 -- even
            prev / 2
        when 1 -- odd
            prev * 3 + 1
Enter fullscreen mode Exit fullscreen mode

When the sequence reaches the stop condition, it returns nil (nothing) – the for calls the step function until it receives nil back.

Now we can build the iterator function, that receives the step function, the stop condition, and the initial state (that we’re doubling up in order to preserve the parameter):

collatz = => _collatz, 1, @*2
Enter fullscreen mode Exit fullscreen mode

We can use it:

mooni> print x for x in collatz 10
10
5
16
8
4
2
1
mooni>
Enter fullscreen mode Exit fullscreen mode

Closures

The Standard Lua iteration is quite cryptic. A clearer approach is using closures.

Using closures, the Collatz must return the final function, that returns each value by turn, so it needs to hold the context in a free mutable variable:

collatz = =>
    value = @*2 -- free variable
    ->
        return if value == 1
        switch value % 2
            when 0 -- even
                value /= 2
            when 1 -- odd
                value = value * 3 + 1
        value
Enter fullscreen mode Exit fullscreen mode

it works just like before, keeping the value variable between executions as state.

Coroutine

The most powerful approach Lua can offer is the coroutine. No free variables (closures), only a stateful coroutine yielding results.

There isn’t much fun in coroutined Collatz, so let’s try the Fibonacci number, which has two state variables.

fib = (value using coroutine) ->
    import wrap, yield from coroutine
    wrap ->
        a, b = 0, 1
        for _ = 1, value
            a, b = b, a+b
            yield a
Enter fullscreen mode Exit fullscreen mode

No magic structures, no free variables, neither (explicitly) side effects, only the good-ol’ fellow for.

mooni> print x for x in fib 10
1
1
2
3
5
8
13
21
34
55
Enter fullscreen mode Exit fullscreen mode

Top comments (0)