The simplest work where Lua may be handy is in replacing application
config files with scripts. This allows one to define complex data
structures and utilize the power of a full-fledged programming language. For
example, the following "config" file, written in Lua:

assigns to variables "username" and "password" values read from
environment vars USER/PWD, but substitutes default values if they are
not defined. The following Haskell program demonstrates how to get
your hands on values defined in such an unusual way:

What we are doing here? First, we create new instance of Lua
interpreter using "newstate". Lua implementation doesn't use global
vars, which means that you can create as many Lua instances as you need
and run them all simultaneously.

Then, "openlibs" imports built-in Lua functions into this instance.
Note that fresh Lua instances only have access to a dozen standard
(arithmetic) operations. By careful selection of functions provided
to the Lua instance, you can turn it into sandbox - e.g. disallow access
to file system, network connections and so on, or provide special
functions which can access only specific directory/host/whatever.

The next operation, "dofile", runs script from file specified. This script
defines variables "username" and "password" that we then read using
"eval". Finally, "close" destructs the Lua instance, freeing memory it has
grabbed.

Now imagine that we need more complex config capable of providing for
each site we have an account in its own user/pwd pair. We can write it either
as an associative table, or as a function mapping site name to user/pwd.
Let's combine both approaches:

But that's not the whole story. When Lua is used as a scripting language
inside your application, the communication should be two-forked.
Imagine, for example, that you develop a game and Lua scripts are used
to control game characters. While the Lua script fully defines their
behavioural logic, it should command something that will render this
behaviour to the player. Just for example:

for i=1,3do
move(1,"forward")
move(2,"backward")
end

This script commands our character to go 1 step forward, 2 steps backward
repeating this 3 times. The "move" procedure here should be defined
on Haskell side to show his behaviour. Let's go:

The only new call here is "register" which registers Haskell function
in Lua instance. Please note that we may call any Lua
function/procedure from Haskell (as we've done in previous example)
and register any Haskell procedure in Lua as far as their arguments
and results has simple enough types (numbers, strings, booleans, lists
and maps). In such simple cases HsLua takes in its hands all the
conversions of data between Haskell and Lua worlds.

Also note that we omitted here a call to "openlibs", making Lua instance
a real sandbox - all the communication with external world that script
can do is to move it, move it :)

Lua variables have dynamic types. When we cast these values from/to
Haskell world, they are mapped to the appropriate Haskell types. Type
class StackValue covers Haskell types that can be casted from/to Lua
values and defines the casting rules. Predefined class instances
include Int, Double, String, Bool, [a] for lists and [(a,b)] for maps
where a and b may be any StackValue types again. There is also an
existential class wrapper XXX that allows to pass heterogeneous
collections (lists/maps) from Haskell to Lua:

HsLua includes two operations which just execute operators in context
of a given Lua instance: "dofile" and "dostring" (executing contents of
file and string, respectively). They return 0 on success and errcode
otherwise:

Two other operations return result of executing string/file: "eval"
and "evalfile", respectively. "eval" may also be used to evaluate
expressions, as it was done in our first script. These operations
return (Right a) on success, where "a" may be any type belonging to
StackValue class. On an error they return (Left Int) where Int will be
either errcode or 0 if casting was unsuccessful:

The next pair of operations is "callfunc" and "callproc". They both call a
Lua function passing to it arbitrary number of arguments. The only
difference is that "callfunc" returns and "callproc" omits the return
value of Lua function called:

A few words about Lua as a language. It's rather close to
Perl/Python/Ruby, the main difference is Lua's compactness. In
particular, HsLua will add only about 200kb to your program. The Lua
syntax definition is just about 40 lines long and omits many modern
features such as exception handling or OOP. It provides simple means
for doing simple tasks that made it perfect tool for non-professional
programmers

But the first impression fools you. Lua is a wolf in sheep's hide. As
its author said, "Lua provides Modula syntax but Scheme semantics".
The main distinctive feature of Lua is its extensibility. It provides
semantical base for implementation of exceptions, OOP, data hiding,
metaprogramming, persistency, functional programming, lazy evaluation,
concurrency/coroutines/iterators. But special syntax for advanced
features is almost non-existent and in many cases Lua gives you only
a base on which you have to build yourself. For example, OOP inheritance
isn't implemented but there are libraries implementing single and
multiple inheritance just by manipulating metatables. So while you can
learn Lua basics in a few minutes, I recommend you to spend a few days
before making a final decision.

If you want to know more about Lua, you can jump to the online book
written by main developer of Lua and describing Lua 5.0 at
http://www.lua.org/pil/ or buy new version of this book describing Lua
5.1 (current version) from Amazon [2]

If a user of your application wants to use some Lua library written in
Lua itself, that's easy - just put the source file into program
directory. But what about libraries containing C parts?
LuaBinaryModules solves this problem - it allows to compile any
library for Lua to a dll/so file which may be imported by any Lua
instance to get full library functionality. Technically speaking, LBM
just adds one more function which registers all library functions and
this function is called automatically by LuaBinaryModules loader

As a result, LuaBinaryModules allows users of your application to
install any libraries they need just by copying their dll/so files
into application directory.

While Lua bytecode interpreter being register-based VM is fastest
among all dynamic languages, sometimes you need even more speed.
LuaJIT compiles bytecode instructions into x86 code, improving speed
up to 7 times (as tested on Great Language Shootout examples). One of
its interesting features is automatic function specialization to the
types of actual parameters

I've quickly tested it on simple i=i+1 statements and found that with
JIT computer runs at 1/10th of its full speed while without JIT it
runs at 1/30th

wxLua is a cross-platform (Windows, Linux, OSX) binding to wxWindows
library, plus IDE written using this binding that supports debugging
of Lua code and generation of Lua bindings to C libraries. So, you get
a full-featured Lua IDE extensible in Lua itself.

It is even more interesting that you can add the wxLua to your
Lua-enabled application, providing user-written code means to build
full-fledged GUI. Just imagine that now you can split your program
into two parts - real work is done in Haskell part which registers its
functions for Lua part and all the funny dialogs and editors are
written in Lua using wxWindows widgets. The Lua part can be easily
created/extended by less experienced users meaning that you may spend
more time on implementing core algorithms. Isn't it beautiful?

We already mentioned that Lua semantics is rather close, may be a bit
better than of other scripting languages, but its syntax is terse. But
this simplicity opens up sudden and very exciting possibility - it's
easy to reimplement Lua and add any other features we want without
losing bytecode compatibility with official implementation

MetaLua does that, reimplementing Lua compiler in Lua itself. But it
goes much further: Lua syntax is described in GG, ParseC-like parsing
combinators library. Unlike ParseC, it allows to change parsing rules
on the fly, making it ideal basis for language with extensible syntax

MetaLua adds to Lua a lot of FP-styled and other features - ADT,
pattern matching, terse syntax for anonymous lambdas, list
comprehensions, familiar syntax for exception handling, RAII brackets,
statements inside expressions, ternary ?: operator, type/domain
checking. All these implemented with usual Lua modules and as
everything in Lua, they are very terse - the largest module,
implementing pattern matching, is just 200 lines long. You can add new
syntax just by dropping new modules into MetaLua directory. Extending
MetaLua is very like to programming in Template Haskell with all its
pitfalls solved and extending-syntax features added. I will be very
pleased if GHC provided front-end like the MetaLua

Just imagine all these features combined together: blazing fast
dynamic FP language that may be easily extended by means of new
libraries and new syntax just by dropping their files into program's
directory and supports creation of GUIs - seamlessly integrated with
your Haskell code. I think it will be invaluable tool that supplements
Haskell's power with easiness and flexibility.