3 ms·
This is a tweaked/updated version of a stackoverflow answer I wrote (see end for link) to someone wanting to know what language they should use for embedding:
by snogglethorpe 14y ago
This is a tweaked/updated version of a stackoverflow answer I wrote (see end for link) to someone wanting to know what language they should use for embedding:
Lua, and Lua's standard implementation(s), capture a wonderful balance of features/smallness/speed/usability, particularly for embedded use.
Lua:
1. Is very small, both source and binary, an order of magnitude or more smaller than many more popular languages (Python etc). Because the Lua source code is so small and simple, it's perfectly reasonable to just include the entire Lua implementation in your source tree, if you want to avoid adding an external dependency.
2. Is very fast. The Lua interpreter is much faster than most scripting languages (again, an order of magnitude is not uncommon), and LuaJIT2 is a very good JIT compiler for some popular CPU architectures (x86, arm, mips, ppc). Using LuaJIT can often speed things up by another order of magnitude, and in many cases, the result approaches the speed of C. LuaJIT is also a "drop-in" replacement for standard Lua: no application or user code changes are required to use it.
3. Has LPEG. LPEG is a "Parsing Expression Grammar" library for Lua, which allows very easy, powerful, and fast parsing, suitable for both large and small tasks; it's a great replacement for yacc/lex/hairy-regexps. [I wrote a parser using LPEG and LuaJIT, which is much faster than the yacc/lex parser I was trying emulate, and was very easy and straight-forward to create.] LPEG is an add-on package for Lua, but is well-worth getting (it's one source file).
4. Has a great C-interface, which makes it a pleasure to call Lua from C, or call C from Lua. For interfacing large/complex C++ libraries, one can use SWIG, or any one of a number of interface generators (one can also just use Lua's simple C interface with C++ of course).
5. Has liberal licensing ("BSD-like"), which means Lua can be embedded in proprietary projects if you wish, and is GPL-compatible for FOSS projects.
6. Is very, very elegant. It's not lisp, in that it's not based around cons-cells, but it shows clear influences from languages like scheme, with a straight-forward and attractive syntax. Like scheme (at least in it's earlier incarnations), it tends towards "minimal" but does a good job of balancing that with usability. For somebody with a lisp background (like me!), a lot about Lua will seem familiar, and "make sense", despite the differences.
7. Is very flexible, and such features as metatables allow easily integrating domain-specific types and operations.
8. Has a simple, attractive, and approachable syntax, which can be important if you intend to have end-users write scripts.
9. Is designed for embedding, and besides its small size and fast speed, has various features such as an incremental GC that make using a scripting language more viable in such contexts.
10. Has a long history, and responsible and professional developers, who have shown good judgment in how they've evolved the language over the last 2 decades.
11. Has a vibrant and friendly user-community.
Stackoverflow link: http://stackoverflow.com/questions/7919763/lua-vs-embedded-lisp-and-potential-other-candidates-for-set-based-data-processi/7927730#7927730 http://stackoverflow.com/questions/7919763/lua-vs-embedded-l...
- _dps 14y agoLet me add my favorite hobby horse to your point 4: LuaJIT's C FFI is a tremendous and undervalued advantage compared to any other language/implementation I've used. Its core value proposition: 0) It can parse C header files and automatically construct bindings. 1) You can write Lua code that works directly on C data types with C memory layout and is JIT compiled. It makes it very easy to achieve performance within ~2x of C while still maintaining the expressiveness and extensibility of Lua. And if you miss writing OO C++, you can easily add methods to your C structs and they will be JIT compiled. See here http://wiki.luajit.org/Allocation-Sinking-Optimization http://wiki.luajit.org/Allocation-Sinking-Optimization and search for "Point Class with FFI cdata Struct" and then "Point Class Benchmarks". 2) Because the memory layout matches C data types, it is trivial to swap out a Lua implementation of a core operation with a C implementation if that becomes necessary. 3) It is easy to write cross-platform systems code without conditional compilation because the native calls through FFI can all be constructed dynamically through Lua (so instead of #ifdef WIN32 all over your socket code, you just have a single line checking for ffi.os == "windows" and then if necessary call the winsock initializer as ffi.C.WSAStartup(foo,bar)).
- snogglethorpe 14y ago> LuaJIT's C FFI is ... Indeed LuaJIT's FFI is a very cool and usable, but it does one huge drawback: it basically ties you to LuaJIT. I'm not trying to diss LuaJIT—it's a wonderful and impressive JIT implementation, and for some applications, irreplaceable—but compared to the standard Lua implementation, LuaJIT is (1) less portable, (2) more complicated, and (3) has various implementation drawbacks.† In addition, of course, there are other alternate Lua implementations which have their own set of tradeoffs. Essentially, it's very nice to be able to switch Lua implementations depending on the circumstance. With normal usage, LuaJIT is carefully designed to make this possible (indeed, easy: one need only change the library one links against, it's not even necessary to recompile one's app), but once you start using things like FFI, that ability is lost. There's a port of LuaJIT's FFI interface to standard Lua, but it's also not portable, and because it will have very different performance characteristics than FFI in LuaJIT (which can "compile out" FFI accesses), it's not really a drop-in replacement for it, and I think not nearly as compelling. † The one that's bitten me in the past is that LuaJIT has a much smaller limit on addressable memory than standard Lua because of the particular design of its nan-encoded object representation. There are some input files for my Lua-using app that will only work when I compile with standard Lua, because using LuaJIT will run out of memory; those are times when I'm very glad I didn't commit to a LuaJIT-only design...