top | item 29659336

Lua: Good, Bad, and Ugly Parts (2012)

202 points| Svetlitski | 4 years ago |notebook.kulchenko.com | reply

94 comments

order
[+] linkdd|4 years ago|reply
Lua is a very nice piece of technology. Its source code is pretty easy to get into, the documentation is complete.

It has its quirks yes, but if I need to add scripting to a software, I'd consider Lua before considering writing a DSL, simply because you can pretty much embed Lua's source in your C/C++ software as a static library[0].

The stack-based approach makes it so easy to interact with C/C++, and I've been looking at the Rust bindings[1] recently out of curiosity, looks promising.

  [0] - https://github.com/lubgr/lua-cmake
  [1] - https://github.com/amethyst/rlua/blob/master/examples/guided_tour.rs
[+] aeternum|4 years ago|reply
Since this is a Lua thread, your reference list should probably start at 1 rather than 0
[+] cies|4 years ago|reply
If you need a few line here an there scripting, sure Lua, JS, PHP... whatever works.

Using these languages for large projects is where the trouble starts: as they push you towards bad solutions that we know are bad for many decades. You need clear description of how to avoid these pittfals, or your growing codebase slowly becomes unmanageable.

I ended up ditching a growing Lua codebase for this reason. Get out before it gets to big to get out.

[+] lmm|4 years ago|reply
Why Lua rather than e.g. TCL or Python (both similarly easy to embed, but better-known as full-fledged languages)?
[+] leephillips|4 years ago|reply
At first Lua seems strange, but after a while you start to appreciate it. It’s designed with a small number of concepts that manage to lead to expressive code with excellent performance.

I use it for two things: scripting TeX¹, where it allows you to do amazing things², even complex numerical calculations³ within the document; and writing Pandoc filters, where it is now the standard method.

1 ‘LuaTeX comes of age’. LWN. Available from: https://lwn.net/Articles/731581/

2 http://wiki.luatex.org/index.php/TeX_without_TeX

3 http://www.unirioja.es/cu/jvarona/downloads/numerical-method...

[+] nerdponx|4 years ago|reply
I really appreciate that the article has a "Different" section for things that are different from, but not necessarily better or worse than, other programming languages.

This is also a very good summary, and tracks with my own experience getting into Lua for Neovim scripting.

[+] spc476|4 years ago|reply
This was written just after Lua 5.2 was released. There have been improvements since then. Lua 5.3 introduced an integer type (64-bit), actual Boolean operators, a UTF-8 library, a way to yield across a C-boundary and a way to pack and unpack binary data. Lua 5.4 introduced deterministic finalizers (and a fall out from that is a limited form of constant local variables).
[+] BoogerDan|4 years ago|reply
Lua appeals to my sensibilites and I want to make use of it. It seems to be a well-designed language and it has a very performant JIT. But a big weakness for non-embedded use cases seems to be its ecosystem. A recent little project I wanted to use Lua on included a sqlite database, oldschool 3DES encryption, and an SMTP client. For many languages, there would be a clearly mob-approved library for each of these. But I found 3 or 4 possibilities to use sqlite in Lua, with no clear winner. I ended up using Ruby instead.
[+] strenholme|4 years ago|reply
While what you went through and felt is valid, I was able to find, in LuaRocks, libraries or Lua interfaces to libraries implementing everything on that wish list. In more detail:

a sqlite database

https://luarocks.org/modules/tami5/sqlite

https://luarocks.org/modules/dougcurrie/lsqlite3

3DES encryption

https://luarocks.org/modules/starius/luacrypto

https://github.com/somesocks/lua-lockbox/blob/master/lockbox...

an SMTP client

https://luarocks.org/modules/luarocks/lua-smtps

[+] astrobe_|4 years ago|reply
In my limited experience, when you want to interact with C libraries, you often end up reading the docs of the original C library anyway because often the bindings are nearly 1:1 - and often the trouble lies in the word "nearly".

Just writing yourself the bindings you actually need is most likely the best approach.

It should be relatively easy to do, because by using something like Lua you goal is precisely to expose functionalities implemented by your language as Lua functions (otherwise you would just convert them into dynamic library functions and use a classic glue language with a decent FFI to connect them).

This is the value proposition of an embeddable scripting language at heart.

[+] monatron|4 years ago|reply
I work on a project that leverages Kong's API Gateway, which is essentially Nginx + Openresty (Lua) + Kong (More Lua). The killer feature wrt Kong is the plugin ecosystem, which (among other things) allows you to act on the request/response lifecycle at various stages. Developers coming onboard to the project usually have little to no experience writing Lua, but we've found that coming up to speed on the language and it's runtime to be fairly painless. These days Kong has shims to write plug-in code in a few different languages (javascript, python, go, and more recently a wasm runtime) but despite our teams unfamiliarity with the language we still go back to Lua because performance can't be beat.
[+] jonpalmisc|4 years ago|reply
I’ve had a very positive experience using Lua as an extension language.

I was writing a text editor at the time. I wanted as much of the core code/actions to be written in Lua as possible, as I’ve always disliked very thin scripting APIs that sit on top of opaque native procedures.

I was able to wrap a handful of native functions in Lua code, then write the remaining 85% of the editor core in Lua. Everything was very fast and the process was straightforward. I’d definitely choose it again.

[+] ufo|4 years ago|reply
Lua 5.4 now includes a short utf8 library in the standard library. It has ways ways to get the utf8 string length and regex patterns for utf8 codepoints. However, it doesn't include any functionality that would require large tables of characters (for example, knowing which unicode characters are alphabetical).

-----

The requirement that return be the last statement is to avoid a syntactic ambiguity. Since Lua has no semicolons, there would be no way to know whether a line following the return statement is part of the return statement.

    return
    f()
[+] delusional|4 years ago|reply
Would you not just terminate the return when you see a newline? like the language already does for expressions.
[+] kdheepak|4 years ago|reply
You can also write rust ( or go, or write in any other language that allows you to expose a C ABI ) and make a Lua module. This solves a number of the different, bad and ugly issues in my opinion. For example, I think using rust’s chrono or unicode_segmentation library makes life so much easier than having to deal with that in Lua. Neovim embeds lua 5.1 jit, and it’s possible to write plugins in rust for neovim using this mechanism.

For any one that knows what I’m talking about it should be obvious how to do this. If not, I wrote about this more here, in case you are interested:

https://blog.kdheepak.com/loading-a-rust-library-as-a-lua-mo...

[+] 1vuio0pswjnm7|4 years ago|reply
Could have sworn I saw this submission 4 days ago.

https://news.ycombinator.com/user?id=Svetlitski

The timestamps next to the two oldest replies make it seem like they were more recently submitted, too. But I think they are 4 days old.

Seems like the title should be "Lua: Good, Different, Bad and Ugly Parts" as there is a fourth section, preceding "Bad", in the blog post called "Different".

Language wonks can endlessly dismiss Lua as a programming language, but it continues to be "embdedded in", i.e., used to extend, useful network applications, e.g., dnsdist, haproxy, nmap. To learn to use the application to its fullest, one has to learn some Lua.

[+] JonChesterfield|4 years ago|reply
A missing 'good' - the reference implementation is extremely easy to extend with existing C or lua libraries. E.g. embed sqlite.c and bindings to it and all of penlight (a bunch of standard library like utilities written in lua).

There are some package managers. However concatenating all the source plus a bunch of libraries into one .c file also works great, My bootstrap/install is to clone that one file via git and feed it to clang.

[+] erwincoumans|4 years ago|reply
It is nice small, so Lua even ran on Playstation 3 SPU!

We used to ship lua binaries for the premake build system.

For me, the indexed from 1 rather than 0 is a big turn off.

Roblox has the mlua fork, with increased performance and added type annotations: https://github.com/Roblox/luau

[+] diego_moita|4 years ago|reply
> For me, the indexed from 1 rather than 0 is a big turn off.

I can't understand why people complain about that.

If you're using 'pairs(table)' iteration then the index doesn't matter.

If you're accessing indexes directly you can have the index '0' in a table.

[+] chirsz|4 years ago|reply
I hope something like `ArrayBuffer` and `TypedArray` would be added to Lua, like to JavaScript.
[+] edflsafoiewq|4 years ago|reply
You can use LuaJIT's FFI.

  local ffi = require 'ffi'
  local arr = ffi.new('float[?]', 100)
LuaJIT's FFI is pretty great. It puts even a lot of compiled languages to shame.
[+] anonymoushn|4 years ago|reply
For better or worse, the language devs have a goal of keeping things simple, so this would have to be provided by a library. It's pretty easy to implement this sort of thing in luajit or provide that library to other luas though.
[+] anonymoushn|4 years ago|reply
(2012)

"lua 5.2 has no globals" is a bit of a misleading takeaway from the getfenf/setfenv changes in lua 5.2.

[+] dang|4 years ago|reply
We've added the year above now. Thanks all!
[+] jbotz|4 years ago|reply
This is from 2012 (should say so in title).
[+] daneel_w|4 years ago|reply
Plenty of good bullet points, but it's now a quite outdated article. A lot has happened in Lua since 2012.