Preferences

I was thinking a while back, how nice it would be if lua was the scripting language in the browser instead of javascript. There are some projects to compile lua to wasm and have it run in the browser...

https://pluto-lang.org/web/#env=lua%3A5.4.6&code=if%20_PVERS...

But interoperability with the DOM is the missing key.

Still, if lua was used instead of javascript, I could see myself saying... man, I wonder what browser development would be like if we replaced lua with x.


What specifically do you think would be better? Lua shares many of JS's quirks (like the relationship between arrays and non-array objects, the behavior of undefined for non-existent object properties, metatables are somewhat similar to JS prototypes, etc.) and adds a bunch more (lack of continue statement, 1-indexing, cannot have nil values in tables).

I can see people liking or disliking Lua and JS both, depending on taste, but it's hard to see someone liking one and disliking the other.

Lua has tail call optimization and js doesn't. For me, this is a dealbreaker for js.

Lua also has operational advantages compared to javascript. You can build it from source in at most a few seconds and run it anywhere that has a c compiler. The startup time is negligible even compared to a compiled c program so you can run entire scripts that do very useful things faster than most js engines can print hello world. There is also the benefit that in spite of what this article discusses, it is possible for most problems to write a lua solution that works for all lua >= 5.1. This is wonderful because it means if I stick to the standard library, the bitrot is essentially zero.

Calling into c is very straightforward in Lua, especially with luajit, which makes it superior to js as a scripting language (the node ffi api is quite painful in my experience and ffi runs against the js execution model).

Lua also essentially got lexical scoping of local variables correct from the beginning while js blessed us with the nightmare of var.

Of course Lua is far from perfect, but while there are some similarities, the differences are quite significant and meaningful.

> Lua also essentially got lexical scoping of local variables correct from the beginning while js blessed us with the nightmare of var.

That was not my experience when I was working with lua. Did anything change since? Asked google. Answered :

> In Lua, if a variable is assigned a value inside a function without being explicitly declared with the local keyword, it will automatically become a global variable. This is because, by default, all variables in Lua are global unless explicitly specified as local.

Yeah, this puzzled me too. I'm assuming they're referring to the semantics of "var" in JS vs "local" in Lua, with the latter resembling "let" in JS, which doesn't have broken scoping.
> Calling into c is very straightforward in Lua, especially with luajit, which makes it superior to js as a scripting language (the node ffi api is quite painful in my experience and ffi runs against the js execution model).

As a scripting language for browsers this is an antifeature, and the fact Lua comes by default with a bunch of features that allow loading arbitrary binary code in the process makes it pretty annoying to properly use it as a sandboxed scripting language.

Why is tail call optimization a dealbreaker for you? That's very specific...
IMHO, Tail call optimization makes sense only when it's enforced (like in clojure), otherwise it's wild.
Guaranteed TCO makes it practical to code recursive algorithms in natural style.
You're conflating a few things here. V8 and Spidermonkey aren't the only interpreters out there. There are a number of them explicitly designed to be small, easy to compile and to embed, such MuJS, Fabrice Bellard's QuickJS, and more still. I can't speak to their FFI interfaces, but you can't judge JS's ability to call C functions based off that of Node/V8. I'm not sure how FFI runs against its execution model given JS is generally used as an embedded language, necessitating foreign function calls.
In theory JavaScript also has it on its standard, unfortunately that is yet another thing that browser vendors don't agree on.
If I remember correctly, TCO is now part of the ECMAScript standard. Safari has implemented it. The issue is that others engines have not because they are concerned about stack unwinding and stacktraces.
I think a lot of people are missing this part, weighing things like 1 based indexing and curly brackets.

All of that is trivial when you consider the Lua reference implementation. It is beautiful.

I agree mostly in that Lua and Javascript are both similar, and like I said in my post above, I could see myself saying the exact opposite if Lua had been included in the browser.

The things I do not like about Javascript can easily be shot down in an argument. Some of it was having to work with Javascript (and it's evil cousin JScript) in the 90s and early 00s.

The type coercion and in the early days people used '=='. I think === did not even appear until ie6?

[] == ![] // true

The lack of a lot of easy helper functions in the standard lib. That now are provided by people writing a bunch of stuff in the npm ecosystem.

The npm ecosystem itself. Lack of security. Lack of... curation? (Also, all this would have probably happened anyway if Lua was in the browser)

I also think javascripts long history has created a legacy of different paradigms

variable declaration var, let, const

function declaration

function f1() {}

const f2 = function() {};

const f3 = () => {};

const obj = { f4() {} };

There is a lot of stuff like this in javascript. I could probably make a blog post about it. But the above gives the general idea of my complaints.

In practice you don't run into these issues often. I'm annoyed when you see different function declaration conventions in the same codebase, but generally () => is used for either one line functions or inline lambdas, and function foo(){} for everything else. Nobody uses var anymore.

The implicit conversions is a definite footgun tho.

Funny you mention nobody uses var anymore when I just saw a post on here yesterday that perf critical code still uses var since it's faster
Bundlers will convert let/const to var, assign classes and functions to var etc but generally people don't write it themselves unless they want to (ab)use its semantics for performance reasons.
Do people often use bundlers for the backend?
For me, JS has just too much magic, in particular the behavior of 'this', and lots of weird quirks, like "for in" vs. "for of". Lua, on the contrary, is very predictable and therfore easy to understand.

One killer feature of Lua (that surprisingly few scripting languages have) is stackful coroutines, i.e. you can yield across nested stack frames. Unlike JS or Python, there is no artificial split between generators and async/await and no need for function coloring.

If Lua had zero-based indexing, it would be close to perfect :)

Have you read large Lua codebases written by others? It is write-only language. All your "very predictable" features are overloadable, at runtime. No static typing to rest your eye on. It is a swamp.

"But, just write good code" you will say. Just like with Perl, some languages are designed in a way to discourage writing good code...

I'm talking about the core language, which I do find very predictable. You can go crazy with any language. Lua is definitely not worse than Python or JS in this regard.

> No static typing to rest your eye on.

That goes for any dynamically typed language. How is that an argument against Lua in particular?

> Have you read large Lua codebases written by others?

No, because I use it as a scripting language, as intended. I totally agree that one shouldn't use dynamically typed languages for building large applications. But again, this is not specific to Lua.

Oh, as a scripting language you embed into your project so that you can write scripts for it — there is hardly anything better than Lua. The C code is super clean and easy to embed and modify.

But once that project gets passed to next maintainer — I'm not sure I'd pick Lua over Forth or Scheme.

Yes, I was going to write this comment a few hours ago but never got around to it. Working on other peoples Lua can be very painful.

Even the fact that people really want to write object oriented code, but every project rolls its own class system is a problem.

When I write lua is just tables of data and functions. I try to keep it as simple as possible.

I've been enjoying writing games for the Playdate, and in Love2d.

if Lua had zero-based indexing it won't be Lua. also removing '.length - 1' globally will reduce gas emissions by 1% worldwide (my guess)
I held a similar opinion several years ago. The main thing is that lua has less magic than js largely because it's been allowed to break compatibility.

My main example is self in lua which is just the first argument of a function with some syntactic sugar vs this in javascript which especially before 'bind' often tripped people up. The coercion rules are also simpler largely by virtue of making 0 true.

Lua has goto instead of continue.

Lua's metatables also cover a fair bit more ground than JS. For example, indexing, math operations (including bitwise), comparisons and equality can be overriden.

Some of thr language features like operators can be overloaded using method tables, much like python's double underscore methods. I do think that the inability to do this in JS is what held it back from becoming a data processing powerhouse. But it perhaps can be made to run fast precisely because of the lack of such overrides (otherwise we'll be running python at JS speeds). That said, LuaJIT seems like a good compromise and might be best of both worlds.
I love JS and Ruby, and I spent a bit of time maintaining a web app in Lua.

There are parts about the language I really enjoy. I like dynamic languages; I don't run into type issues so often it bothers me, but the tooling around Lua still leaves me wishing for me.

Part of this is really my own ability, or lack thereof, but I feel slow and constrained in lua. I have a hard time debugging, but I don't feel these things in other languages.

I like lua better because its minimalist. Javascript feels like a kitchen sink language.

Otoh, missing ++, +=, ..= operators really bothers me.

But that's just personal taste, not objective by any means.

Yeah. I think if I were to pick one reason, it would be Lua is "minimalist". But, like I wrote, maybe, it too, would have just had lots of stuff added onto it if it had been in the browser. Hard to say.

I love ++, but you know what? I was shocked when a co-worker pointed out that it is frowned upon to use ++ in javascript. It some big companies, their linter settings mark ++ as something that should be changed.

https://eslint.org/docs/latest/rules/no-plusplus

Lol, i suppose there is no accounting for taste, but the justification for that rule is really something.

Appearently its really confusing if you put a bunch of newlines between the ++ operator and its ophand. No kidding.

The origin of this rule was that Douglas Crockford doesn't like ++.

From JavaScript: The Good Parts (May 2008):

> The ++ (increment) and -- (decrement) operators have been known to contribute to bad code by encouraging excessive trickiness. They are second only to faulty architecture in enabling viruses and other security menaces. The JSLint option plusplus allows the use of these operators.

Needless to say, I'm with you and hackthemack on this.

Nil is better than how undefined works. It's not just as bad and then more bad on top.
There’s also a Javascript implementation of Lua which allows one to run Lua in a browser:

https://github.com/fengari-lua/fengari-web

I don’t know if this can access the DOM in Lua, but considering that Fengari is in Javascript, adding a _DOM global variable should not be too hard (if it hasn’t already been done).

Fengari lets you access the DOM. Its pretty cool.
No need for _DOM.

    local js = require "js"
    local window = js.global
    local document = window.document

    window:addEventListener("load", function()
        local el = document:getElementById("main")
        el:addEventListener("click", function(evt) js.console:log(evt.target) end
        document.body:appendChild(el)
    end
IIRC Brendan Eich has talked about this - if he’d adopted Lua in 1995 instead of creating JavaScript, it wouldn’t have been Lua 5.x but Lua 2.x.

Lua has improved substantially from version to version because it’s been able to break compatibility. That wouldn’t be possible in the browser, so today we’d still be stuck using (an augmented version of) the outdated Lua 2.x.

Yes, he did:

https://web.archive.org/web/20191024193930/https://twitter.c...

“Lua in 1995 was very different, no coros e.g., and no one would be happy if it flash-froze and then slow-forked on a different path from Lua's. See https://www.hackerneue.com/item?id=1905155 and yes, wasm is the right long-term plan. In 1995 it was supposed to be Java, but that didn't pan out!”

Fengari has DOM interop.

http://fengari.io/

It is a Lua reimplementation in JS.

There is also nelua (https://nelua.io/) which can use WASM to compile allow its usage in the browser: https://github.com/edubart/nelua-game2048/

This item has no comments currently.

Keyboard Shortcuts

Story Lists

j
Next story
k
Previous story
Shift+j
Last story
Shift+k
First story
o Enter
Go to story URL
c
Go to comments
u
Go to author

Navigation

Shift+t
Go to top stories
Shift+n
Go to new stories
Shift+b
Go to best stories
Shift+a
Go to Ask HN
Shift+s
Go to Show HN

Miscellaneous

?
Show this modal