Near as I can tell, every single emulator with scripting capabilities uses Lua for them, and we've all seen just how awesome the result can be. My question, to the very few of you who care at all is: what is it about Lua that makes it the only contender in this space? More precisely, where does a language like Janet or Wren fall short, outside of popularity (which doesn't immediately translate to UX here)?
I ask because I like Janet, that is the concept of it and the way the project is run, and Lua has thousands of tiny quirks, which are charming but can grate. It would be helpful to know what Janet could do better to fit into this niche, if not for any established emulator then perhaps for some headstrong projects in the future.
Popularity most certainly does affect the user experience. The more popular, the more resources there are, and more people to offer help when someone has questions. Additionally, Lua's popularity also means that a user who has used Lua scripting one place, doesn't need to learn a brand new language just to write a script in another place. Lua is also a highly extendable language without being overly complicated. All classes/objects are just tables in disguise.
I don't know about thousands, but yeah it's got quirks, however, so does every other language too. That doesn't mean the language isn't worth using. Many of Lua's quirks are those that typical uses likely won't encounter anyways.
Besides the fact I've never heard of such languages before (and I suspect the same goes for many people), Janet definitely doesn't look simple or beginner friendly at all. There's a lot of superfluous syntax which gives off a strong esoteric vibe. Plus, there seems to be only one implementation, and its Github repo admits there is no language spec. This means that the number of emulators that can readily use it, is somewhat limited. Some languages may be able to produce C bindings and use it that way, but not all. Also not seeing any clear way of extending the provided functions, may not even be possible. In which case, it is completely useless for the emulator use-case (which requires being able to add custom functions that hook into the rest of the program.)
Wren's syntax is better, but compared to Lua it's also more complex (more keywords and concepts the user must understand). It appears to include some kind of foreign module loading, but it's not super clear to me what's possible. It also has much better docs than Janet, but again no language spec as far as I can see. Otherwise it suffers many of the same problems as Janet.
Lua on the other hand, has much better and more comprehensive docs. It has been reimplemented probably hundreds of times, across many different languages. It's relatively easy to extend. (Programs can provide custom APIs, with or without using imports.)
These are helpful, thanks. There are a few tiny points though:
No const globals and undecorated assignment defaulting to global initialisation are highly visible and simply insane. I know metatables can work around them but at that point it's just a tarpit. Other languages' quirks can't compare to that. Again, not unusable, even charming; just annoying. I don't want to spend too much time on this though because this isn't a hate thread.
Yep, that's true. Familiarity is huge, and often outweighs any technical benefit of something new. So any existing emulator (or application of any kind, really) making a full switch is a bad move; the purpose of this question, though, is to see how such a contender could become a better option for new projects.
Simply false. The syntax simply descends from a different family, and there are enormous benefits to it (macros which don't suck, one-pass compiler which is actually decent).
There are hundreds of bindings to it, but as far as I know only two implementations: PUC and LuaJIT. Every application with a Lua VM embeds one of these as a library, and every binding communicates through the C ABI (which just about any worthwhile language can do). So Janet and Wren are only behind Lua in not having an official spec, which I do admit is a significant point against.
It is 100%possible. Lumping the whole API into a table will be awkward in Janet (though still possible), probably easier in Wren, I don't know; but no respectable "Lua-like" would ever not offer host extension.
Joined: 8/30/2020
Posts: 110
Location: Sydney, Australia
It's because Lua's goal was to be easy to embed from other languages, and while that's not unique to Lua, the network effect made it dominant. There are others which see some use, such as JavaScript, but there simply aren't many embeddable scripting languages which are good by modern standards.
I've made a list alternatives to be considered on the BizHawk issue tracker.
edit:
I think there would need to be a near-perfect language, clearly excelling over Lua in every way, and even then it's not guaranteed to overthrow it.
I could not disagree more, and I'm surprised to hear this from a Rust programmer who I'd assume would be more aware of language design.
Beginners aren't in the habit of properly indenting their code, which makes a missing end difficult to locate. if is not an expression and there's no ternary operator. Variables are global by default, and functions automatically capture locals in their closure, so avoiding side-effects is hard. The default is 1-indexing, which may be more intuitive for beginners, but in this context you'll be working with virtual memory which is 0-indexed, so that's one more facet you have to keep track of. Values have types, but not variables or parameters, so you don't get any compile-time warnings, and runtime errors may or may not be silent. There are no increment/decrement operators. nil is falsey but 0 is not. The length operator # behaves unintuitively with dict-like tables. The concatenation operator .. works with non-strings, but only sometimes. There's an OOP-like method call syntax, but the standard library doesn't use it, so third-party code may be your first encounter with it. Variables are mutable by default, including function parameters (which can't take <const>).
You are likely to run into many of these during your first few hours with Lua. Other "quirks", like silent discarding with multiple return values, are less likely to come up but could still be considered bad design. And the story is even worse for Lua ≤ 5.3.
When compared to a hobby language, I might agree, but Lua's documentation is by no means good. And since its standard library is so small, you'll have to use third-party code anyway (or write your own helpers).
I contribute to BizHawk as Linux/cross-platform lead, testing and automation lead, and UI designer. This year, I'm experimenting with streaming BizHawk development on Twitch. nope
Links to find me elsewhere and to some of my side projects are on my personal site. I will respond on Discord faster than to PMs on this site.