#LUA

2025-06-27
While it has its own issues, there are several good reasons why my favourite #ProgrammingLanguage in the real world is #C

Why not #Go?
Because it's from #Google.

Why not #Csharp or #Fsharp?
#Microsoft.

Why not #Rust or #Zig?
#LLVM (aka #Apple & friends).

Ultimately, most of languages I avoid like the plague are controlled by #BigTech one way or another.

C is simple enough to get several alternative compilers based on useful standards.² ³


¹ In theory I still prefer #Oberon07, but when I want to code something useful I still use C instead to lower the entry barrier for other devs, because there are too many incompatible implementations of the compiler and "standard" library.

² Ok, #Python, #Scheme and #Lua have similar qualities, but for the tools I write I usually prefer binary executables with no runtime.

³ No, #C++ is not an option. 😉
algernon found his parensalgernon@come-from.mad-scientist.club
2025-06-27

Today, I'm writing tests. Originally, I planned to write a bunch of tests in Rust to exercise the request handlers, but that felt like a huge pain in the backside, and would've involved a lot of repetition and boilerplate.

Then, I figured: I'll write the tests in #Roto and #Lua! Test the things from that side. Much less boilerplate, but still a lot of repetition.

Instead, I'll be writing a test suite to verify the decisions of a request handler. I'll run it for both engines, #Roto and #Lua. I will still have to write the scripts twice, but I will only write the verification once.

2025-06-26

New software release today!

Just published v2.0 of Daemonparts, a collection of unix daemon boilerplate for #Lua. Next version of Nepenthes needed this out.

I think it's unlikely anything not made by me is using it, but it's 2.0 because there are some severe breaking changes.

Anyway if you're interested in daemonizing Lua scripts it's on LuaRocks, and documented here:

https://zadzmo.org/code/daemonparts

António Manuel Diasammdias@masto.pt
2025-06-26

A lua hoje parece a ponta de uma unha cortada.

#fotografia #lua

Fotografia após o pôr do sol, com a lua nova como um finíssimo crescente branco sobre o alaranjado do céu. Na parte inferior, o contorno negro de uma montanha.
2025-06-26

Oh wow, learned a lot from Robin's workshop, very inspiring. I'm definitely going to dive into Lua scripting to streamline my Ardour workflow.

#Ardour #Lua #LinuxAudioConference #LAC2025

Alfonso Sicilianoalfonsosiciliano@bsd.cafe
2025-06-26

🖥️ My ultra-budget server powering websysctl.alfonsosiciliano.net has been running smoothly for the past 2 months. So far, so good!

📈 #Crawlers hit tens of thousands of sysctl parameter pages daily. That's fine, since robots.txt allows it. But why keep requesting non-existent pages as if the site were built with WordPress 😤 ? Fortunately, the stack (#FreeBSD :freebsd: + #OpenResty 🌐 + #Lapis ✏️ + a custom-built #database 📦 ) stays well within the limited resources of my $5/month cloud server.

The code might soon be #OpenSource stay tuned!

#UNIX #sysctl #WebDev #WebServer #ThePowerToServe #coding #Lua #kernel

Screenshot of the "Tree MIB" page from the WebSysctl site. The left panel shows an expandable tree view of the FreeBSD sysctl MIB hierarchy, with nodes like sysctl, kern, vm, sys, security, and their subcategories. The security.mac.mmap_revocation_via_cow node is selected. The right panel displays detailed information about this sysctl parameter, including its link, OID, name, description ("Revoke mmap access to files via copy-on-write semantics, or by removing all write access"), type (integer), format (I), flags (RD, WR, MPSAFE), label, and handler status (Defined). The top navigation bar includes links: Home, Docs, Table, Tree (highlighted), Update, Login, and Contacts.
2025-06-26

The @ardour #Lua scripting workshop at #LAC25 #INSA #Lyon has just started. And I am curious to learn how to extend the functionalities of this great free and #OpenSource #DAW in a programmatically way in #realtime.

As @lualang is #CrossPlatform like #Ardour is, you can draft your script on a Windows machine at work and refine it on your #Linux computer later at home, for example.

Let's see how we can automate tasks in Ardour sessions, which otherwise would require another person operating #plugin parameters, session properties, #routing, etc. interactively.

2025-06-26

Robin's workshop "Ardour Lua Scripting" has kicked off!

youtube.com/watch?v=PPpsbsPYrf

#LinuxAudioConference #LAC2025 #Ardour #Lua

2025-06-26

I've been porting github.com/2Retr0/GodotOceanWa to the Recoil Engine/Beyond All Reason. Need to do a bit of work on optimization, a ton of clean up, and then adding some features.

My fish schooling sim(boids) needed a nicer place to live. So I went to work.

Pretty far from done but there is potential.

#Godot #BAR #Lua #GLSL

Screenshot of Beyond All Reason. The water plane is replaced with a clipmap which is displaced by a wave simulation. Each level of the clipmap is colored differently.Screenshot from Beyond All Reason. A wave simulation is running.
algernon found his parensalgernon@come-from.mad-scientist.club
2025-06-26

Unfortunately, there are gotchas there, too.

(fn decide [request]
  Outcome.not_for_us)

This #fennel code compiles to the following #lua:

local function decide(request)
  return Outcome.not_for_us
end
return decide

The problem here is that I'm not require-ing this file. I maybe should. Without require, that return makes little sense, and the decide function won't be found in the global scope, so...

Error: error converting Lua nil to function

Which makes perfect sense. Except the error message is bad, and needs to be improved.

algernon found his parensalgernon@come-from.mad-scientist.club
2025-06-26

Today's adventures begin with trying to make #iocaine play well with #Fennel. There's work to be done on this front...

For starters, I don't think I will be able to support running the Fennel compiler as part of the init process. It seems to require debug and assert, which I'm not sure I want to make available to the Lua runtime in iocaine.

debug requires mlua.unsafe_new(), which in turn requires an unsafe block, and I'm not comfortable with that. Not even sure how I can make assert available, mlua doesn't seem to provide that as part of stdlib.

So, next best thing: compiling #Fennel to #Lua ahead of time!

algernon found his parensalgernon@come-from.mad-scientist.club
2025-06-25

That's a nice 163k req / sec. Faster than #Lua, slower than #Roto. That's funny, 'cos Roto is using cranelift too.

But now the big question: is it worth adding wasmtime as a scripting engine too? Or is Lua and Roto enough?

algernon found his parensalgernon@come-from.mad-scientist.club
2025-06-25

Right. Reading the docs: yes, Store is short lived, and the linker needs to be instantiated for every request too. Both should be cheap.

Currently waiting for a dummy #wasm implementation to compile, one similar to my first #Lua try: a decide function that returns false (or in this case, 0, as i32).

Curious how this will perform.

algernon found his parensalgernon@come-from.mad-scientist.club
2025-06-25

After cleaning up a bit of a mess I made, I ran some benchmarks:

Timer precision: 30 ns
handler                           fastest       │ slowest       │ median        │ mean          │ samples │ iters
├─ request_handler_language_lua   279.7 ns      │ 279.4 µs      │ 349.7 ns      │ 417.1 ns      │ 9036446 │ 9036446
╰─ request_handler_language_roto  65.17 ns      │ 2.958 µs      │ 69.11 ns      │ 69.93 ns      │ 1061654 │ 67945856

Both benchmarks do essentially the same: return Outcome::Garbage. While #Lua is certainly fast, and is going to be Just Fine for most loads, #Roto blows it out of the water.

The complexity of the script matters little, because the heavy lifting is being done on the Rust side, and is common between the two.

Great to see my first choice justified. Still, gonna keep Lua around, because it's not slow, and is a more familiar language.

I might put it behind a feature flag, though.

algernon found his parensalgernon@come-from.mad-scientist.club
2025-06-25

A very nice #Lua convenience: I don't need an init() function! I can just do the init in the body of the script.

function decide(request)
   if _G["foobar"]:contains(request:header("user-agent")) then
      return Outcome.not_for_us
   end

   return Outcome.garbage
end

_G["foobar"] = Patterns("test-agent", "curl")

It is also easier to make this kind of stuff available to Lua, from the Rust side:

#[derive(Clone)]
struct Patterns(AhoCorasick);

impl UserData for Patterns {
    fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
        methods.add_method("contains", |_, this, needle: String| {
            Ok(this.0.is_match(&needle))
        })
    }
}

pub fn register(runtime: &Lua) -> Result<()> {
    let constructor = runtime.create_function(|_, patterns: Variadic<String>| {
        let ac = AhoCorasick::builder()
            .ascii_case_insensitive(true)
            .build(patterns.iter()).unwrap();
        Ok(Patterns(ac))
    })?;
    runtime.globals().set("Patterns", constructor)?;

    Ok(())
}

(Yes, there's an unwrap() there, I will get rid of it.)

It's so much simpler than for Roto, because Roto does not support lists yet, so I had to add a list builder too.

#iocaineDevLog

algernon found his parensalgernon@come-from.mad-scientist.club
2025-06-25

Ok, dispatch is in, some quick benchmarks, using a script that does nothing but return Outcome::NotForUs:

  • lua (luajit): 127k req/sec
  • lua (luau-jit): 142k req/sec
  • roto: 173k req/sec

So #Roto wins over #Lua by a sizeable margin here, even with luau-jit (which, iirc, is supposed to be the fastest).

However, #Lua is fast enough. I'm willing to trade some performance for user convenience, and Lua is at a spot where the performance drop, while noticable, is within acceptable limits, and is offset by the convenience of the language.

algernon found his parensalgernon@come-from.mad-scientist.club
2025-06-25

In a number of ways, #Lua is going to be a better fit than #Roto: it's a far better known language, and a whole bunch of things are easier to do in Lua.

Do I regret going with #Roto first? Absolutely not. I like Roto's syntax better, and prefer its minimalism over Lua. From what I remember about my prior benchmarks, Roto is also significantly faster. But I'll do some side-by-side comparisons once the Lua support is in a better place, and once I can actually choose which one to use.

Right now I just made a struct that implements the same functions as MeansOfProduction, and replaced Roto with Lua. That is obviously not how it will work down the road.

#iocaineDevLog

algernon found his parensalgernon@come-from.mad-scientist.club
2025-06-25

Last night I started to wonder: what if I embedded #Lua in #iocaine?

So today I'm going to do that. A first, exploratory hack is compiling now, so I can benchmark it. It doesn't load any external files yet, it's a hardcoded return false.

#iocaineDevLog

Client Info

Server: https://mastodon.social
Version: 2025.04
Repository: https://github.com/cyevgeniy/lmst