Picture of stu

Clojure Wins Again

Steve Yegge's most recent post takes a right angle turn about a third of the way through, and begins a comparison of Emacs Lisp and JavaScript.

And the winner is ... Clojure!

OK, Steve didn't say that. What he did do was call out things he liked about JavaScript and Emacs Lisp.

For JavaScript:

  • momentum
  • (namespace) encapsulation
  • delegation (polymorphism?)
  • properties (by Steve's definition)
  • serialize to source

For Emacs Lisp:

  • Macros
  • S-Expressions

I first picked up Clojure looking for many of the same things that Steve wants. I found them. Clojure can do all the things on both lists above. (Serialize to source isn't formal yet, but check the mailing list. And of course, you will have to judge "momentum" for yourself.)

The scary thing is that Clojure wins the language war before you even learn about its signature features. When I started exploring Clojure, I quickly realized it had everything I wanted, which could be summarized as "Lisp that really embraces the Java platform."

Then Clojure changed the definition of what I wanted. Now I also want

If you have half an hour, watch a compelling vision of what software development will look like in 2010.

Picture of stu

RunCodeRun at the Professional Ruby Conference

I will be bringing RunCodeRun Beta invites to the Professional Ruby Conference in Boston next week. If you are attending the conference, and want to get your open source Ruby project configured for free Continuous Integration on RunCodeRun, come and see me.

If your build goes green, I will have a T-shirt for you (while supplies last).

Once you go green, you don't go back.

Picture of jgehtland

Minor bug fix to Vasco

  • Posted By Justin Gehtland on November 07, 2008

If you downloaded Vasco and ran into the bug where it couldn’t find “data.js”, that bug has been fixed. You should update from the git repo and try again. Thanks for the bug report in the comments, Andreas!

Picture of stu

Clojure Beta Book Available

  • Posted By Stuart Halloway on November 05, 2008
  • Tags

The Clojure Beta book is now available. Here's the Table of Contents. (Chapters with an asterisk are included in this beta.)

  • Preface*
  • Getting Started*
  • Exploring Clojure*
  • Working with Java*
  • Unifying Data with Sequences*
  • Functional Programming
  • Concurrency*
  • Macros
  • Multimethods
  • Third-Party Libraries
  • Case Study

Because this is a Beta book, and Clojure is continuing to evolve, there will be errata. Please let me know any problems you find, and I will address them in the next Beta.

Other Clojure resources

Picture of jgehtland

Vasco now supports nested routes

  • Posted By Justin Gehtland on November 03, 2008

I’ve added support for nested routes in Vasco. Whenever you have a standard nested resource scenario, Vasco will now prompt you for the appropriate parent(s) id(s) before your request.

Here is the list of nested routes from our sample app:

And here is the dialog prompting for both the direct ID and the parent resource ID:

This is brand new—if there are any bugs, please report them. Thanks!

Picture of jgehtland

Castronaut -- SSO, The Big Unit and a Fedora

  • Posted By Justin Gehtland on October 28, 2008

I’d like to introduce you to another Relevance open source project, Castronaut. Attentive readers will have noticed our focus on security issues, from code audits to books to restful authentication to SSO and on. We’ve used lots of different centralized authentication systems in the past, and have really settled on two options: OpenID and CAS. OpenID is great for public sites where the user pool is self-expanding; CAS is great for closed sites where the user pool is despotically maintained. (The reasons to choose between an open, decentralized protocol and an internal, managed one are many; this is just one simple vector).

In the past, we’ve used the original JA-SIG Java version of CAS, as well as the more recent RubyCas Server. In the end, we decided to write our own. The major reasons are:

  • we need a non-Java based solution. Some of our clients simply won’t allow JVM-based software in their systems.
  • we need a solution that is based on the MIT license, not the GPL (or LGPL, for that matter).
  • we need a solution that is testable and tested.
  • we need a way to create a project that has the word “Castro” in it.

We couldn’t get that combination with any of the existing projects, so we launched Castronaut into orbit. Here’s some things you’ll need to know.

Built on Sinatra

We stuck with Ruby for the implementation. Duh. However, we wanted to implement it in something lighter than Rails (and Merb) but needed more than Camping provided. We also wanted a testable and well-tested solution. Camping failed the sniff test because it isn’t well-tested, nor particularly testable. Sinatra, being a thin wrapper around Rack, is well tested, current and has lots of eyes on it.

Uses standard adapter architecture

Like any good authentication application, we provide a standard adapter architecture for our authentication providers. Right now, we are shipping with:

  • restful_authentication, which can be pointed at any data schema that restful_authentication itself can use.
  • ldap, with upcoming pre-authenticated ldap and active directory
  • development, which uses unencrypted credentials, for easy testing and experimenting

We built this to solve particular needs. We fully expect it to grow over time, as our needs and, hopefully, the needs of other users dictate. It is specifically this need to grow and change that led us to create Castronaut in the first place.

CAS 2.0 Spec compliance

We support all the major portions of the CAS 2.0 spec except proxy granting ticket IOUs. Which means we support ticket granting tickets, service tickets, proxy granting tickets and proxy tickets. Castronaut therefore allows for centralized authentication, single sign-on, and pass-through service authentication. We’ll tackle the IOU problem the first time we have a real-world usage for it. Feel free to provide us one.

Updated Small Things, Loosely Joined code samples

You can download a new set of the samples from my Small Things, Loosely Joined talk that use Castronaut. The only difference is the use of restful_authentication for the included apps and a small change to the rubycas-client configuration settings.

So, what’s next?

Installation is a snap, and well documented. You can install as a gem using:

> sudo gem install relevance-castronaut --source http://gems.github.com

Edit a config YAML file somewhere, and launch:

> castronaut -C [path-to-yml-file]

That’s it. We hope people will use it and give us feedback at our Lighthouse page.

Picture of jgehtland

Introducing Vasco: A Route Explorer for Rails

  • Posted By Justin Gehtland on October 22, 2008

We’d like to introduce Relevance’s latest open source project, Vasco. Vasco is a route explorer for Rails projects. As we develop applications with explicit requirements for RESTful APIs for integration purposes, our clients need some way to visually accept that the stories are complete. It is also helpful for the developers to have a way to manually interact with the APIs as a second avenue for testing, verifying whether our routes end in gold and silk, or pain and death. So, we wrote Vasco.

Vasco is a simple plugin, with a single rake task. Once installed and initialized, it creates a web interface that knows about all your RESTful routes and the models at the far end of them. It lets you play with the GETs, POSTs, PUTs and DELETEs and see the responses. If your APIs are protected by BASIC auth, no worries, since the plugin runs from inside your app. And if you are lucky, it will expand your colonial footprint and lead to Empire.

To install, just run:
> script/plugin install git://github.com/relevance/vasco.git
Once installed:
> rake vasco:explore

After that, launch your app and point your browser to http://localhost:3000/vasco (or wherever you home your dev apps). You’ll be treated to a simple interface. On the left is a list of all the controllers in the app with RESTful routes associated with them. On the right are two boxes, one for viewing the request, one for the response. Click any controller to expand its list of available routes. If you click on something like, in this example, GET /ports, Vasco will send the request to your app and display the results immediately.

If you click on a route that requires user input, like PUT /ships/:id, a dialog will appear with a form you can fill in. The :id field will be prepopulated with a known ID from the database, assuming your database had fixture or other data loaded when you ran the vasco:explore task. You can fill in the rest of the form and either commit the request, or cancel.

After PUTting the request, the results will again be displayed. When a call only returns a status code, the results will be displayed as a simple success or failure message.

We’ve got docs on the GitHub wiki, as well as a list of upcoming features. We hope you enjoy Señor de Gama.

Picture of stu

Participate in a Clojure Case Study

  • Posted By Stuart Halloway on October 20, 2008

Relevance is seeking a partner for a Clojure case study. Here's the deal:

  • You have a small but non-trivial application slated for development in Java. (Let's say $20K - $50K budget).
  • Relevance builds your application in Java, per your budget.
  • Relevance builds a second version of the application in parallel, for free, in Clojure.
  • You own the Intellectual Property for both the Java and Clojure versions.
  • Relevance produces a case study comparing the two implementations. The case study cites extensively from both codebases.
  • Relevance releases the case study under a Creative Commons License.

If you are interested, give us a call at 919.442.3030, or email stu at thinkrelevance.com.

For more about Clojure, check out the home page and these video introductions. For more about Relevance, check out our approach and our list of satisfied clients.

[10/21/2008: updated to make clear that the two versions will be developed in parallel, not in sequence.]

Picture of glenn

RunCodeRun Badges

  • Posted By Glenn Vanderburg on October 17, 2008
  • Tags

Like all of us here at Relevance, I’m very excited about RunCodeRun, the hosted continuous integration service we’ve been building. This week I wrote runcoderun-badges, to make it easy to display the build status of our open-source projects on any web page we choose. One of the core benefits of continuous integration, after all, is accountability—and how better to hold yourself accountable than by showing your integration status to the world?

RunCodeRun badge screenshot

I started with Dr Nic’s wonderful GitHub badges (it would’ve been foolish not to!) but a lot has changed. I’ll keep this up to date as RunCodeRun evolves.

If your open source projects are already on RunCodeRun, check out the runcoderun-badges README for information on adding a badge to your blog. (And if your projects are not yet on RunCodeRun, drop by and request an invitation.)

Update: As Dan Manges discovered, these badges don’t play nicely with the GitHub badges on the same page. The problem appears to stem from the way each badge depends on JQuery. For now, consider using just the RunCodeRun badge (you can get to a project’s GitHub repository from its page on RunCodeRun), but I know that’s not a good long term solution, so I’m working to fix the problem.

Picture of jgehtland

Updates on the New Mothership

  • Posted By Justin Gehtland on October 16, 2008

Michelle went over to check out the progress on the new offices and found they had repainted the outside of the building. It used to be a dingy powder blue, but look at her now! All shiny and butter-cream!

We’re the second floor, corner. The apartments are the third floor of that sage building at the back. Man, I can’t wait to get in there.

Picture of jason

Refactotum Coming to Raleigh Ruby Camp

  • Posted By Jason Rudolph on October 15, 2008

This Saturday, we'll be hosting a half-day Refactotum session at Raleigh Ruby Camp to help developers contribute to open source Ruby and Rails projects. By setting aside just a few hours and following some key steps, every developer can make a meaningful contribution to open source.

If you want to hit the ground running on Saturday, take a few moments to look over the Refactotum Overview, grab rcov, flog, and tarantula, and consider downloading the code for an open source project that interests you.

The Refactotum kicks off at 9:30 AM. See the Raleigh Ruby Camp wiki for location information and to reserve your spot. Hope to see you there!

Picture of rob

Introducing RunCodeRun

  • Posted By Rob Sanheim on October 14, 2008
  • Tags

Relevance is pleased to be able to introduce you to RunCodeRun—a hosted continuous integration service for Ruby and Rails projects. We’ve been working on it for a few months now, and have been in a private beta mode, but as of today we’ve reached a major milestone. Today, anybody can surf to RunCodeRun and browse all the open source projects that have been building there and view their build histories.

We are also happy to announce that we are going to be sponsoring Rails Rumble by providing hosted continuous integration for interested teams. We’ll have several team members providing support over the weekend and helping to make sure any test-driven Rumble teams can keep their projects happy and green. We’ll have more details on the Rumble partnership at the RunCodeRun blog.

Why a hosted continuous integration service?

We, like just about everybody else on Planet Ruby, are ga-ga for GitHub. Social source control has been a major factor in open source for a long time, but GitHub really elevated the game. It makes setting up source control for your project dead simple, and eliminates the front-end IT pain of managing a project. That still leaves continuous integration, the back-end IT pain, up to the team. We want CI to be as automatic, and as easy, as source control, and the way to do that is a hosted solution.

If GitHub enables easy sharing and collaboration, RunCodeRun will enable easy builds and quality metrics to find out which projects to depend on and which to pass over. To learn more about RunCodeRun and follow our progress, subscribe to the RunCodeRun blog. See you on the other side.

Picture of jgehtland

Greening Relevance

  • Posted By Justin Gehtland on October 13, 2008

Some of you may already know, but I was not a CS major in college. In fact, I doubled in English and, a new major at the time, Environmental Science and Policy. Now, as the founder of a software company, I’m just as interested in my academic areas as I was then, but I’m trying to apply them through the filter of how I spend my days (and evenings, and late nights, and …).

I’m pretty sure you can spot the English major trying to poke its way out of my chest, but that ES/P stuff? What about it? That turns out to be a hard nut to crack. What does a software company do to try to go (or stay) green? We don’t have fleet vehicles to turn into hybrids or hydrogen guzzlers. We only have a small amount of office space to heat and cool, and we don’t control the HVAC settings most of the time. We don’t have factories, our emissions are mostly of the code and pomposity varieties, and the last thing I remember polluting the environment with was the simple_services plugin.

So, we went out and got ourselves some new digs. We partnered up with a company called Greenfire, who has been working with the city of Durham to renovate some of the historical districts of downtown, but with an environmentally conscious bent. Our new office space is being renovated with LEED certified techniques and materials. They drilled three monstrous geothermal wells to provide the temperature regulation for the space. They are reusing materials from the interiors of other buildings being demolished. Our windows ACTUALLY OPEN. To the OUTSIDE.

In addition to the nature of the builder and their procedures, we get one extra benefit. Not only are we getting a kick-ass office, we are also renting the two apartments upstairs and two of our team are going to move in, thus chopping a whole lot of commute out of our team’s day. Another team member is going to bike to work (since the building has an indoor bike rack and some showers) cutting another commute out, and preventing the early onset of heart disease.

I believe strongly that those of us in the business sector have a responsibility to use our energies in ways that don’t just prevent negative consequences, but actually foster positive ones. Moving into the new offices is just one is just one small step that we can take. I’ve also seen other groups take some strong steps, and I’m hoping to hear from more folks in our neck of the economy as well. I feel that there’s still more we can do. Those of you working in software, what other changes have you been able to make (or been wanting to make) to go green?

Picture of jgehtland

Relevance is upgrading the mothership

  • Posted By Justin Gehtland on October 10, 2008

We’re thrilled to announce that Relevance is moving the North Carolina headquarters from the outskirts of Chapel Hill to the heart of downtown Durham. We’re in the buildout phase of development now, but expect to be in the new offices by the start of the year.

Why are we moving, you might ask?

For starters, our current offices were designed to hold our company for about three years’ worth of growth, but it turns out we underestimated our growth curve by about 2.25 years. The NC office is bursting at the seams, and even though we do an awful lot of pair programming sitting crammed around a table, everybody wants to have a little room to breathe, right?

Secondly, I’m a Durhamite and have wanted to be part of the resurgence of downtown since it really started a few years ago. As we cast around for alternatives to our current space, it became clear we could be part of the rebuilding of the historic districts of downtown, and get a more urban environment for our team to hang out in. Our new office space will have food and drink and fun within walking distance, which you just can’t get out in the burbs.

So, we’re doubling our space, and building out the perfect working environment for a team of agile, enterprisey code samauri. We’ll post some pics of the new digs as the buildout continues. And maybe pics of our mopey faces while we wait for moving day.

Picture of stu

PCL -> Clojure, Chapter 17

  • Posted By Stuart Halloway on September 25, 2008
  • Tags

This article is part of a series describing a port of the samples from Practical Common Lisp (PCL) to Clojure. You will probably want to read the intro first.

This article covers Chapter 17, Object Reorientation: Classes.

Creating structs

Common Lisp defines classed with defclass. In Clojure, I can define structs with defstruct:

(defstruct bank-account :customer-name :balance)

The bank-account struct has two basis keys: customer-name and balance. I can specify values for these keys, in the order they were declared, using struct:

user=> (struct bank-account "John Doe" 1000)
{:customer-name "John Doe", :balance 1000}

With struct, all the basis keys are optional:

user=> (struct bank-account)
{:customer-name nil, :balance nil}

If you prefer named parameters, you can use struct-map instead of struct:

user=> (struct-map bank-account :balance 10)
{:customer-name nil, :balance 10}

Very important: structs are still maps. I can specify additional keys that are not part of the basis:

user=> (struct-map bank-account  :balance 10
                                   :customer-name "Jane Doe"
                                   :status :gold)
{:customer-name "Jane Doe", :balance 10, :status :gold}

Accessing structs

The examples below assume an example-account:

(def example-account (struct bank-account "Example Customer" 1000))

Pedants call get to access a structure value:

user=> (get example-account :customer-name)
"Example Customer"

But that's way too much effort. Structures are functions of their keys:

user=> (example-account :customer-name)
"Example Customer"

If the struct keys are symbols, I can go the other way. Symbols are functions of structs:

user=> (:customer-name example-account)
"Example Customer"

Other than symbols, what else can be a structure key? Ah, sweet immutability. Since Clojure data structures are immutable, any of them can function as keys.

I can use assoc and dissoc to get a new map with a key added or removed:

user=> (assoc example-account :status :elite)
{:customer-name "Example Customer", :balance 1000, :status :elite}

user=> (dissoc {:a 1 :b 2} :a)
{:b 2}

But I can't dissoc from example-account because you can never remove a basis key:

user=> (dissoc example-account :customer-name)
java.lang.Exception: Can't remove struct key

Defaults and validation

Since structs are also maps, default values are easy: just merge them. The example below doesn't even use a struct. (Often duck typing is good enough.)

(def account-defaults {:balance 0})
(defn create-account [options]
  (merge account-defaults options))

If I want to validate fields, I can just write a validation function. Here is a validation that simply requires non-false values:

(defn validate-account [account]
  (or (every? account [:customer-name :balance])
      (throw (IllegalArgumentException. "Not a valid account"))))

Of course, if I wanted to create tons of different structs with similar validations, I could build some helpers. Macros + metadata would be one way to go.

Wrapping up

Clojure's structs fill some of the same roles as Common Lisp's classes. The exmaples above show how to create and access structs, and how to add default values and validation.

That said, Clojure's structs are not classes. They do not offer inheritance, polymorphism, etc. In Clojure, those kinds of jobs are handled by the incredibly flexible defmulti (see the previous article for details, especially the references at the end).

Notes