Lua Fun: functional programming for Lua built around LuaJIT's trace compiler
Lua Fun is a high-performance functional programming library for Lua designed with LuaJIT's trace compiler in mind.
At a glance
- What is it?
- Lua Fun gives Lua developers over 50 functional primitives including map, filter, reduce and zip, and is designed so that LuaJIT's trace compiler can turn nested functional expressions into tight machine loops. Its master branch carries an early alpha designation; a separate stable branch exists for production.
- Who is it for?
- Lua Fun is worth evaluating for LuaJIT projects that want map, filter, reduce and related primitives without paying a per-call function overhead. Skip it if you need a frozen API, a documented support story for Lua beyond 5.3, or a numbered artifact to pin: none of those are present.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 20 days ago.
- What is it written in?
- Mainly Lua, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Over 50 functional primitives for Lua, designed around LuaJIT's trace compiler
Lua developers who want a functional style face a practical problem: a naive implementation of map, filter and reduce carries a function-call overhead on every iteration. Lua Fun addresses this by designing each primitive to be transparent to LuaJIT's trace compiler, so the compiler can inline and merge them into a single compiled loop rather than executing them as a sequence of calls.
Over 50 primitives are provided, including the higher-order functions a programmer familiar with Standard ML, Haskell, Erlang, JavaScript or Python would expect. map, filter, reduce and zip are named explicitly in the project description; the full set is documented at luafun.github.io.
All of this fits in a single file, fun.lua, at the repository root. That design choice has a practical side effect: the complete implementation is auditable by reading one file, and adding the library to a project requires nothing more than copying that file.
2 calling styles for the same set of primitives: global injection and method chaining
2 calling styles are available. With the functional style, a single call injects all primitives into the global environment:
> -- Functional style
> require "fun" ()
> -- calculate sum(x for x^2 in 1..n)
> n = 100
> print(reduce(operator.add, 0, map(function(x) return x^2 end, range(n))))
328350After require "fun" (), names like reduce, map and range are globally available. With the object-oriented style, everything goes through a local table and chains off prior results:
> -- Object-oriented style
> local fun = require "fun"
> -- calculate sum(x for x^2 in 1..n)
> print(fun.range(n):map(function(x) return x^2 end):reduce(operator.add, 0))
328350Both calls produce 328350 for the same input. Global injection is terser for interactive use and scripts where naming collisions are not a concern. Method chaining avoids polluting the global namespace, which matters more in a larger codebase where another module might already define a name like map.
Installing via LuaRocks using fun-scm-1.rockspec or copying fun.lua directly
2 installation paths exist. LuaRocks is the package manager the project targets, and a RockSpec file named fun-scm-1.rockspec is at the repository root. No explicit luarocks install command appears in the repository documentation; the project links the rockspec file directly for download.
Copying fun.lua into a project directory is the other path. Since the whole library is that 1 file, dropping it in and requiring it works without a build step or dependency resolution. This path is particularly useful for projects that do not use LuaRocks or that vendor their dependencies.
Setup details beyond the README are at luafun.github.io/getting_started.html. That page covers the initial steps for new users, and the repository's HACKING.md covers development setup for anyone who wants to modify the library itself.
LuaJIT traces a functional chain to one machine loop in native code
Running luajit -jdump on the example above shows what LuaJIT does with the chain at runtime:
-- skip some initialization code --
->LOOP:
0bcaffd0 movaps xmm5, xmm7
0bcaffd3 movaps xmm7, xmm1
0bcaffd6 addsd xmm7, xmm5
0bcaffda ucomisd xmm7, xmm0
0bcaffde jnb 0x0bca0024 ->5
0bcaffe4 movaps xmm5, xmm7
0bcaffe7 mulsd xmm5, xmm5
0bcaffeb addsd xmm6, xmm5
0bcaffef jmp 0x0bcaffd0 ->LOOP
---- TRACE 1 stop -> loopThe project describes this as "one machine loop containing just 10 CPU assembly instructions without CALL." Counting the lines inside the ->LOOP block gives 9 instructions, not 10. Whether that discrepancy is a typo or reflects an instruction the dump notation elides is not explained in the project.
The practical point is that the range, map and reduce calls were merged by the trace compiler into a single compiled loop with no function-call dispatch visible. That is the core architectural claim: high-order functions that a naive implementation would execute as nested calls become a flat loop under LuaJIT.
The master branch carries an early alpha designation and an unstable API
Master is the development branch, designated early alpha. 2 things follow from that. First, the API is not frozen: function signatures, calling conventions and primitive names can change between commits without any formal announcement. Second, a stable branch exists and is the project's own recommendation for production deployments.
For anyone who continues using master, the documented mechanism for tracking breaking changes is to grep git log for the string "Incompatible API changes". No formal record of breaking changes is maintained outside that git log, so that grep is the only structured way to spot a breaking commit.
This is an unusual maintenance model. Most production dependencies have a documented breaking-changes mechanism or a semantic versioning contract. Lua Fun's answer is a branch pair, stable and master, with the expectation that production users stay on stable and take responsibility for monitoring master themselves.
LuaJIT 2.1 alpha is the recommended runtime and Lua 5.1-5.3 are also supported
LuaJIT 2.1 alpha is the recommended runtime for Lua Fun. That recommendation appears without qualification: 2.1 alpha is treated as the expected production LuaJIT version, not a caveat. The trace compiler behaviors the library relies on, including tail-call tracing, up-recursion and down-recursion handling, are documented on the LuaJIT wiki pages linked from the project.
Lua 5.1-5.3 are also supported for users who are not running LuaJIT. On those versions, the library still works as a functional-primitives collection, but the JIT compilation that produces the tight native loop output shown in the dump section does not apply.
Nothing in the project documentation covers compatibility with Lua runtimes beyond the 5.1-5.3 range, so users on other Lua versions should test before committing to the library.
Written for Tarantool and distributed without numbered Git tags
Lua Fun was originally written to use with Tarantool, an in-memory data store and Lua application server described in the project as "an efficient in-memory store and an asynchronous Lua application server." That origin explains the performance focus: Tarantool runs Lua for application logic inside a server process, and a functional library that compiles to native code fits the latency requirements of that architecture. Lua Fun is general enough to use outside Tarantool, but its design priorities came from that context.
GitHub carries no tagged releases for this project. The rockspec filename fun-scm-1.rockspec uses the SCM convention, indicating distribution from source control rather than numbered artifacts. Pinning to a specific version means tracking a specific commit hash or keeping a local copy of fun.lua.
Lua Fun is distributed under the MIT/X11 License, the same terms as Lua and LuaJIT. GitHub classifies it as Other because the text lives in COPYING.md rather than a standard-named file.
Editorial conclusion
Lua Fun is worth evaluating for LuaJIT projects that want map, filter, reduce and related primitives without paying a per-call function overhead. Skip it if you need a frozen API, a documented support story for Lua beyond 5.3, or a numbered artifact to pin: none of those are present. Before adopting, checkout the stable branch rather than master, read the Getting Started guide at luafun.github.io/getting_started.html, and run luajit -jdump on your own code to verify the trace compiler is actually merging the chains you care about.
Frequently asked questions
What is Lua Fun?
Lua Fun is a functional programming library for Lua that provides over 50 primitives such as map, filter, reduce and zip. It is designed for LuaJIT's trace compiler so that functional chains compile to tight native machine loops rather than executing as nested function calls.
How do I install Lua Fun?
Copy fun.lua from the repository into your project, or use LuaRocks with the fun-scm-1.rockspec file at the repository root. Getting Started documentation is at luafun.github.io/getting_started.html.
Is Lua Fun safe to use in production?
The master branch carries an early alpha designation and an unstable API. The project's own recommendation is to use the stable branch for production deployments.
Does Lua Fun require LuaJIT?
LuaJIT 2.1 alpha is recommended, and the native-loop compilation only occurs under LuaJIT. Lua 5.1-5.3 are also supported, but on those runtimes the library functions as a standard functional-primitives collection without JIT compilation.
Is Lua Fun still maintained?
The repository is not archived and the last push was on 2026-09-21. No tagged releases exist on GitHub; the stable and master branches are the 2 access points.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/luafun-luafun)