We used Luerl, the underlying Lua engine, in production for years as a sandboxed scripting environment for FarmBot devices back in the day. Users could execute scripts directly on the device to control peripherals. It was a solid library and the community support was great. From an ergonomics perspective, developers preferred this approach over API calls. I am surprised more projects don’t provide a Lua scripting layer.
> I am surprised more projects don’t provide a Lua scripting layer.
Completely agree. I've been adding Lua scripting support to pretty much everything I make now. Most recently my programmable SSE server [1]. It's extended the functionality far beyond anything that I would have had the time and patience to do myself. Lua is such a treat.
This is not embedding the C Lua runtime and compiler, but rather a
complete implementation of Lua 5.3. This feat is made possible by the
underlying Luerl library, which implements a Lua parser, compiler,
and runtime, all in Erlang.
Okay, that's actually pretty cool (:
Also a sign of Lua's maturity and popularity, that it's got various independent implementations (LuaJIT, this one, perhaps others I don't know about).
This is so cool. A key benefit is that it's not embedding the C Lua runtime and compiler, but rather implements Lua in the host language (Elixir/Erlang).
When sandboxing user code in another runtime, you need to serialize the data to and from that runtime. That comes with a performance penalty.
So, for example, if you sandbox code in WASM, you need to pick a transport data format, like JSON. You need to serialize Elixir data structures into JSON, send it to WASM, and then deserialize the result. For a high-performance data pipeline, this adds up!
But if your sandbox is in the host language, no serialization/de-serialization is required. You can execute the sandboxed language in microseconds.
Very nice, but it is confusing to name a library for using a language the same thing as that language. I suppose this is meant to be a temporary state of affairs while Lua (the library) gets merged into Luerl, but I would have personally called it Luerl++ or such.
More seriously, I considered alternate names, but settled on this because it was short, literal, and given that its in the context of Elixir, makes sense when using it.
As you stated, the hope is to consolidate it into Luerl at some point
I am trying to understand why would anyone prefer to use Lua to create script instead of Elixir, which supports running scripts. While Lua has lots of users the language just have too many wrong design choices. If I had the choice between Elixir and Lua for scripts I would use Elixir every time.
Elixir is not a sandboxed language, so you can't just accept arbitrary Elixir programs from users and execute them inside of your application without security concerns. Lua, on the other hand, can be executed in a sandboxed fashion, limiting and constraining the reach of user programs.
I would also personally prefer Elixir to Lua, but this would be great for allowing isolated/sandboxed BEAM processes to execute Lua code from your end users whom are likely unfamiliar with Elixir. As mentioned in the article, this is precisely what TV Labs uses it for to allow smart tv app developers to write and run tests for their apps.
Lua can help if you're handing this over to someone else not just devs who know Elixir.
Also, as the sibling post mentioned, in this case Lua is completely interpreted in an Erlang process. That allows a good amount of sandboxing, they have isolated heaps already and you can control memory limits and other resource usages, and all that in a relatively tiny footprint of a few KBs.
This is more for your apps users. Like lets say you have a CRM saas written in Elixir. Then you can allow your users to script things in your app with Lua. If you allow them to use Elixir running in your app you might allow someone to hack your app.
I've been considering adding Lua support to Keila for a while already. It seems like a perfect fit for when I'm going to implement email automation and want to allow custom business logic. This would certainly make that plan easier.
Thanks OP for sharing the library with the community!
davydog187, I just wanted to thank you for stepping up and lending Robert a hand. It's nice to see new releases and lots of cleanups happening in Luerl. The project is a real gem and it's nice to see new activity in it!
Thanks, I really appreciate that. While its not my main focus by any means, its been a really fun project to chip away at (both the higher level library and Luerl itself).
I do think that it has the potential to be really great with continued investment
Fun fact (probably well-known fact for HN audience): Both Lua and Elixir were created by Brazilians. Lua by Roberto Ierusalimschy and team at PUC-Rio in 1993, and Elixir by José Valim in 2011
The reason for calling it Luerl was that it was/is an implementation of Lua on Erlang. It is Dave who has been working with a more serious Elixir interface. The original one, which still exists, had a very simple Elixir interface module which just flipped the argument ordering to calls to be more Elixiry in feel.
Both the Lua library and Luerl predate Pythonx. I started this library nearly 2 years ago, its only now that I'm releasing a stable version.
However, Pythonx was originally created by a member of our team, Cocoa, who built it in her own free time. The Livebook team forked her project, conceptually, and released it.
Recently, I had a simple Flask project, just a single Python file, and wanted to convert it to Elixir using AI. But what I got was a sprawling directory of modules and files in Elixir. Apparently, that’s just how things are done in the Elixir world. That moment made me realize why some languages catch on while others struggle. If spinning up a basic web server already feels like jumping through hoops, I can’t imagine the overhead for more complex projects.
I'm sure there are people who think Elixir/Phoenix >> <other-solutions>, but for me it was a nightmare.
OTOH, the language is beautiful as it's macros all the way down.
There's another single-file example on that page that shows how to implement routing. The reason AI probably gave you a more fleshed out project structure is because people typically default to using Phoenix (Elixir's equivalent of Rails) instead of going for something simpler like Plug.
After getting a result you didn't like with AI, did you try refining your prompt to state that you wanted a single-file structure?
You can write a single file Elixir app if you want to. There's nothing preventing this. Setting up a simple web server w/ Plug is straightforward. You'll have the same problems you'd have with a non-trivial Flask app, which is that scrolling through a huge file is a pain.
We should try not to make technical judgements based in flippant things like how few lines can someone not even familiar with the ecosystem get a hello world working
Elixir is somewhat lacking in training data compared to some more popular languages, so AI will often regurgitate nonsense (more so than in more popular languages).
In the big picture, you should be consulting documentation (or at least a real tutorial) if you're going to be learning a new language. Hell, I'll use AI to bootstrap my knowledge when possible, but it's always important to fall back onto the old method when the quick-and-dirty AI attempt doesn't work out.
rickcarlino|9 months ago
benwilber0|9 months ago
Completely agree. I've been adding Lua scripting support to pretty much everything I make now. Most recently my programmable SSE server [1]. It's extended the functionality far beyond anything that I would have had the time and patience to do myself. Lua is such a treat.
[1] https://github.com/benwilber/tinysse
interroboink|9 months ago
Also a sign of Lua's maturity and popularity, that it's got various independent implementations (LuaJIT, this one, perhaps others I don't know about).
johnisgood|9 months ago
_acco|9 months ago
When sandboxing user code in another runtime, you need to serialize the data to and from that runtime. That comes with a performance penalty.
So, for example, if you sandbox code in WASM, you need to pick a transport data format, like JSON. You need to serialize Elixir data structures into JSON, send it to WASM, and then deserialize the result. For a high-performance data pipeline, this adds up!
But if your sandbox is in the host language, no serialization/de-serialization is required. You can execute the sandboxed language in microseconds.
I wrote more about this here: https://blog.sequinstream.com/why-we-built-mini-elixir/
Wish this library existed just a couple months ago!
Philpax|9 months ago
toast0|9 months ago
If you wait long enough before replacing whatever2 with something that would be whatever3, you can go back to whatever (see pg -> pg2 -> pg)
davydog187|9 months ago
Luerl++ is not a valid module name :)
More seriously, I considered alternate names, but settled on this because it was short, literal, and given that its in the context of Elixir, makes sense when using it.
As you stated, the hope is to consolidate it into Luerl at some point
davydog187|9 months ago
https://github.com/rvirding/ship-demo
antfarm|9 months ago
Some instructions to install it on macOS: https://erlangforums.com/t/lt-using-luerl-to-run-spaceships-...
gilgamesh3|9 months ago
I am trying to understand why would anyone prefer to use Lua to create script instead of Elixir, which supports running scripts. While Lua has lots of users the language just have too many wrong design choices. If I had the choice between Elixir and Lua for scripts I would use Elixir every time.
davydog187|9 months ago
Check out Anthony Accomazzo's post about Mini-Elixir, which does a great job breaking this down much further https://blog.sequinstream.com/why-we-built-mini-elixir/
prophesi|9 months ago
https://docs.tvlabs.ai/scripting/introduction/getting-starte...
rdtsc|9 months ago
Also, as the sibling post mentioned, in this case Lua is completely interpreted in an Erlang process. That allows a good amount of sandboxing, they have isolated heaps already and you can control memory limits and other resource usages, and all that in a relatively tiny footprint of a few KBs.
victorbjorklund|9 months ago
unknown|9 months ago
[deleted]
joshprice|9 months ago
https://hexdocs.pm/lua/Lua.html
davydog187|9 months ago
pentacent_hq|9 months ago
davydog187|9 months ago
rdtsc|9 months ago
davydog187|9 months ago
I do think that it has the potential to be really great with continued investment
dlojudice|9 months ago
jkaufmann_|9 months ago
antfarm|9 months ago
https://www.youtube.com/watch?v=4YBBoXXH_98
rvirding|9 months ago
dpflan|9 months ago
https://dashbit.co/blog/running-python-in-elixir-its-fine
It certainly is more attractive in implementation. Well done!
davydog187|9 months ago
However, Pythonx was originally created by a member of our team, Cocoa, who built it in her own free time. The Livebook team forked her project, conceptually, and released it.
https://github.com/cocoa-xu/pythonx
iLemming|9 months ago
davydog187|9 months ago
binary132|9 months ago
cmdrk|9 months ago
I would say BEAM itself is not particularly sandboxed, and certainly clusters of Erlang nodes assume a lot of shared trust.
codingbear|9 months ago
cess11|9 months ago
xvilka|9 months ago
[1] https://github.com/kyren/piccolo
behnamoh|9 months ago
I'm sure there are people who think Elixir/Phoenix >> <other-solutions>, but for me it was a nightmare.
OTOH, the language is beautiful as it's macros all the way down.
technojamin|9 months ago
There's another single-file example on that page that shows how to implement routing. The reason AI probably gave you a more fleshed out project structure is because people typically default to using Phoenix (Elixir's equivalent of Rails) instead of going for something simpler like Plug.
After getting a result you didn't like with AI, did you try refining your prompt to state that you wanted a single-file structure?
sodapopcan|9 months ago
devoutsalsa|9 months ago
sph|9 months ago
bad_haircut72|9 months ago
https://m.youtube.com/watch?v=SxdOUGdseq4&pp=0gcJCdgAo7VqN5t...
We should try not to make technical judgements based in flippant things like how few lines can someone not even familiar with the ecosystem get a hello world working
arcanemachiner|9 months ago
In the big picture, you should be consulting documentation (or at least a real tutorial) if you're going to be learning a new language. Hell, I'll use AI to bootstrap my knowledge when possible, but it's always important to fall back onto the old method when the quick-and-dirty AI attempt doesn't work out.
butterNaN|9 months ago