Jan 12 2012


ThinkRelevance: The Podcast - Episode 003 - Brenton Ashworth on ClojureScript One

I was particularly excited to record this, our third episode of ThinkRelevance: The Podcast. That's because on today's show, we talk with Brenton Ashworth about ClojureScript One, which was released just this week. As Brenton will explain, ClojureScript One is a project aimed at helping people learn how to use ClojureScript quickly and effectively.

Download the episode here.

As a reminder, you can subscribe to the podcast using our podcast feed. I'm still working on getting the show added to iTunes, but that should happen pretty soon.

You can send feedback about the show to, or leave a comment here on the blog. Thanks for listening!

Show Notes

Jan 05 2012


ThinkRelevance: The Podcast - Episode 002 - David Liebke on Avout

Hello, and welcome to the second episode of ThinkRelevance: The Podcast. We had so much fun last time that we thought we'd do it again! This time, we talk to David Liebke (@liebke), a developer here at Relevance. The main thrust of our conversation centers on Avout, a Clojure library for managing distributed state in a consistent manner. Avout is pretty cool, and we get to hear David explain it, as well as talk a bit about the source of the names of all David's projects, the book Anathem.

Download the episode here.

In other exciting news, the show now has an actual feed, just like a real, grown-up podcast. You can find it at I'll work on getting the show added to iTunes as the next step.

Also, I believe I forgot to mention this last time, but please send feedback about the show to Thanks for listening!

Show Notes

Dec 19 2011


ThinkRelevance: The Podcast - Episode 001

Relevance is a fascinating place to work. The primary reason for that, in my opinion, is the great people that work there. I find I'm constantly having interesting conversations with my coworkers, and it's not always about tech stuff. More than once I've had a random hallway conversation and thought, "Wow, if I had recorded that, it would make a pretty good podcast episode."

So that's what I'm doing. On a roughly weekly basis, I'm going to be releasing conversations with the people I am privileged to work with. We've got no set agenda: just have an interesting conversation about whatever people want to talk about.

As this is our first episode, I'm still figuring out how to do all the usual podcast stuff, like getting it on iTunes, creating a feed, and all that jazz. So for our inaugural episode, we're just going with a simple download link. I'll get all the fancy podcast stuff figured out, soon, I promise.

In this episode, I talk with Justin Gehtland, who's sort of our CEO (he explains the "sort of" in the episode). As is always the case when talking to Justin, it was a fun conversation. I hope you'll agree.

Show Notes

We mention a lot of people in the podcast. Here's a list of where to find them on the web:

Other notes:

Nov 15 2011


Documenting Architecture Decisions


Architecture for agile projects has to be described and defined differently. Not all decisions will be made at once, nor will all of them be done when the project begins.

Agile methods are not opposed to documentation, only to valueless documentation. Documents that assist the team itself can have value, but only if they are kept up to date. Large documents are never kept up to date. Small, modular documents have at least a chance at being updated.

Nobody ever reads large documents, either. Most developers have been on at least one project where the specification document was larger (in bytes) than the total source code size. Those documents are too large to open, read, or update. Bite sized pieces are easier for for all stakeholders to consume.

One of the hardest things to track during the life of a project is the motivation behind certain decisions. A new person coming on to a project may be perplexed, baffled, delighted, or infuriated by some past decision. Without understanding the rationale or consequences, this person has only two choices:

  1. Blindly accept the decision.

    This response may be OK, if the decision is still valid. It may not be good, however, if the context has changed and the decision should really be revisited. If the project accumulates too many decisions accepted without understanding, then the development team becomes afraid to change anything and the project collapses under its own weight.

  2. Blindly change it.

    Again, this may be OK if the decision needs to be reversed. On the other hand, changing the decision without understanding its motivation or consequences could mean damaging the project's overall value without realizing it. (E.g., the decision supported a non-functional requirement that hasn't been tested yet.)

It's better to avoid either blind acceptance or blind reversal.


We will keep a collection of records for "architecturally significant" decisions: those that affect the structure, non-functional characteristics, dependencies, interfaces, or construction techniques.

An architecture decision record is a short text file in a format similar to an Alexandrian pattern. (Though the decisions themselves are not necessarily patterns, they share the characteristic balancing of forces.) Each record describes a set of forces and a single decision in response to those forces. Note that the decision is the central piece here, so specific forces may appear in multiple ADRs.

We will keep ADRs in the project repository under doc/arch/

We should use a lightweight text formatting language like Markdown or Textile.

ADRs will be numbered sequentially and monotonically. Numbers will not be reused.

If a decision is reversed, we will keep the old one around, but mark it as superseded. (It's still relevant to know that it was the decision, but is no longer the decision.)

We will use a format with just a few parts, so each document is easy to digest. The format has just a few parts.

Title These documents have names that are short noun phrases. For example, "ADR 1: Deployment on Ruby on Rails 3.0.10" or "ADR 9: LDAP for Multitenant Integration"

Context This section describes the forces at play, including technological, political, social, and project local. These forces are probably in tension, and should be called out as such. The language in this section is value-neutral. It is simply describing facts.

Decision This section describes our response to these forces. It is stated in full sentences, with active voice. "We will ..."

Status A decision may be "proposed" if the project stakeholders haven't agreed with it yet, or "accepted" once it is agreed. If a later ADR changes or reverses a decision, it may be marked as "deprecated" or "superseded" with a reference to its replacement.

Consequences This section describes the resulting context, after applying the decision. All consequences should be listed here, not just the "positive" ones. A particular decision may have positive, negative, and neutral consequences, but all of them affect the team and project in the future.

The whole document should be one or two pages long. We will write each ADR as if it is a conversation with a future developer. This requires good writing style, with full sentences organized into paragraphs. Bullets are acceptable only for visual style, not as an excuse for writing sentence fragments. (Bullets kill people, even PowerPoint bullets.)




One ADR describes one significant decision for a specific project. It should be something that has an effect on how the rest of the project will run.

The consequences of one ADR are very likely to become the context for subsequent ADRs. This is also similar to Alexander's idea of a pattern language: the large-scale responses create spaces for the smaller scale to fit into.

Developers and project stakeholders can see the ADRs, even as the team composition changes over time.

The motivation behind previous decisions is visible for everyone, present and future. Nobody is left scratching their heads to understand, "What were they thinking?" and the time to change old decisions will be clear from changes in the project's context.

Experience Report

You may have noticed that this post is formatted like an ADR itself. We've been using this format on a few of our projects since early August. That's not a very long time in the global sense, but early feedback from both clients and developers has been quite positive. In that time, we've had six to ten developers rotate through projects using ADRs. All of them have stated that they appreciate the degree of context they received by reading them.

ADRs have been especially useful for capturing longer-term intentions. We have several clients who are stabilizing their current systems, but looking toward a larger rearchitecture in the not-too-distant future. By writing these intentions down, we don't inadvertently make those future changes harder.

One potential objection is that keeping these in version control with the code makes them less accessible for project managers, client stakeholders, and others who don't live in version control like the development team does. In practice, our projects almost all live in GitHub private repositories, so we can exchange links to the latest version in master. Since GitHub does markdown processing automatically, it looks just as friendly as any wiki page would.

So far, ADRs are proving to be a useful tool, so we'll keep using them.

More Reading

Thanks to Philipe Kruchten for discussing the importance of architecture decisions. I'm told there is more about them in Documenting Software Architectures which is near the top of my reading queue.

Oct 24 2011


Now with four more awesome

We may have stopped pretending to be Apple but we haven't stopped adding more awesome to our team: Naoko Chamberlain, Clinton Nixon, Russ Olsen and Jenn Hudson.

Naoko's personality drove her to project management/coach calling. She’s a planner and couldn't help that if she tried. She hugely appreciates the details. It comes naturally to observe and attend to her surroundings, and she truly enjoys teamwork whether at work, play, or playing ball. She also loves to organize everything -- even her sock drawer is organized by color and type.

When Naoko is not planning to-do's or organizing her sock drawer she expresses her love for wine, conversations, and sports. When all three are in one place she is in an extra good mood (except for when Boilermakers, Yankees, or Colts are losing an important game).

Clinton has spent the last 12 years all over the technology industry, from monitoring network security at Three Letter Agencies to hacking for startups to managing teams of developers. After discovering both Ruby and Durham, NC six years ago, he's been a huge fan of both. He's spent enough time at Relevance game nights and other events that he's felt like part of the family for a long while. He has perfectly normal, non-nerdy hobbies outside of programming, like playing Dungeons & Dragons and playing the ukulele.

Russ Olsen started his career doing that other kind of engineering, the sort that involves electricity, gears and getting dirty. Pretty rapidly the wonder of computer programming lured Russ away, which probably explains why most of his fingers are still intact today.

Since turning to coding, Russ has worked on everything from 3D design and image processing software to database query engines and workflow systems. Russ first discovered Ruby back in 2000 when he went looking for a simple programming language to teach to his son. The seven year old lost interest, but Russ never did and he has been building increasingly sophisticated systems in Ruby ever since.

Russ also spends a fair bit of time promoting Ruby via public speaking and he helped found RubyNation, a regional Ruby conference held each Spring in Northern Virginia. Russ has also written extensively about Ruby in the form of two highly regarded books: The first, Design Patterns in Ruby was published in 2008 and is a complete reworking of the classic Gang of Four patterns for a modern dynamic programming language. Russ's second book Eloquent Ruby is a guide to writing idiomatic Ruby. Eloquent Ruby was an instant hit in the Ruby and Rails community when it was published earlier this year.

Russ also has been secretly enamored with parentheses since a very early age and lately has been dabbling in Clojure.

Jenn has 20 years of accounting and analytical experience in a wide range of industries including software, alternative energy, legal, construction, retail and photofinishing, working with both small business and major corporation settings. She has extensive experience at managing an entire business including preparing strategic plans, implementing new programs and products, marketing and analyzing performance. While away from the office, she enjoys cooking and entertaining, travel to far away places and following her daughter's volleyball team around the country.

I'd also like to wish our alumnus Shay Frendt the best of luck with our friends at Chargify. We love you, we miss you.

We're still looking for more awesome. If you'd like to join this awesome team, introduce yourself.

Aug 08 2011


Friday Update 1.1

Welcome to the latest installment of the critically acclaimed "Friday Update"! This week's theme is "In-browser Awesomeness (plus one more)", and boy do we have an exciting lineup for you today!

First up, our brilliant intern Vojto (pronounced VOY-toe) has spiked out a Cocoa library called Atmosphere which waits for client-side changes and pushes those changes to the server automagically. You can read more about it on his blog.

Next we have the illustrious Chad Humphries, who is investigating using Rails 3.1, Backbone.js and Jasmine to build applications. He is excited to announce that the Jasmine tests run both inside and outside the browser.

Continuing our theme, Bobby Calderwood and Alex Redington are working on an in-browser ClojureScript evaluator. A server is required to perform compilation, but, in conjunction with some additonal work from Alan Dipert and Brenton Ashworth, we could soon have a browser-connected REPL!

And our c-c-c-combo breaker: David Liebke is working on a Clojure library called cogito. It's a Clojure implementation of System-Z+, a probabalistic reasoner.

That's it for now!

And don't forget to sign up for Clojure/conj!

Aug 01 2011


Friday Update 1.0

An important part of Relevance's culture is the work we do on Fridays. Many of you have likely heard of 20% time. Perhaps you've even heard it from us! But for those who haven't, 20% time is time that is devoted entirely to personal development and contributing to the open-source community. It doesn't have to be open-source, but it almost always is. In fact, we used to call the 20% time "Open-source Friday," but decided to stop lest we discourage people from following interests or scratching itches that couldn't be open-sourced.

Since this time is so important to us, we've decided to share a cross-section of our Friday projects with the rest of you! Consider this the first of many Friday Updates.

On the Clojure front, the Clojure/core team has been focusing on porting Clojure and its libraries to the recently announced ClojureScript. In particular, keep your eye out for David Liebke's port of Annalemma, dubbed Apogee. And if you haven't seen it already, Stuart Sierra recently wrote a blog post about ClojureScript.

The team is also busy organizing the second Clojure/conj! Which you should sign up for today! Early bird pricing ends soon!

Rob Sanheim and Jamie Kite put together a Rails 3 engine called Honey Badger which sticks a badge onto the page of a running Rails app with the environment, current git SHA, or anything else you'd like displayed in non-Production environments.

Craig Andera recently released ShadowSpawn, a Windows utility for working with shadow copies. Check out his announcement for more details.

And last, but most certainly not least, Jess Martin has released an iOS library called CoolButtons. It allows you to draw glassy iOS-style buttons, all using CoreGraphics and no images.

See you next week!

Jul 25 2011


Rails 3.1 HackFest Wrap-up

Thanks to everyone who participated in the Rails 3.1 HackFest! I hope you enjoyed sharing your love of Rails, plus a few beers, as much as we did. It was great getting to know some of our neighbors.

In addition to upgrading a few Rails apps to the latest 3.1 release candidate, we also submitted a few RailsGuides patches, found a bug and submitted a failing test. We didn't even have a chance to fix it before grzuy picked it up and submitted the patch.

We ran into a few bumps moving to the 3.1 asset pipeline, but overall the upgrade from Rails 3.0 to 3.1 has been smooth. As for the 2.3 to 3.0 upgrade, Rails provides deprecation warnings in the previous point release, 3.0.9 as I write this, so the upgrade goes a little something like this:

  1. Upgrade to Rails 3.0.9
  2. Upgrade other gems as necessary (e.g., haml 3.0 to haml 3.1 + sass 3.1)
  3. Run tests, fix tests, rinse and repeat
  4. Walk through the application and fix any deprecation warnings that crop up in the rails log
  5. Upgrade to Rails 3.1

And now...your moment of zen.

Jul 20 2011


Rails 3.1 HackFest comes to Bull City, July 22-23

Join us at Relevance Inc. this Friday and Saturday as we participate in the Rails 3.1 HackFest.

Come on down for two days of upgradin', pipelinein', bug fixin' good times! This is a great opportunity to meet some local Rails hackers, work through the 3.1 upgrade process, and give back to the larger Rails community. If you're in town this Friday or Saturday, please drop by any time.

UPDATE: The Relevance office will be open Friday and Saturday from 8:30am until 6:00pm or after. Grab your laptop and swing by for an hour or camp out for both days; we'll be here...with pizza.

Find us at:
514 South Duke Street
Durham, NC 27701

For more information, please contact us via email at or by phone at 919-283-2748.

Jul 10 2011


Heroku-ification of a Clojure App

Here at Relevance, Inc we often use Heroku for our Rails apps. Unfortunately, there hasn't been a similarly easy deployment story for our Clojure web apps. Recently, Heroku has changed that with their Cedar stack.

My colleague, Craig Andera, has been working on a web port of a board game called Artifact. I noticed he added a GitHub Issue "Deploy app to Heroku" This seemed like the perfect time to show off just how easy it is to deploy a Clojure web app to Heroku.

I grabbed a recent commit that was configured to run a local Jetty server. Here is the simple process I followed to get his app deployed to Heroku. As a prerequisite, you should have a Heroku account as well as the heroku gem installed. That process is described on their site.

Start with cloning the repo

git clone
cd artifact

The next step is to create a new heroku app on cedar called artifact. When this command is run from inside your app, the remote heroku repository is automatically added for you.

heroku create --stack cedar artifact

Then modify the -main function to work with how Heroku manages ports. The change we are making here is to read the port from the environment variable when it is available.

In core.clj, change the following block of code from

(defn -main [& args]
  (run-jetty app {:port 8080}))


(defn -main [& args]
  (let [port (Integer/parseInt (get (System/getenv) "PORT" "8080"))]
    (run-jetty app {:port port})))

Next, create a Procfile in the root dir of the app to tell Heroku how to start our app. This tells the web dyno to use leiningen to launch the web server.

web: lein run -m artifact.core

Commit the changes and push to Heroku.

git add .
git commit -m "Heroku-ify"
git push heroku master

And finally view the page.

heroku open

You can see the app at It is still in early development, so expect to run into rough edges. If you'd like to help, I'm sure Craig would love your contributions.

The process of taking a working Clojure web app and moving it to Heroku took me less than ten minutes, a small code change, and an additional line of config. This is a major development in the life of Clojure web development. With Heroku, we can build an app with the power of Clojure and the ease of deployment that Heroku provides to other frameworks, such as Rails. This helps us continue to expand our business and offer choice in deployment strategies to all our customers.

For more detail than just this simple intro, be sure to read "Building a Database-Backed Clojure Web Application".

Popular Tags