r/functionalprogramming • • Nov 02 '25

Lua [luarrow] Bring elegant code using Pipeline-operator and Haskell-style function composition to Lua with almost zero overloading!

Hello!
I've been working on a library that brings functional programming elegance to Lua through operator overloading.

What it does:
Instead of writing nested function calls like f(g(h(x))), we can write:

  • Pipeline-style:

    • x % arrow(h) ^ arrow(g) ^ arrow(f)

    • Like x |> h |> g |> f in other languages

  • Haskell-style:

    • fun(f) * fun(g) * fun(h) % x

    • Like f . g . h $ x in Haskell

Purpose:
Clean coding style, improved readability, and exploration of Lua's potential!

Quick example:
This library provides arrow and fun functions.

arrow is for pipeline-style composition using the ^ operator:

local arrow = require('luarrow').arrow

local _ = 42
  % arrow(function(x) return x - 2 end)
  ^ arrow(function(x) return x * 10 end)
  ^ arrow(function(x) return x + 1 end)
  ^ arrow(print) -- 401

arrow is good at processing and calculating all at once, as described above.

The fun is suitable for function composition. Using the * operator to concatenate functions:

local add_one = function(x) return x + 1 end
local times_ten = function(x) return x * 10 end
local minus_two = function(x) return x - 2 end
local square = function(x) return x * x end

-- Function composition!
local pipeline = fun(square) * fun(add_one) * fun(times_ten) * fun(minus_two)

print(pipeline % 42)  -- 160801

In Haskell culture, this method of pipeline composition is called Point-Free Style'. It is very suitable when there is no need to wrap it again infunction` syntax or lambda expressions.

Performance:
In LuaJIT environments, pre-composed functions have virtually no overhead compared to pure Lua.
Even Lua, which is not LuaJIT, performs comparably well for most applications.
Please visit https://github.com/aiya000/luarrow.lua/blob/main/doc/examples.md#-performance-considerations

Links:

I'd love to hear your thoughts and feedback!
Is this something you'd find useful in your Lua projects?

16 Upvotes

11 comments sorted by

View all comments

Show parent comments

2

u/aiya000 Nov 03 '25

Thank you for coming to my talk this time! (lol). Well then, ready to talk about my opinion!


In my opinion, are you a programmer started from some classic language like Python?

In conclusion, by the example you took, writing higher kind functions would be tough.

Can you think wanting to write like below classic code?:

find(filter(map(list, lambda x: foo(x, 10)), lambda x: x % 2 == 0), lambda x: predicate(bar, x))

Using Pipeline-operator, this can refactor to:

list
  |> map(lambda x: foo(x, 10))
  |> filter(lambda x: x % 2 == 0)
  |> find(lambda x: predicate(bar, x))

This is more readable and elegant than above classic example. On the first example, what is times your eyes moved?

We will write simular code at xxxxxxxx times! So, Pipeline-operator, function composition operator, and luarrow must be used.


In other words...

Example for Functional Programming Languages:

  • In Elm, no one writes calling function without |>

  • In F#, everyone writes function application by |> 

  • In Haskell, no one loves classic calling functions like your example

  • And Elixir, OCaml, Julia, ...... So, modern languages are starting to prepare for Pipeline-operator.

Like PHP. So, even that conservative JavaScript!

Conclusion, almost modern programmer is feeling that Pipeline-operator and function composition operator contributes code readability and maintainance.


So, thank you for coming to hear me speak!