Compare:
(define memcpy
(let ((this (dynamic-link)))
(pointer->procedure '*
(dynamic-func "memcpy" this)
(list '* '* size_t))))
vs. ffi.cdef [[
void * memcpy ( void * destination, const void * source, size_t num );
]]
You also get the ability to add metamethods and finalizers to returned C objects (so you can use Lua's built-in GC to clean up after, for example, your FILE*).As for the speed, there's no reason that a lot of dynamic languages couldn't be as fast as LuaJIT. But none of them are even close. I wish LuaJIT was still up in the computer language shootout. The LuaJIT interpreter (with JIT turned off) is 3x faster than V8 on the PC, and faster than Java on Android. And that's the interpreter - the JITed code is way faster.
Of course, macros are awesome, and a huge point in Guile's favor. On the plus side, Lua is very easy to understand, especially if you're coming from Javascript.