I've lamented for a while that, while JS engines are flourishing from a speed perspective, there has never been one as small or embeddable as Lua.
Now we have JS as embeddable as Lua, and nearly as small (it probably can't be quite as small because Lua is a simpler language).
Now the only thing Lua has on JS, implementation-wise, is an implementation that is very small/embeddable and very fast (LuaJIT). LuaJIT is also about as small as a JIT-compiled interpreter can be.
> Now the only thing Lua has on JS, implementation-wise, is an implementation that is very small/embeddable and very fast (LuaJIT).
Well, and a simpler, more regular syntax. Simpler semantics. Real coroutines. Tail call elimination. Multiple returns. Better iteration syntax and protocol. Better lexical scope. Operator overloading. A well-established FFI. No weird variable hoisting, nasty implicit conversions, semicolon insertion, etc.
But, sure, aside from those things, Lua doesn't have anything on JS as a language. (Of course, as an ecosystem, JS is miles ahead.)
Your parent explicitly stated that he's talking about JS implementations and not about the language. All you've said may be true, but it's completely off-topic and has no relation to the parent post at all.
Still interesting to people not knowing the other advantages Lua has. Might get some interested in the language.
Not everything has to be strictly on-topic to have merit, especially since we've already derived from the topic (from a specific embeddable JS engine to the comparative merits, implementation wise, of JS vs Lua).
Those are all very important comparisons (and I would add that both Lua and JS got the global by default thing wrong0. I would note that ES6 requires proper tail calls and that trampolining can accomplish tail call elimination (tail call elimination is different than proper tail calls).
The major issue to me is time. I know quite a few languages, but have only mastered a couple. JS is everywhere and the browser makes sure this will be the case for a long time.
The issue is that these advantages do not outweigh the ubiquitous nature of JavaScript. If I already need to learn all of those JS quirks, why learn Lua too?
I still think that https://love2d.org/ is one of the easiest, most fun and rewarding ways of stepping into game programming (especially when compared with the currently existing JS Game Dev Frameworks).
The issue is that these advantages do not outweigh the ubiquitous nature of JavaScript. If I already need to learn all of those JS quirks, why learn Lua too?
In my case, because Awesome is a nice window manager.
Although on this theory, I should really have learned some Haskell by now. And yet. Every trip to the xmonadrc is a fresh glimpse at the depths of my own ignorance.
I wanted to reply exactly that but then noticed that op is talking about implementations, not the language itself.
I'd still prefer programming in lua to programming in javascript where possible. Honestly, the only advantage of javascript outside the browser are the hordes of people who already sort-of know it (and often don't want to learn anything else).
I love LuaJIT but I am starting to feel seriously uncomfortable about its memory limitations.
64-bit LuaJIT can only use memory allocated within the first 2 GB. Mainstream desktop systems consume more and more memory so by the time you fire up your LuaJIT app there might be (next to) no memory left within that range.
32-bit LuaJIT can use the first 4 GB but again sooner or later desktop systems will leave little there too + 32-bit code is already deprecated technology on the desktop.
Makes me damn sad really. Unfortunately making LuaJIT capable of using the full address space requires a major rewrite.. one which will likely never happen. LuaJIT's author has moved on to other projects and LuaJIT is now in maintenance mode, getting nothing but small fixes.
Seriously if you are a Mike Pall-grade elite low-level hacker (I am talking to all four of you ;) ) would you please continue LuaJIT development?
IIRC, he's said that even if the pointer model gets extended, the garbage collector's not up to scanning more than 2GB efficiently so your programs will run like a slug.
Also, it's worth remembering that the 2GB limit only applies to Lua objects. Objects allocated through the FFI API aren't limited by this. So any pure data structures which don't contain Lua object pointers can be allocated with simple malloc(). It'll be loads faster that way, too.
If I could be sure that LuaJIT has access to all the memory the GC can efficiently handle I would be happy. Again the problem is that LuaJIT may only be able to allocate a few MB or even no memory at all on a desktop system where the user starts your LuaJIT(embedding) app after the first 2GB of address space are eaten up. And that scenario is becoming more and more likely every year because the RAM requirements of mainstream desktop systems certainly are not going down.
Right now I do not feel comfortable offering a LuaJIT app for download because it may crash immediately with an "out of memory" error when the user has some memory heavy app running in the background.
How does system memory usage stop Lua from addressing memory in its own address space? That doesn't at all fit with my understanding of how virtual memory works in modern operating systems.
It appears LuaJIT employs optimizations that assume that its pointers fit in 31 bits. This wouldn't be particularly surprising, fast interpreters often try and steal bits from pointers for lots of reasons, e.g. inlining values (so the indirection is eliminated), encoding the class type in the pointer (some JVMs have done this), etc.
LuaJIT stores non-number objects as NaN floating point values. (A NaN value has 48 bits of payload which can be set to anything.) LuaJIT uses 16 bits of that value for the type and the remaining 32 bits as payload, so pointers are limited to 32 bits.
If you control the application that is embedding LuaJIT, you should be able to reserve (but not commit) that address space early on in the application startup.
Other applications won't affect your own process's address space.
Thanks for the interesting link. If I am reading it correctly, they are planning to do the thing that Mike Pall tells people not to do: target LuaJIT bytecode [1]. I'm very curious to see how that will work out.
Pall is thinking about how to create the most efficient implementation here and of course compiling to LuaJIT bytecode is not optimal there. However compiling to JVM bytecode is not optimal for any language except Java either, yet everyone and their dog does it.
Accepting sub-optimal performance in exchange for getting a JIT, garbage collector etc. for free seems like a good deal in many cases. Note that Pall estimates a development time of multiple years (!) for the optimal solution.
I wonder if they'll beat castl [0], which compiles JS to goto-enabled Lua (Lua 5.2+ and LuaJIT).
Targeting the bytecode directly will not buy much, it is very close to Lua itself, semantically. The LuaJIT parser and bytecode compiler are also wicked fast.
Furthermore, IIRC, the JIT works best with idiomatic Lua code, compiled to "kosher" bytecode by LuaJIT itself.
I've lamented for a while that, while JS engines are flourishing from a speed perspective, there has never been one as small or embeddable as Lua.
Now we have JS as embeddable as Lua, and nearly as small (it probably can't be quite as small because Lua is a simpler language).
Now the only thing Lua has on JS, implementation-wise, is an implementation that is very small/embeddable and very fast (LuaJIT). LuaJIT is also about as small as a JIT-compiled interpreter can be.
But it looks like Tessel is working on filling that gap as we speak -- they are working on targeting LuaJIT for their JavaScript implementation http://blog.technical.io/post/102381339917/a-new-engine-for-...