Clojure implemented on the Erlang VM. This community-maintained fork keeps Clojerl working on current Erlang/OTP releases.
Fork releases are published on GitHub
and as ghcr.io/antlobach/clojerl container images. The Hex badge reports the
original project's clojerl package.
Juan Facorro created Clojerl, with substantial work from the
original Clojerl contributors. This fork preserves their
history, license, and authorship while providing ongoing compatibility
maintenance. The original project remains available at
clojerl/clojerl.
This fork is tested on Erlang/OTP 24 through 28 and requires rebar3.
git clone https://github.com/antlobach/clojerl
cd clojerl
makeOn Windows:
git clone https://github.com/antlobach/clojerl
cd clojerl
rebar3 clojerl compileStart with this README and the examples in scripts/examples.
The original Clojerl documentation remains useful for project
history and language design, but may not describe current fork behavior.
Release images are published from this fork to GitHub Container Registry:
docker pull ghcr.io/antlobach/clojerl:0.9.1
docker run --rm -it ghcr.io/antlobach/clojerl:0.9.1To build the image locally:
docker build -f scripts/Dockerfile -t antlobach/clojerl:0.9.1 .
docker run --rm -it antlobach/clojerl:0.9.1The REPL starts with:
Clojure 0.9.1
clje.user=>Run make repl. On Windows, first run rebar3 clojerl compile, then
bin/clje.bat.
Clojure 0.9.1
clje.user=>
From the REPL, evaluate Clojerl expressions:
clje.user=> (map inc (range 10))
(1 2 3 4 5 6 7 8 9 10)The scripts/examples directory demonstrates Clojerl special forms
and Erlang VM interop.
The original project maintains a basic Cowboy web application example.
rebar3_clojerl integrates Clojerl with Erlang's rebar3
build tool. It can create a project, compile code, run tests, and start a REPL.
Refer to the plugin repository for its command documentation.
Erlang is a great language for building safe, reliable and scalable systems. It provides immutable, persistent data structures out of the box and its concurrency semantics are unequalled by any other language.
Clojure is a Lisp and as such comes with all the goodies Lisps provide. Apart from these Clojure also introduces powerful abstractions such as protocols, multimethods and seqs, to name a few.
Clojure was built to simplify the development of concurrent programs and some of its concurrency abstractions could be adapted to Erlang. It is fair to say that combining the power of the Erlang VM with the expressiveness of Clojure could provide an interesting, useful result to make the lives of many programmers simpler and make the world a happier place.
- Interoperability as smooth as possible, just like Clojure proper and ClojureScript do.
- Provide most Clojure abstractions.
- Provide all Erlang abstractions and toolset.
- Include a default OTP library in Clojerl.
The following goal comes from Juan Facorro's original project README:
Learn more about Erlang (and its VM), Clojure and language implementation.
This project is an experiment that I hope others will find useful. Regardless of whether it becomes a fully functional implementation of Clojure or not, I will have learned a lot along the way.
Clojerl is an experimental implementation of Clojure on the Erlang VM. Its goal is to leverage the features and abstractions of Clojure that we love (macros, collections, seq, protocols, multimethods, metadata, etc.), with the robustness the Erlang VM provides for building (distributed) systems.
Yes. LFE and Joxa were each created with very specific and different goals in mind. LFE was born to provide a LISP syntax for Erlang. Joxa was mainly created as a platform for creating DSLs that could take advantage of the Erlang VM. Its syntax was inspired by Clojure but the creators weren't interested in implementing all of Clojure's features.
Yes, they are. On one hand Clojure provides tools to handle mutable state in a sane way, while making a clear distinction between identity and state through reference types. On the other, concurrency in the Erlang VM is implemented through processes and message passing. The idea in Clojerl is to encourage the Erlang/OTP concurrency model, but support as many Clojure constructs as possible and as far as they make sense in the Erlang VM.
But... but... Rich Hickey lists here some of the reasons why he chose not to use the actor model in Clojure.
That is not a question, but I see what you mean :). The points he makes are of course very good. For example, when no state is shared between processes there is some communication overhead, but this isolation is also an advantage under a lot of circumstances. He also mentions here that building for the distributed case (a.k.a processes and message passing) is more complex and not always necessary, so he decided to optimise for the non-distributed case and add distribution to the parts of the system that need it. Rich Hickey calls Erlang "quite impressive", so my interpretation of these writings is that they are more about exposing the rationale behind the decisions and the trade-offs he made when designing Clojure (on the JVM), than about disregarding the actor model.
No. Some of Clojure's features are implemented by relying on the underlying mutability of the JVM and its object system. The Erlang VM provides very few mutability constructs and no support for defining new types. This makes it very hard or nearly impossible to port some features into Clojerl's implementation.
Yes, but they will need to be ported, just like for ClojureScript. In fact, most of Clojure's core namespaces were ported from the original .clj files in the Clojure JVM repository.
Report fork-specific bugs and compatibility problems in the fork issue tracker.
Credit for Clojerl's language design and original implementation belongs to Juan Facorro and the original contributors. Historical discussions, design context, and prior releases remain available in the upstream repository.