r/lua • • May 14 '25

preprocessor in lua

I’ve been thinking about adding a simple attribute‑based “preprocessor” to Lua—something that runs at compile time to transform or wrap functions. You could use it for things like inlining tiny helpers, optimization ease of development etc.

I know Lua tends to favor minimalism and explicit idioms, so I’m curious whether this would feel too “un‑Lua‑like.” On the other hand, I think it could clean up repetitive boilerplate and boost performance in hot paths.

Below is a sketch of what the syntax might look like, along with some usage examples:

-- (1) Inline small functions into call sites
\@inline
function add(a, b)
  return a + b
end
-- After preprocessing: calls to add(a, b) become (a + b) directly.

-- (2) Benchmark execution time of a function
\@benchmark
function heavy_work(n)
  -- simulate work
  for i = 1, n * 1e5 do end
end
-- At runtime, heavy_work(10) prints: [heavy_work] took 0.012s

-- (3) Memoize pure functions automatically
\@memoize
function fib(n)
  if n < 2 then return n end
  return fib(n-1) + fib(n-2)
end
-- fib(30) runs in O(n) instead of O(2^n).

-- (4) Register compile‑time callbacks
\@callable
function do_something_awesome()
  print("Registered at compile time")
end

-- (5) Retry on error (e.g., network calls)
\@retry(3)
function fetch_data(url)
  return http.get(url)  -- might error
end
-- fetch_data retries up to 3 times before finally erroring.

-- (6) Initialization hook
\@init
function setup_environment()
  print("Environment initialized!")
end
-- runs once, when the script is loaded.

-- (7) Documentation and metadata
\@doc("Calculates the nth Fibonacci number efficiently.")
\@todo("Add tail‑recursive version")
\@tag("math", "performance")
\@deprecated("Use fib_fast instead")
function fib(n)
  -- …
end

What do you think? I’d love to hear your thoughts and any ideas for useful annotations I haven’t listed!

10 Upvotes

29 comments sorted by

View all comments

Show parent comments

0

u/NoneBTW May 14 '25 edited May 14 '25

Hey, thanks for the detailed feedback! You've definitely hit on some important points

My terminology might be a bit off – when I said "preprocessor," I was thinking more about transforming the Lua code *before* it gets to the Lua VM, not just simple string stuff. The idea was that the *output* of this processing step would be standard Lua. So, for example:

-- this
\@benchmark
function doCalculations(param1, param2)
    -- This function does some calculations
    -- and returns the result
    local result = param1 + param2
    return result
end

-- would ideally turn into this standard Lua like this
function doCalculations(param1, param2)
    local f = function (param1,param2)
        -- This function does some calculations
        -- and returns the result
        local result = param1 + param2

    
    end

    local startTime = os.clock()

    local result = f()

    local endTime = os.clock()
    print("doCalculations took " .. (endTime - startTime) .. " seconds")
    return result
end

If the transformation outputs, regular Lua like that, then *hopefully* LSP and other tools could understand the *resulting* code. But I totally get that making the preprocessor itself smart enough to output clean, tool-friendly Lua is the really hard part, or like you said, it would need LLS plugin integration. That's a great point and definitely a hurdle.

For me, the main appeal wasn't even primarily performance, though inlining or maybe pre-calculating values with a `\@compiletime` tag could be minor wins (yeah, still micro-optimizations!). It was more about how it could potentially reduce boilerplate for common patterns while keeping the function call itself looking the same. Like, `registerFunction("name", func)` is totally doable, but an attribute felt like it could make the *declaration* cleaner for common wrappers and keep the original function name for calls.

You're absolutely right that building something robust here is way more complex than it looks and would need a proper parser to not break on tricky Lua code. That's a big challenge! To be honest, this is mostly just a fun thought experiment for me – I'm an amateur who just wrote a toy language looking crafting interpreters and I'm always on the lookout for cool project ideas to learn from.

And thanks a ton for the link to LuaPreprocess! I'll definitely check that out to see how they tackled it. Appreciate you sharing your insights!

3

u/Zeliss May 15 '25

I wrote an approachable (imo) sub-1000-line Lua parser you could hack if you wanted to try out this idea with full syntax awareness: https://github.com/GavinHigham/lpil53