Lua

Lua is one of the many languages with a Tk binding.
It is a vaguely Algol-styled scripting language developed open source at a Brazilian institution, characterized by using hash tables as central data structure, even for vectors and lists. Lua's kernel is unusually compact. Lua style emphasizes metaprogramming. It has multiple implementations, notably LuaJIT.

Current version: 2022-01-26 - Lua 5.4.4

Roberto published the Lua book early in 2004.
Lua has its own wiki .

Bringing Lua and Tcl together

Lux is Jean-Claude Wippler's experiment at binding Lua together with more traditional scripting languages ...

ltcltk : A package that provides bindings for Lua to Tcl and the Tk toolkit. I it now maintained anymore and a copy of it claimed to work with Lua 5.3 (maybe even 5.4) is at Github

LÖVE is a framework for making 2D-games in Lua.

tclua : A Lua binding for Tcl programming language, even older than ltcltk (16 years without changes by 2022).

Creating a Lua interpreter in Tcl

SWIG

Max Ischenko reports success using SWIG to wrap Lua libraries as loadable .so-s exposed through Tcl.
He even has an incr Tcl class he calls "LuaInterpreter".

mfi: Yup, that was pretty simple. To compile a .so you just do:

 swig -tcl8 -module lua Lua.i
 gcc -c -fpic lua_wrap.c
 gcc -shared lua_wrap.o -o lua.so -llua -llualib

And the above mentioned itcl class is a little more complex than this sketch:

 itcl::class LuaInterpreter {
        public {
                method doFile fname { return [lua_dofile $L $fname] }
                method doString buf { return [lua_dostring $L $buf] }
                method call {func {arg ""}} {}
 
                method popLast {} {
                        set value [lua_tostring $L -1]
                        lua_remove $L -1
                        return $value
                }
                method printStack {} {}
        }
        constructor {} {}
        destructor { lua_close $L }
        common call_template "return %s(%s);"
 }
 
 itcl::body LuaInterpreter::constructor {} {
        set L [lua_open 1024]
        L doString "function _ERRORMESSAGE(msg) print(msg) end"
 }
 
 itcl::body LuaInterpreter::call {func {arg ""}} {
        set op [format $call_template $func $arg]
        doString $op
 }

I found the interface of doString, call and popLast quite sufficient for my needs. Notice also, that you can have as many instances of Lua interpreter as you want. --mfi.

Creating a Tcl interpreter in Lua

See LuaJIT. There are Tcl bindings to LuaJIT using Critcl.

Performance

Lua is quite fast: https://benchmarksgame-team.pages.debian.net/benchmarksgame/index.html but doesn't seem to have all the nifty features that other languages do.

On the other hand, Lua does support full co-routines; Roberto is a sometimes-cited theoretician of concurrency.


An article about Lua's byte code engine: https://www.lua.org/doc/jucs05.pdf . Apparently they moved from a stack based to a register based engine and saw big performance improvements.

References

While Lua began with an emphasis on industrial automation and allied areas, it's now significant in game development. Two books provide substantial introductions:

This is an article about embedding Lua: Embed Lua for Scriptable Apps

RegExp and Unicode

WJP A real weakness of Lua when compared to Tcl is its feeble regular expression support. Lua regexps don't have groups. The quantifiers apply either to the preceding symbol or the preceding builtin character class. (Lua does have capture groups, for use with backreferences, but they do not serve as quantifier domains.) Lua lacks the range quantifiers (e.g. {2,4} = "from two through four inclusive") found in any POSIX regexp package. It does not permit characters to be specified using the usual octal and hex escapes, and it does not have any of the recent innovations such as assertions. If you're doing anything involving more than simple regexp matching, Lua just doesn't cut it. Tcl has one of the best regexp packages. Lua has perhaps the poorest. Lua also does not support Unicode. It is 8-bit clean but has no concept of multibyte or wide character.

Lars H: In other words, the Lua "regexps" are really more of a beefed-up string match than real regular expressions. (For those who don't know regexp theory: There is a very strict definition of regular expression that has its roots deep down in computer science and mathematics. The abilities to have alternative branches and repetition of arbitrary subexpressions are essential parts in this definition; losing them loses most of the power of the concept. Character classes, hex escapes, range quantifiers, lookahead constraints etc. are on the other hand "just" syntactic sugar that helps reducing the size of the regexp (often a significant reduction, but one can do without them). The "back reference" feature of Tcl regexps does however go beyond what pure regular expressions should be capable of.)

WJP: Yes, good characterization. Alternation and closure of subexpressions are essential for true regular expressions but Lua has alternation and closure only for singletons. As for syntactic sugar, its true that in some sense it is less important, but some syntactic sure makes a huge difference in practice. It would not be much fun to have to write out [abcdefghijklmnopqrstuvwxyz] every time instead of [:lower:], and its even worse if you're looking at all of Unicode. After all, Tcl is only "syntactic sugar" on machine language. They're both Turing complete in principle, and both just finite state transducers in practice (assuming a finite universe and therefore computers with a finite set of states). Lua has one construct that I've never seen anywhere else: %bXY (%b constant, X and Y variables over characters) matches a string beginning with an X and ending in a Y. It looks like its intended for matching balanced delimiters.

RS however still prefers [a-z] to [:lower:] - less to type, and clearer in what is meant (is lowercase äöü/Greek/Cyrillic included?)

WJP Lua doesn't support Unicode, so unless you're talking about a parochial 8-bit encoding, it doesn't support Greek, Cyrillic, etc. If it did, off the top of my head I'm not sure that the cases are always segregated in such a way that ranges can be used. Certainly some other sets aren't. Consider ASCII/ISO8859/Unicode Latin punctuation. So, yes, when it works ranges like [a-z] are fine, but they aren't a general solution. Speaking of which, one thing missing from Tcl are classes corresponding to Unicode ranges and Unicode general character properties. In Java you can write things like:

 \p{InHiragana}\p{InKatakana} 

to search for a hiragana character followed by a katakana character, or

 \p{Zs}

for the class of space characters.


RS Unicode ranges are as easy as [a-z]: consider this regexp matching a hiragana and then a katakana:

 % regexp -inline {[\u3041-\u309e][\u30a1-\u30fe]} あのビール
 のビ

WJP True, though the Java versions with names are still handy if you don't have a Unicode range list available. And the range construct doesn't handle the Unicode general character properties.


HJG Regarding RE, from http://www.lua.org/pil/20.1.html "Programming in Lua":

 Lua does not use POSIX regular expressions (regexp) for pattern matching.
 The main reason for this is size: A typical implementation of POSIX regexp takes
 more than 4,000 lines of code. This is bigger than all Lua standard libraries together.
 In comparison, the implementation of pattern matching in Lua has less than 500 lines.

But the text follows so:

Of course, the pattern matching in Lua cannot do all that a full POSIX implementation does. Nevertheless, pattern matching in Lua is a powerful tool and includes some features that are difficult to match with standard POSIX implementations.


So, there are some compromises to make a small (ca. 100 kb) embedded/embeddable language...

WJP Sure, there are reasons for not including full regular expression support, but the lack of it still makes Lua less attractive than Tcl for applications in which regular expressions are useful. I'm not suggesting that the developers of Lua are stupid, just that Lua doesn't really compete with Tcl in some areas.

davidw In some areas, it doesn't. Something like Unicode needs to be integrated into the core. However, regular expressions could mostly be bolted on as an additional package, leaving the core small for those who need that, and giving regexp's to those who need them... That's what I believe to be the best strategy at least.


It's Lua's position to be very small, and strictly ANSI C. It's a design choice to keep everything out of the core, and let extensions be written. PUC themselves write a lot of extensions (IE Kepler, ALua) that are distributed separately, and encourages and helps the community write more.

If I recall correctly a full regex implementation is more source than the entirety of the Lua core (or used to be). Admittedly, I've never been fluent or in love with regex, but Lua's parsing is pleasant and adequate. Most everyone uses it despite regex libs being readily accessible, and I'd guess that the people that write those bindings are just unfamiliar with Lua. I'd say "Lua just doesn't cut it" is a unjust characterization. If you expect to use regex exactly the same as Lua gsub, you will be dissapointed. It's just different. :)

Lua doesn't have direct knowledge of unicode; Lua strings are just strings of data (char). It gives you all the tools you need to work with it, and people do with success.

Discussion

Quote from The Evolution of an Extension Language: A History of Lua [L1 ]:

...
At that point, we could have adopted an existing language, instead of creating a new one.

The main contenders were Tcl ref and, far behind, Forth ref and Perl ref. Perl is not an extension language. In 1993, Tcl and Perl ran only on Unix platforms. All three have highly cryptic syntax. And none of them offers good support for data description. So, we started working on a new language.
... The fact that Tcl left Forth and Perl far behind (in 1993) shows its potential as an extension language. But the point is, for data description, Tcl programmers desperately needed better hashes (I wish we had dict 10 years ago!). -- 20060613 Sarnold

DKF: For the record, dict could never have been done before 8.0; the performance would have been terrible. It wasn't easy to do until 8.4 (when some kind soul reengineered the hash table engine to allow for Tcl_Obj keys and other customized cleverness).


ZB 01.07.2008 "...vaguely C-styled..." - Really "C-styled"? It looks just like Pascal to me, not any C...

Scott Beasley No, C and VB. C was in one speeding car with VB in he other. They hit head-on ;)


zzo38 I prefer Forth, and you can program Forth in Lua, I found one mini-forth programmed in Lua it isn't very good, so I made a lot of improvement to it: http://zzo38computer.cjb.net/luaforth/ It still isn't completed yet. Some of the primitives in there could really work as definitions written in Forth, but some simple ones just aren't, but they could be, as follows:

 : + NEGATE - ; 
 : 1+ 1 + ;
 : ALLOT HERE + HERE! ;
 : -ROT ROT ROT ;
 : <> = 0= ;
 : ?DUP DUP IF DUP THEN ;

and so on.


Scott Beasley 12-02-2008 - My son plays several online games that embed lua in to them for client side scripting, and also server side for some. He asked me to help with a few scripts, and I did as I never get to show-off to my children with my love of coding :) I was initially impressed with lua's easy of use (still am) and speed. lua is VERY, VERY lite and is fast in many ways due to it's weight. I took a few days over the Holiday to "play" with lua. After getting it on my OSX PPC, 2 Linux machines and one XP, I started in earnest. First thing I noticed is that A lot of compiling and configuring of C/C++ to get ANY DARN lib or extension I wanted to use or test. What you notice is there is hardly any lib/package coding in lua itself, and a lot of C and C++ code. Granted the lua interpreter compiled without any issues on all platforms and systems, but most libs/packages took a little to a lot of work to get working on most of the platforms. This was a buzz-kill for me, as I know the power of PURE Tcl/Python etc.... Yes you may loose some speed but you gain the world in platform crossing. Having SO MUCH C etc makes lua fast, but I think faster then it really is. I would love to see something like MD5 or the like in pure lua to really compare speeds. My 2 cents anyway.

As a note, I would like to say I am not knocking lua hard, but just a little :) It is fast, lite and easy to embed, but lacks in the General Purpose areas that Tcl and others have.


SEH 20111129 -- A forum thread that starts out about Guile, then turns into a comparison of Tcl and Lua, with many nice things said about the former: [L2 ]. I liked the following quote:

 I've interfaced Tcl, Guile and Lua to C. 
 In terms of ease, Tcl wins hands down, 
 with Lua a (not-so-close) second.