Hacker News new | past | comments | ask | show | jobs | submit login
Nelua: AOT statically typed Lua (nelua.io)
155 points by gatane on Jan 26, 2023 | hide | past | favorite | 51 comments



Wow, amazing stuff. I love Lua, it was how I learned programming as a kid. Coincidently from the same world as the author. Open Tibia.

The author made a custom client (https://github.com/edubart/otclient) for the game that is still very much in active use by thousands of players. He's a very skilled developer.

Great to see AOT compiled Lua, I know of the other solutions: Luau (from Roblox), Teal, TypeScriptToLua, Terra, etc., but this one is my favorite so far.

Love the simple compilation to C (and WASM support via Emscripten). Though Terra's JIT is enticing and good replacement for LuaJIT, this is for embedded systems, it's a good replacement for Lua PUC-Rio.

Typed Lua Projects:

- https://luau-lang.org/

- https://terralang.org/

- https://github.com/teal-language/tl

- https://typescripttolua.github.io/

There's also a language server for Lua dialects for type checking in the IDE:

https://github.com/sumneko/lua-language-server


Although deviating slightly from the original topic. I find it very interesting and nostalgic that other people here have started, possibly, their programming careers through Open Tibia. I myself have, as you did, started programming with Lua on Open Tibia and used to be very active in the community as a kid sharing scripts and projects (The community was always very supportive and made me feel like I could have a career doing it - definitely a great boost for me). It's great to see that Lua is still so relevant (perhaps even more so than when I started) and that it keeps being pushed forward. Congrats to the author for releasing this project.


The FAQ doesn't cover "how does this differ from lua", but overview contains the disclaimer:

> not all Lua features are implemented yet. Most of the dynamic parts, such as tables and handling dynamic types at runtime

It has coroutines to some extent

> At the moment Nelua does not support variable arguments in yield and resume (unlikely Lua).

It also extends lua primitives - lots of control flow things, arrays and records which look like tables but are passed by value, not by reference.

So it's an ahead of time statically typed language which looks somewhat like lua. Compiled to C, no interpreter. It says it's meta-programmable using lua which I assume is really confusing given the two languages look similar and behave differently.


One under-advertised feature of the language is that it supports WASM: https://github.com/edubart/nelua-lang/discussions/11

It’s been used successfully to make games for virtual game consoles like wasm4 and GamerCade.


>"Compiled to C"

Must be fun to debug generated C code.


It's very easy with the "#line" macro. Works perfectly with gdb too, at least in Nim-land debugging embedded firmware via JTAG.


C compiles to assembly, Chez Scheme compiles to C, Idris2 compiles to Chez Scheme. They are fine languages to work with.


To each their own. If I can't step through original code when debugging I am not interested. I've had my share of debugging machine codes. Do not want anything resembling it.


#line directive gives you exactly that, you step through original code, it's similar to source maps in JavaScript. #line directive has two arguments the file name and the line of the source in your language i.e. nim, nelua, koka whatever. Debuggers support it for decades. Having said that, printing variables and making debugger aware of the type system of the original language is another story maybe someone can comment on that.


Neat! Another compile-to-C language. As someone who's using Nim in production building embedded firmware, this is such a handy feature for us. Being able to use the language wherever C can be used is huge, and Nelua looks like it produces even more human-readable output than Nim with -d:danger does, impressive stuff!

The interop benefits of compile-to-C are so useful for my work that it's always exciting to see another language take advantage of it. Of course it has some downsides, but being able to leverage existing C libraries (source-based or binary-libs) with the worlds simplest bindings is fantastic, even when those source based libraries do really funky things with macros and such. Inspecting the C output of the language to ensure the binding matches is great :)


Similar to Terra https://terralang.org/


Indeed, almost the entire pitch reads like a recapitulation of the pitch for Terra 10 years ago. There are a few different design choices, but discussion of Terra is a striking omission from the FAQ.


I already asked this question exactly 2 years ago: https://github.com/edubart/nelua-lang/discussions/51


Do you agree with edubart's runtime vs. compile time distinctions between Nelua and Terra?

I was interested in Terra a while back, but it didn't seem to get a lot of traction. This three-year-old critique put the nail in the coffin for me:

https://erikmcclure.com/blog/a-rant-on-terra/


That was somewhat of an entertaining read.

> Terra is C if you replaced the preprocessor with Lua.

This is what is written on the tin.

PUC made there own version of Terra

Pallene http://www.inf.puc-rio.br/~roberto/docs/Gualandi-2020-SCP.pd...

https://github.com/pallene-lang/pallene

https://www.youtube.com/watch?v=H3inzGGFefg

This is a good writeup on all the Alt-Luas https://injuly.in/blog/gsoc/


Related:

Nelua Programming Language - https://news.ycombinator.com/item?id=28293836 - Aug 2021 (118 comments)


Is a Lua that compiles to C anywhere near as useful as a JIT Lua? I thought one of the major use cases for the language was run-time scripting. Am I misunderstanding?


"Nelua is a systems programming language for performance sensitive applications, like real-time applications and game engines. Its syntax and semantics are similar to Lua, but its garbage collection is optional, it provides optional type notations, and it is free from an interpreter. Nelua uses ahead-of-time compilation to generate optimized native binaries. It is metaprogrammable at compile-time using Lua and it is simple and easy to use."

This seems to mean that you can't drop a Nelua script into a game/engine and use it. You have to compile the script and link with the game? Something with either an interpreted mode or runtime code generation seems more appropriate.


If you are interested, the README.md [1] explains everything in detail.

[1] https://github.com/edubart/nelua-lang#about


This part clears it up:

> The initial motivation for its creation was to replace C/C++ parts of projects which currently uses Lua with a language that has syntax and semantics similar to Lua, but allows for fine-grained performance optimizations and does not lose the ability to go low level, therefore unifying the syntax and semantics across both compiled and dynamic languages.

So it's ideal if you have an app written in (dynamic) Lua and use Nelua for AOT parts to speed it up.


Interesting, a lot of new languages are dynamic languages with types.

You should try crystal lang if you love writing ruby code.

crystal lang has both interpreter and compiler, so that you can debug with interpreter during development and run compiled binary in production.


Hard to tell. But currently the Crystal type system is a bit restricted.

For example, you can't express this in crystal, like in Typescript:

    type Easing = "ease-in" | "ease-out" | "ease-in-out";


Why would you want that over enums?


Enum is limited for integer value.


You can define string enum type with a macro.

https://github.com/crystal-lang/crystal/issues/10281#issueco...


The internal representation doesn't really matter, does it?


Many languages to choose from, that's great

I wish the same could be said about tooling

How is the debugging story? gdb/ldb compatible? does it support its types?

Is there a language server available? formatter?


> gdb/ldb compatible

As it is compile-to-C and the #line macro is very easy to output in these languages, I'd nearly guarantee "yes" as the answer to that.

Despite nothing else really being aware of Nim, I debug embedded firmware written in it, on a microcontroller via JTAG and gdb/openocd, and it works perfectly.


Teal is great for this - statically typed and compiles down to lua. I’ve even integrated it into other languages because teal is written in teal (compiling down to lua, which can be run on lots of different devices!)

https://github.com/teal-language/tl


I want to start adding support for Lua derivatives to my IDE - which adds static type checking to regular Lua. Inference, structural & nominal types, generics etc. (Luanalysis - https://github.com/Benjamin-Dobell/IntelliJ-Luanalysis/)

I feel like plugin support would be best but I've no idea how that's supposed to work in the presence of a predefined grammar. There's also so many variants I don't think there's a good way to build out a composite grammar.

Does anyone have any ideas about modular/extendable language parsing? For reference, I'm using https://github.com/JetBrains/Grammar-Kit.


The million dollar question: has anyone written a Lua interpreter in Nelua yet?


What's AOT mean? It doesn't appear anywhere on the article.


It compiles Ahead Of Time, i.e. you compile to a binary which then can be executed, as opposed to intepreted, like Lua, or JIT (Just In Time - i.e. compiles at runtime when required/hot path) like LuaJIT.


Ahead of time.


If anyone can give me the history of compile-time VMs as compilers, i'd be interested. It's the obvious solution to making static langs as usable as dynamic, but seems to have exploded in lang-design popularity over the last decade.

Who was the first to do it? Why? What did they inspire?

I take it Jonathan Blow has been a significant inspiration, but there's clearly prior art to this approach.


oh well


Another stab at a "typed Lua" is this paper by one of the original authors of Lua: https://doi.org/10.1016/j.scico.2020.102393

The paper describes the language Pallene


Quite sad to see Discord and Reddit being used as "Community" channels.


Can I transpile this "Lua" to LuaJIT (5.1/5.2) and run it in nginx?


LuaJIT + nginx event loop is probably the fastest network runtime in existence. Is there a faster one? In terms of writing high-level code that executes at the speed of the machine.



I'm not sure of the speed, but F5 load balancers run a custom version of TCL to process requests. [1]

Been that way for a long time, so I imagine it has been pretty optimized over the decades.

https://techdocs.f5.com/kb/en-us/products/big-ip_ltm/manuals...


Article from F5 website:

"Tcl, The How and Why"

https://web.archive.org/web/20131205081839/https://devcentra...


F5 acquired nginx. I would be surprised if their stuff isn't running Lua now


I would be extremely surprised if they don't still support traditional iRules syntax (or even offer Lua, honestly). This is hardware that gets used by banks and governments; they don't just switch their API, with all the massive re-training that would entail, in a few years. There is a gargantuan amount of legacy code and support to consider.


This is very neat. I find myself wishing for a Fennel conversion…


I low-key dislike when people nitpick titles, but in this case I'll do it (:

The title makes it sound like this is a variant of Lua, or somehow largely compatible.

The page itself is more clear, calling it a "programming language with a Lua flavor".

Emphasis on "flavor".

I feel like the list of differences from Lua is about as big as the similarities, and it's definitely not a drop-in replacement, at least in its current form (contrast with something like LuaJIT).


I'm not sure if that's the intent, but "ne Lua" literally means "not Lua" in most Slavic languages.


Of the features to selectively take from Lua, the syntax is one I like. Pascal-style syntax does not have the statement separation issues a more expression-rich language like JavaScript has. It not only does not have statement separators, it is almost completely whitespace agnostic.

As a strategy to get adopters, it could also have value. There's a small but widely spread group of people who have been exposed to Lua in various games and programs.


To me the killer language feature of Lua is tables, specifically being able to use ANYTHING as an index in a table. Really powerful. Its portability is its next feature.

Beyond that, I have grown to somewhat dislike Lua over the years due to the typical complaints, but also because it's tough to read and write. The keywords are so bulky and whitespace practices are random, requiring a linter. I actually like using brackets instead of do/then/end because brackets stand out more. When you're tossing functions around left and right, it's annoying to write out "local function" everywhere. I also am ambivalent about using metatables for implicit behavior that can be non-obvious to the code reader.


Unfortunately Wren adoption is practically nonexistent.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: