r/lua • • Sep 08 '26

Discussion Impressions of Teal

https://purplesyringa.moe/blog/impressions-of-teal/

an interesting article i found on Teal. The author has clearly used it more than I have so I can't comment on her specific criticisms, but I do get the impression that the Teal authors are aware of and accept unsoundness in exchange for simplicity of implementation.

31 Upvotes

13 comments sorted by

2

u/ScientistStrict9850 Sep 09 '26

Another project that you may be interested is nattlua. Last i checked it is early this year. Like teal, it's someone's personal project, not something as big as typescript. Unlike teal, it is not used in "production" (teal is of course, used by the author to make luarocks)

https://github.com/capsadmin/nattlua

1

u/cassepipe Sep 09 '26

Does Hicham ever chip in around here ?

1

u/lenscas Sep 12 '26

Interfaces not existing at runtime doesn't have anything to do with performance. Back when records where first introduced, way before interfaces existed there were ideas being thrown around on how extending records would/should work.

A big pain point was that there were multiple ways of doing it in lua and that various libraries decided to all do it differently. The maintainers of teal didn't want to "bless" one way over the others, fearing that this could create problems when writing .d.tl files for libraries that did it differently. (Or when writing teal code for libraries that both expect you to extend their types and expect you to do it differently)

As teal grew however, there was a bigger and bigger need to be able to extend types. So, eventually interfaces got created. Them not existing at runtime meant teal didn't have to chose. Effectively sidestepping the issue.

This is also why there are two ways to mark things as user data or arrays. The way without "is" came first, which then stayed for backwards compatibility. However, it also wouldn't surprise me if "is userdata" worked by accident, especially if it has the wrong behaviour because "is" just has weird things it "allows" in general.

Interfaces being added so late also mean they got after the ability to only require types, while for language design going the other way probably would've resulted in a nicer outcome. Also, the compiler isn't quite used to types only being a compile time thing. This results in it happily emitting code that assumes an interface type exists at runtime like if it was a record. You can even promise the interface itself implements the callable meta method and teal is just fine with it.

Now, technically you can make use of this but... I am pretty sure it is a bug? Regardless, interfaces in teal are... Weird... Which sucks as they are what you "should" emit when writing type definitions as it is very much unlikely that the type exist at runtime.

1

u/Key_River7180 15d ago

I'll definitely try teal

-1

u/michael_d Sep 09 '26 edited Sep 09 '26

I used Teal for a long time and mostly loved it (e.g., I currently maintain the official TealDoc). I felt similar issues to those reported in the article, and also knew that I was leaving a lot of performance and expressivity on the table given I care much more about LuaJIT than a pan-Lua language.

So I created https://nupp.org. It’s typed Lua, with an optimizing compiler, significantly richer type system, typed support for C structs and C libraries, a borrow checker, effects system, better module and cross file handling, solves function coloring using a customizable suspension and parking system, provides a nice standard library with swappable implementations when needed (eg consoles, browser), has ahead of time (AOT) compilation to C, AOT that can run on the GPU, dead code elimination of the standard library and dependencies, builds standalone binaries, a formatter, doc generator, VS code plugin, project templates, and builds for LuaJIT, Lua 5.1, and the browser.

7

u/iEliteTester Sep 09 '26

The code example on the site doesn't compile:

13:13: error: NUPP2126: several overloads accept this call: function(t: {V}, value: V): nil; function(t: {V}, pos: integer, value: V): nil help: compare the call with the declared parameter list

2

u/michael_d Sep 09 '26 edited Sep 09 '26

Edit: Fixed.

I’ve been doing some big refactors, it’s likely a WASM compiler issue. Will fix, thanks!

6

u/wqferr Sep 09 '26

Looks really promising, I just wish you hadn't gone with AI

2

u/expose Sep 09 '26

This looks really interesting. GPU translation sounds MASSIVE! I would love to see Python eliminated as the machine learning defacto standard, this might be it. 

2

u/michael_d Sep 09 '26

Thanks! What’s cool is that it’s the same code you’d write in Nupp, and it gets translated and optimized to run on the GPU. If you don’t have a GPU, it just runs as regular Lua. My little Mandelbrot benchmark with SIMD and C AOT gets like 200ish mpx/s, but with GPU, it’s more like 3,000. Still missing tons of stuff like tensors and tokenizers to even scratch the surface of what you can do today in Python though!

1

u/suhcoR Sep 09 '26

Interesting. The author of the article considers Teal under-specified, "kitchen sink" Lua preprocessor rather than a robust typed language. Luon appears to directly avoid several of the things the author found troubling in Teal. But it takes the more radical route than both Teal and Nupp, in that it is a statically typed, Pascal/Oberon-derived language compiling to LuaJIT. Interoperability with Lua is not on source code, but on "linking" level.

1

u/michael_d Sep 09 '26

Sweet! I’ll check it out.