Today we talk to Peter Lubell-Doughtie about Ona.
How long have you been working with Clojure and ClojureScript?
Ona has been working with Clojure and ClojureScript for three years. We started using it when we built an updated version of the front-end to our data collection and management platform. I was introduced to Clojure about five years ago through Cascalog. I’ve had an affinity for LISPs ever since learning it in undergrad and using it in a genetic programming research project that generated s-expressions to evolve an agent communication language.
How big is the team you have using Clojure or ClojureScript?
At any one time we have about 4-6 team members working full-time on projects in Clojure and ClojureScript; this comes out to about a third of our engineering team. We use a number of different editors, including Meow, an emacs config created by one of our engineers.
What product or service are you building with Clojure or ClojureScript?
We are building a data collection, management, and visualization platform targeted at humanitarian and international development organizations. These organizations, e.g. the World Food Program and UNICEF, use our platform to conduct on-going surveys in the field. Field data is merged with historic data in real-time to construct a comprehensive view of projects they have invested in or are running. This allows organizations to see problems as they occur and make adjustments, e.g. directing health workers to understaffed clinics or inspectors to buildings with more severe damage. The Clojure and ClojureScript component is a stateless layer with all data persistence and retrieval mediated through our API client, Milia, and visualization in our ClojureScript data viewers, Hatti and Vega-viewer.
What Clojure or ClojureScript library have you enjoyed working with the most?
On the Clojure side, we’ve benefited a lot from the Ring middleware Optimus, which bundles and optimizes all our assets.
On the ClojureScript side, we were early adopters of Om and use it extensively to render reactive views. We use it with Hiccup-based markup, some of which is shared with Clojure (we’d like to share more).
For libraries we use in both Clojure and ClojureScript, we make heavy use of the i18n library Tempura combined with custom helpers to load all text from translation files. We also run a lot of static analyzers in our build step including Kibit and Bikeshed to catch duplication and enforce uniform code-style.
What about working with Clojure or ClojureScript gives you the most value?
Consistency and an approximation of purity give us the most value. When using Clojure and ClojureScript we can look at the front-end or back-end---really anywhere in our codebase---and know it’s following the same set of simple rules. We can trace through the data flow and explicitly see how transformations are happening.
These features also help us when working with less experienced engineers or engineers without a functional programming background. Working in Clojure, with strict static analyzers, significantly limit the possible approaches to solve a problem, and rules out a bunch of anti-patterns.
What is your stack?
We use NGINX as a reverse-proxy to hand-off requests to our application server which runs a Ring based Jetty server and routes requests to a set of views using Compojure. We render views on the server side using Enlive and occasionally Hiccup. All styles are written in SCSS. The client side uses Om to render React views with Secretary for routing and Sablono for markup. We use our core.async based API client Milia to interact with API data from the client side.
For testing, we self-host Drone to run continuous integration builds. Code must get past Sass-lint, Bikeshed, cljfmt, Eastwood, Kibit, and a production ClojureScript build (which will alert us to any issues with advanced compilation), before we run the tests suites. We write Clojure tests in Midje and ClojureScript tests in cljs.test.
Why is using Clojure or ClojureScript valuable to your business?
Because our platform is used globally to improve child and maternal health, governance, agriculture, access to infrastructure, and government accountability, mistakes in our platform have serious consequences. E.g. fewer vaccinations given and fewer essential resources distributed (think water and blankets). In a very literal way, our mistakes mean fewer lives saved. Using Clojure and ClojureScript simplifies how we process real-time data streams from around the world, and helps us minimize our mistakes. If you’re interested in working with us please get in touch.
If you'd like to share your Clojure story, please contact email@example.com.