Blog Posts tagged with: clojure

Nov 07 2013

Comments

When Should You Use Clojure's Object-Oriented Features?

In the world of object-oriented programming, it is common to create classes to represent data elements from your domain. These classes run into all kinds of trouble. First, they tend to breed closely coupled classes like DTOs and XML type mappers. Second, they rarely contain any intelligence and sometimes don't contain any behavior at all. Third, proliferating concrete classes can make it hard to see common abstractions trying to escape.

In the past, I answered all of those objections by arguing that they were "merely" bad design. It is possible to do good OO design that doesn't suffer from those failings. I've reluctantly come to believe that the majority of OO code will never escape those failings. Common style, frameworks, and tools all push toward a design dominated by "god classes" and data containers.

Instead of fighting that, I've decided to embrace it. If your objects are just going to be data containers, then embrace the data! Don't hide it away inside objects, and don't fragment your namespace of functions over the data by splitting them across dozens of classes.

Now when I build applications in Clojure I tend not to use Clojure's OO constructs, protocols and types, for the domain data passing through the system. I've followed Rich and Stu down the path of values and data structures.

I do find Clojure's OO constructs valuable for the structure of the system itself. I like to use protocols to limn the boundaries between subsystems. They provide exactly the degree of information hiding I want. We've been evolving a common idiom for creating instances of protocols, where we have an implementation as a type together with a constructor function. The constructor function is considered public, while the type is meant to be private.

(defprotocol IMarshaller
  (marshall   [_ data] "Marshall data, return a ByteBuffer ready to transmit.")
  (unmarshall [_ bbuf] "Unmarshall data from the ByteBuffer"))

(deftype EdnMarshaller []
  IMarshaller
  (marshall   [_ data] (io/clj->bbuf data))
  (unmarshall [_ bbuf] (io/bbuf->clj bbuf)))

(defn edn-marshaller [] (EdnMarshaller.))

Most of what we pass across subsystem boundaries are primitives and data structures of primitives. This particular example uses Java ByteBuffer objects, but we treat them like immutable value objects so I'll call them "primitives" for the sake of argument.

That troika of protocol, type, and constructor appears fairly often, but there are some variants.

In this example, the functions on the type are small enough that you could simply reify the protocol inside the constructor function:

(defn edn-marshaller [] 
  (reify IMarshaller
    (marshall   [_ data] (io/clj->bbuf data))
    (unmarshall [_ bbuf] (io/bbuf->clj bbuf))))

This works best when the constructor only takes one set of arguments. I would split this out when there are optional or variadic arguments to the constructor function.

Using objects to represent subsystems gives us information hiding and polymorphism. That's exactly what we need. Using data structures for the application data gives us leverage over those data structures. One more thing to consider is when and how to avoid coupling data structure shapes across subsystems, but that's a topic for a future post.

Oct 08 2013

Comments

Ambrose Bonnaire-Sergeant - Cognicast Episode 042

cover art

Ambrose Bonnaire-Sergeant has made quite a splash recently with his campaign to fund development of core.typed, a library that provides a gradual type system for Clojure. In this episode, we talk extensively with Ambrose about core.typed just minutes before he launched the campaign.

Listen to or download this episode.

Read More »

Oct 01 2013

Comments

Robert Stuttaford - Cognicast Episode 041

cover art

On this - our first post-merger episode! - we talk to Robert Stuttaford of Cognician about their use of Clojure, ClojureScript, Pedestal, and Datomic.

Listen to or download this episode.

Read More »

Aug 27 2013

Comments

Alex Miller - Podcast Episode 039

cover art

Alex Miller is the organizer of some of the best conferences I've ever been to (and one I haven't): Strange Loop, Clojure/West, and Lambda Jam. He is also Relevance's newest employee. As we both found ourselves in Durham recently, it was the perfect time to sit down together and talk conferences, community, and Clojure.

Listen to or download this episode.

Read More »

Aug 20 2013

Comments

Craig Andera - Podcast Episode 038

cover art

You've had the joy of listening to Craig's insightful questioning of our guests for a long time now; it is our great pleasure to turn the microphones around and capture Craig Andera on the other end of the questions. Guest host Justin Gehtland gets Craig to talk about his career path that led to working at Relevance, his changing taste in technologies, and the genesis and details of ThinkRelevance: the Podcast. We hope you enjoy getting to know Craig a little better.

Listen to or download this episode.

Read More »

Aug 13 2013

Comments

Brenton Ashworth - Podcast Episode 037

cover art

On episode 27, Tim Ewald gave us an overview of Pedestal, Relevance's open source framework for building web applications. We spent most of our time talking about the server side of that technology, but I think the app side of Pedestal is in many ways even more fascinating. Because it contains so many new ideas, it's also something people have had a harder time getting started with.

To help people understand the concepts in Pedestal App, Brenton Ashworth recently authored the Pedestal App Tutorial. I highly recommend people check it out - it's a great resource. On this episode, Brenton does a great job of explaining the concepts in Pedestal App. I'm sure you'll come away with a better understanding of the library. I definitely did. I thank Brenton for taking the time to talk to me!

Download this episode.

Read More »

Jul 26 2013

Comments

Neal Ford of ThoughtWorks - Episode 036

cover art

Those of you lucky enough to have heard Neal Ford speak on anything know that he is one smart, funny, and perceptive dude. It was my great pleasure to have him on the show, where we talked about Evolutionary Architecture, Clojure, Datomic, the poetry of Donald Rumsfeld, the ThoughtWorks Radar, and the role of fake LinkedIn profiles in software development. I thank Neal for joining me on this episode!

Download this episode.

Read More »

Jul 10 2013

Comments

Rich Hickey and core.async - Podcast Episode 035

cover art

Download this podcast episode.

Listeners of the show need no introduction to Rich Hickey, even if he had not already been our guest twice. In this episode, we talk to him about his latest brain gem, the core.async library. It was an illuminating discussion, and I thank Rich for taking the time to explain the concepts to me!

Read More »

Jun 12 2013

Comments

Kurt Zimmer of Room Key - Podcast Episode 033

cover art

Download this podcast episode.

I've said it before: one of the few downsides to working at Relevance is getting to hear all sorts of cool customer success stories that we can't talk about. Which is why Justin and I were thrilled to record an episode with Kurt Zimmer from Room Key, one of our clients and an enthusiastic user of both Clojure and Datomic. We talked about Relevance's relationship with Room Key, and about Kurt's experience successfully selling cutting-edge technologies into extremely large, conservative organizations.

Kurt is a sharp guy, and it was a pleasure to have him as a guest.

While I've got your attention, I'd also like to mention a few things:

Read More »

Jun 04 2013

Comments

My Clojure Workflow, Reloaded

This is a companion post to my discussion with Craig Andera on Relevance Podcast Episode 32 and my Clojure/West talk Clojure in the Large. I've talked about various bits and pieces of this workflow at other times, too, but I'll try to bring it all together here in the hopes that others will find it useful.

One of the great pleasures of working with a dynamic language is being able to build a system while simultaneously interacting with it. To make this possible, first you need the ability to redefine parts of the program while it is running: Clojure provides this capability admirably. However, some aspects of Clojure's runtime are not quite as late-binding as one might wish for interactive development. For example, the effect of a changed macro definition will not be seen until code which uses the macro has been recompiled. Changes to methods of a defrecord or deftype will not have any effect on existing instances of that type.

The facilities that Clojure provides for loading code from files are not sufficient to deal with these issues. I wrote the second version of tools.namespace to make a "smarter" require that recognizes dependencies between namespaces and reloads them appropriately.

But tools.namespace is only part of the story. To really get the benefit of interactive development, I want to ensure that the version of the application I am currently interacting with is congruent with the source files I'm editing. That means not only that the application must be running the most up-to-date version of the code, but also that any state in the application was produced by that same code. It is dangerously easy, when changing and reloading code at the REPL, to get an application into a state which could not have been reached by the code it is currently running.

Therefore, after every significant code change, I want to restart the application from scratch. But I don't want to restart the JVM and reload all my Clojure code in order to do it: that takes too long and is too disruptive to my workflow. Instead, I want to design my application in such a way that I can quickly shut it down, discard any transient state it might have built up, start it again, and return to a similar state. And when I say quickly, I mean that the whole process should take less than a second.

To achieve this goal, I make the application itself into a transient object. Instead of the application being a singleton tied to a JVM process, I write code to construct instances of my application, possibly many of them within one JVM. Each time I make a change, I discard the old instance and construct a new one. The technique is similar to dealing with virtual machines in a cloud environment: rather than try to transition a VM from an old state to a new state, we simply discard the old one and spin up a new one.

Designing applications this way requires discipline. First and foremost, all state must be local. Any global state, anywhere, breaks the whole model. Second, all resources acquired by the application instance must be carefully managed so that they can be released when the instance is destroyed.

Enough talk. Here's how it works.

Read More »

Popular Tags