QuickJS is presumably intended for embedding within applications - how does it compare to Lua for this?
Both languages are fairly quirky - at least JavaScript’s quirks are widely-known. But how do the implementations compare in terms of API, robustness, portability, performance etc?
Also, I’m not aware of any static typing add-ons for Lua, but presumably it’s possible to use TypeScript with QuickJS?
> ...but presumably it’s possible to use TypeScript with QuickJS?
I don't see why not, since TS compiles down to JS. The engine doesn't know or care about what kind of transformations the code went through before it was JS. You might need to be careful about compatibility, the QuickJS intro says 'Almost complete ES2023 support", so you'd have to avoid any unsupported features.
Teal (https://github.com/teal-language/tl) is the closest we have from a "TypeScript for Lua". It is natively supported by many projects now, including game engines such as the Bevy scripting plugin and Defold.
On the other hand, my understanding is that the transformations the TS compiler does to the code is just stripping annotations, so it's not unreasonable to call it an add-on.
I have been using TypeScript for quite sometime but it's my first time learning of one gradually typed language. I always decribed TypeScript as optionally statically typed
From my observations: cold start, ease of patching.
If you're running a lot of different JS code or restarting the code frequently, it's faster than node.
Where it's useful: fuzzing. If you have a library/codebase you want to fuzz, you need to restart the code from a snapshot, and other engines seem to do it slower.
It's also really easy to patch the code, because of the codebase size. If you need to trace/observe some behavior, just do it.
Because the main goals are to be small, embeddable, and have low startup time.
A top class engine requires a JIT and that generally leads to being large and having high startup time. LuaJIT is pretty much the exception which proves the rule and 1. Mike Pall is a monster of a developer not unlike Bellard; and 2. Pall is on record (in discussions with other JIT people) that in his opinion you can’t bolt a JIT to an existing runtime and get a maximally efficient JIT. So you’d need someone of that class of skill to decide to make that their legacy.
And it's not like that Bellard is unable to produce a JIT compiler; see, for example, QEMU dyngen [1] which eventually inspired CPython's new JIT compiler.
Like other replies said, having JIT requires quite different tradeoffs to be made.
And unfortunately, making a very fast interpreter-based JS engine is a tedious and human-power-heavy work, it involves a lot of work which can't be eliminated by better skills.
Apparently Figma still uses it for plugins, so there's that.
It can be compiled to WebAssembly and run with the sandboxing of WebAssembly. Not just data sandboxing but sandboxing that can prevent it from slowing down the rest of the app (though it runs slower).
This in 2023: "Either Figma hasn't updated QuickJS since, or they've moved to a different VM, because Figma's VM is missing many of the features QuickJS now supports." https://www.sam.today/blog/bumbling-the-figma-api
fetch is a WHATWG standard, not ECMAScript. Qjs devs have made a language interpreter and not a scripting environment.
You can use txiki [1] for that, it has fetch.
I think because it runs inside a WebAssembly sandbox, but maybe someone with hands on experience can explain what's necessary to make calls outside that (if it's possible at all).
I would be careful to use this in production. I'm a diehard C and C++ fan, but: Having a mutex unlock inside an if statement that performs an early return, on line 52000 something, does not inspire confidence.
Excellent job on building this, and it's very readable and nice, otherwise!
It looks like the mutex is theoretically sound.. unlocked before all returns, as long as there isn't an exception raised in between. I wonder what the parent comment's issue is.
Oh yeah of course its sound, but this is not how you write C code, because all it takes is for someone else in 10 years to, somewhere between 51000 and 53000 introduce an early return statement and forget to unlock that mutex, or other little things.
This is solved in C usually with a goto to a cleanup routine, and avoiding early returns.
Both languages are fairly quirky - at least JavaScript’s quirks are widely-known. But how do the implementations compare in terms of API, robustness, portability, performance etc?
Also, I’m not aware of any static typing add-ons for Lua, but presumably it’s possible to use TypeScript with QuickJS?