Lua and Perl

 | Perl | 1 Comment

Being the hard-core developer type person that I am, every couple of years or so I like to take up a new programming language. This activity provides me with new insights into the wonderful world of programming, seeing how other people tackle interesting problems in different ways.

So last month I picked up a copy of Programming in Lua, and boy has it been a fascinating read. I can definitely recommend purchasing a copy of this book to add to your arsenal of programming literature.

Since my favorite programming language is Perl, each new book I study makes me rethink and compare things about other programming language with Perl (and its potential limitations). This is what I have been doing with Lua.

Two interesting features of Lua which would be great if Perl could do something similar are: "tail-call elimination" and "coroutines".

Tail-call elimination

Basically a tail-call is a goto in disguise. Place as the last statement in a function a return g(x) and you've got a tail-call:

function f(x) return g(x) end

Since the function f(x) has nothing else to do, it doesn't make sense having it wait around until the tail-call returns, using up unused resources like the stack. Might as well avoid using the extra stack space, making it possible to call an unlimited number of nested calls without worrying about the stack overflowing. The following example function can be called forever and the stack will never run out.

function foo(n)
    if n > 0 then return foo(n -1) end
end

A useful example application mentioned in the book, would be traversing a maze with the tail call providing a simple state machine describing going from one cell to the other. Each step goes north, south, east or west into the adjacent room, the exit being the tail-call which transports you from one room to the next.

Coroutines

A coroutine is another wonderful Lua concept. Very similar to threads, it provides a single line of execution within its own context. Several coroutines can work hand in hand, for example in a producer-consumer relationship. You can create, yield and resume coroutines.

Take the example of a producer coroutine reading lines from a file, passing the text to the consumer coroutine. The consumer coroutine receives from the producer.

function consumer (prod)
    while true do
        local x = receive(prod)
        io.write(x, "\n")
    end
end

The send and receive functions provide the gates on each side of the read-write pipe.

function receive (prod)
    local status, value = coroutine.resume(prod)
    return value
end

function send (x)
    coroutine.yield(x)
end

Finally, the producer-coroutine looks like this:

function producer ()
    return coroutine.create(function ()
        while true do
            local x = io.read()
            send(x)
        end
    end)
end

Coroutines can be used for many other things, like iterators or non-preemptive multi-threading applications.

What about Perl?

An interesting challenge could be to see how Perl might be used to implement similar functionalities like those that Lua does natively. As Perl advances and becomes more powerful, it makes sense to see how other programming languages work, and whether or not Perl could be extended to include more advanced concepts.

You'll also want to check out meta-tables and meta-methods, which I believe could be made part of Perl in the not-so distant future.

Official Website

If this all sound confusing, get the book where it's explained clearer and in more detail.

Be sure to check out The Official Lua Website where you will find alot of documentation and tons of examples to whet your curiosity.

1 Comment

Hi there,

for Coroutines, you can use the Coro module. It actually works quite well.

For tail-call elimination, Perl6 has that I believe. There is a goto optimization that could be used to implement tail-call elimination. From the perlfunc manpage:

The "goto−&NAME" form is quite different from the other forms of "goto". In fact, it isn’t a goto in the normal sense at all, and doesn’t have the stigma associated with other gotos. Instead, it exits the current subroutine (losing any changes set by local()) and immediately calls in its place the named subroutine using the current value of @_. This is used by "AUTOLOAD" subroutines that wish to load another subroutine and then pretend that the other subroutine had been called in the first place (except that any modifications to @_ in the current subroutine are propagated to the other subroutine.) After the "goto", not even "caller" will be able to tell that this routine was called first.

NAME needn’t be the name of a subroutine; it can be a scalar variable containing a code reference, or a block that evaluates to a code reference.

Best regards,

Leave a comment

Recent Entries

No more winter greens
The cool, windy and grayish afternoon calls me onward. It's drizzling on my windshield but I do not care.
Champion of Scotland
I nearly cried my eyes out when I discovered that young Tommy Morris dies in the prime of his
Sticky keyboard
Up until yesterday the Del-, Ins- and Home- keys on the upper right-hand corner were sticking alot, and it's
Perl on steroids
Read this from beginning to end, and you then tell me with a straight face that it hasn't completely
Seventh Dutch Perl Workshop
Going to attend the 7th Dutch Perl Workshop tomorrow in Arnhem. Cannot wait to get up bright and early