{% extends "templates/base-1-col.html" %} {% block content_title %}About{% endblock %} {% block content_body %}
"Clozhang" is a set of libraries and tools (including the library
clozhang-proper) that are dedicated to Clojure-BEAM
interop, where BEAM languages include all those of the Erlang
ecosystem: Erlang, LFE, Elixir, Joxa, Reia, Luerl, Erlog, etc.
Clozhang supports production deployments of distributed, fault-tolerant, soft real-time BEAM/JVM applications with appropriate restart and fail-over strategies and hot code-loading.
In particular, the aim of Clozhang is to support production deployments of distributed, fault-tolerant, soft real-time BEAM/JVM applications, capable of running JVM code in supervision trees with appropriate restart and fail-over strategies, hot code-loading (live system updates with no downtime), and the like.
From the developer perspective, Clozhang wants to make OTP-based communications between BEAM languages and the JVM as Clojure-idiomatic as possible and as natural to BEAM programmers as can reasonably be provided.
For an overview of the three primary ways in which one may develop JVM-BEAM interoperable applications, be sure to read the API comparison docs. To see how LFE and Clojure applications can interoperate, you'll want to read the "Talking to Servers" tutorial.
Here's a Clojure OTP server written using Clozhang:
(defn ping-pong
[]
(let [init-state 0]
(loop [png-count init-state]
(match (receive)
[:ping caller]
(do (! caller :pong)
(recur (inc png-count)))
[:get-ping-count caller]
(do (! caller png-count)
(recur png-count))
[:stop caller]
(do (! caller :stopping)
:stopped)))))
And here's LFE talking to Clojure:
(clozhang-lfe@host)> (! #(default clozhang@host) `#(ping ,(self)))
#(ping <0.34.0>)
(clozhang-lfe@host)> (! #(default clozhang@host) `#(ping ,(self)))
#(ping <0.34.0>)
(clozhang-lfe@host)> (! #(default clozhang@host) `#(ping ,(self)))
#(ping <0.34.0>)
(clozhang-lfe@host)> (c:flush)
Shell got pong
Shell got pong
Shell got pong
ok
(clozhang-lfe@host)> (! #(default clozhang@host) `#(get-ping-count ,(self)))
#(get-count <0.34.0>)
(clozhang-lfe@host)> (c:flush)
Shell got 3
ok
Here's part of an LFE OTP gen_server:
(defun handle_call
(('ping _caller state-data)
`#(reply pong ,(+ 1 state-data)))
(('ping-count _caller state-data)
`#(reply ,state-data ,state-data))
(('stop _caller state-data)
`#(stop shutdown ok ,state-data))
((_message _caller state-data)
`#(reply ,(unknown-command) ,state-data)))
And here's Clojure talking to LFE:
clozhang.dev=> (rpc/! :clozhang-lfe :ping-pong :ping)
:ok
clozhang.dev=> (rpc/! :clozhang-lfe :ping-pong :ping)
:ok
clozhang.dev=> (rpc/! :clozhang-lfe :ping-pong :ping)
:ok
clozhang.dev=> (rpc/receive :clozhang-lfe)
:pong
clozhang.dev=> (rpc/receive :clozhang-lfe)
:pong
clozhang.dev=> (rpc/receive :clozhang-lfe)
:pong
clozhang.dev=> (rpc/! :clozhang-lfe :ping-pong :get-ping-count)
:ok
clozhang.dev=> (rpc/receive :clozhang-lfe)
3