Picture of glenn

Tarantula Supports Ruby 1.9

We’re excited about Ruby 1.9. It’s fast and stable, and brings nice improvements for programmers. But there are obstacles to adoption—mostly gems, plugins, and tools that don’t support 1.9 yet.

So we’re working on the things Relevance maintains, to get them on board. We’re doing it by dog-fooding: We’ve got one customer project that we’re actively testing on both 1.8 and 1.9 (although deployment is still on 1.8 for the moment). That’s helping us see where the holes are, so we can fix them. We’re already working on Ruby 1.9 support for RunCodeRun, and investigating the best way to interface rcov with 1.9.

Now one more piece of the puzzle is in place: on our last open-source Friday, Chad upgraded Tarantula to support Ruby 1.9. If you’re trying out Rails on 1.9 (or even if you aren’t), get the latest version (0.2.1) of tarantula from github:

gem install --source http://gems.github.com relevance-tarantula

Then add the plugin to your app and add some fuzz-testing goodness to it!

Picture of glenn

The Longevity of "Enterprise" Tools

During the recent erubycon conference, there was a lot of twitter traffic from attendees about how great the conference was. One who did not attend wondered if a conference discussing “Ruby in the enterprise” was wishful thinking or reality?.

Sorry if this disappoints anyone, but there was almost no wishful thinking, and a lot of reality. But there’s a third option: planning next moves. There was a lot of discussion about how to promote Ruby effectively in enterprises that aren’t already using it—not because Ruby is the be-all, end-all of programming (it’s not) but because we have all found it helpful across a wide variety of programming tasks, and we think it is a good antidote for the more common, “enterprisey” tools that often bring more bad than good to a project.

During a panel discussion right after my keynote (Why “Enterprise Tools” are Bad for the Enterprise), someone asked “What do we say to a manager who doesn’t trust open-source tools to still be around in a few years?”

Something snapped in me—I’d heard that same question one too many times. Commercial tools are available solely based on their customers. If the tool gets enough customers, the tool continues. Otherwise, it will all disappear. And it must disappear, given the nature of the software business.

There are three scenarios (with variations) for new software development tools, and all are common:

  • get enough customers to be profitable, and continue for many years.
  • get enough customers to look viable, get purchased and see the tool squashed or sidelined by the new owners.
  • get just a few customers, and have your board shut you down.

When you choose a commercial tool, you’re making a bet that enough other people will purchase it to make it viable, and that it won’t be purchased and shut down by a competitor.

When you choose open-source tools, there is no monetary pressure on the toolmaker to continue; only community pressure. It’s much easier (and cheaper) to bring community pressure. Additionally, even if the toolmaker chooses not to continue, the community can keep the tool alive. Many open-source development tools that have long since dropped from most people’s radar (think Tcl, for example) still have thriving communities that actively support the tools and help each other with difficulties. With a proprietary tool, the legal structures surrounding it virtually guarantee that the tool will die if the vendor loses interest.

In every respect, open source tools have a better chance of surviving than their commercial cousins. Sure, some of those commercial tools will be viable for a long time, but most won’t. Whereas most open source tools will be around for a long time. Open source tools actually diminish risk, not enhance it.

Anyway, getting back to the panel question at erubycon: I decided it was time for action, because this is such an easy point to refute with just a little preparation.

So I volunteered to play scribe during the party that evening, and I spent much of the party sitting in a chair with a pad and pen, while attendees helped me remember “enterprise tools” that have come and gone. We built a list of commercial, “enterprise” software development tools of one sort or another that were commercially viable no longer ago than 1995 (when Java first hit the scene) but which are now “dead”. (“Dead”, for purposes of this list, means either that there is no longer commercial support for the tool, or that there has been no significant new development on the tool in the past five years.)

It’s a long list.

The point of this is not to prove that open-source tools are better than proprietary tools (obviously I think they are in most cases, but this list won’t prove it either way). The point is to show clearly that there is no guarantee that a tool will still be around and supported after a few years, proprietary or not.

I’m sure there are other tools that we didn’t think of. I’m equally sure that some of the tools currently on the list are actually alive; the fact that attendees at erubycon haven’t heard of a tool for a while doesn’t mean it isn’t still being maintained and supported somewhere. (Here’s a good example. I thought of a tool that seemed like an open-and-shut case for this: NetDynamics, the original Java application server. A little research shows that it was purchased by Sun, and some of its code formed the basis for the iPlanet application server, which was later called Sun ONE, and then the Sun Java Enterprise System, and is now called GlassFish. Nevertheless, I strongly doubt that old apps written for NetDynamics would run on GlassFish, and I’d be interested to know whether there was ever a clear migration path for NetDynamics customers.)

So I’m starting the task of double-checking that list. If you’re interested in helping, send me email! I’ll blog about the results here.

Picture of stu

Rifle-Oriented Programming with Clojure

  • Posted By Stuart Halloway on August 12, 2009
  • Tags

Any comparison of hot JVM languages is likely to note that “Clojure is not object-oriented.” This is true, but it may lead you to the wrong conclusions. It’s a little like saying that a rifle is not arrow-oriented. In this article, you will see some of the ways that Clojure addresses the key concerns of OO: encapsulation, polymorphism, and inheritance.

This is a whirlwind tour, and we won't have time to cover the full details of all the Clojure code you will see. When we are done, I hope you will decide to explore for yourself. You can download and start using Clojure by following the instructions on the getting started page.

Just Enough Clojure Syntax

Clojure has vectors, which are accessed by integer indexes:

[1 2 3 4]
-> [1 2 3 4]

(get [:a :b :c :d :e] 2)
-> :c

In the preceding example, the initial [1 2 3 4] is input that you enter at the Read-Eval-Print Loop (REPL). The -> indicates the response from the REPL.

Clojure has maps, which are key/value collections:

{:fname "Stu", :lname "Halloway"}
-> {:fname "Stu", :lname "Halloway"}

Sets contain a set of values, and their literal form is preceded with a hash. Here is the set of English vowels, using backslash to introduce a character literal:

#{\a \e \i \o \u}
-> #{\a \e \i \o \u}

Lists are singly-linked lists, and are enclosed with parentheses. Lists are special: Not only are they data, they also act as the syntax for invoking functions. The list below invokes the plus (+) function:

(+ 1 2 3 4 5)
-> 15

Collections themselves act as functions. They take an argument which is the key/index to look up:

([:a :b :c :d :e] 2)
-> :c

({:name "Stu" :ext 101} :name)
-> "Stu"

Enough syntax, let's get started.

Encapsulation

Encapsulation is the hiding of implementation details so that clients of your code do not accidentally become dependent on them. In object-oriented languages, this is ususally done at the class level. A class has public methods, private implementation details, and various other scopes in between.

Clojure accomplishes the purposes of encapsulation in three ways: closures, namespaces, and immutability.

Closures

A closure closes over (remembers) the environment at the time it was created. For example, the function make-counter below closes over the initial value passed via init-val:

(defn make-counter [init-val] 
  (let [c (atom init-val)] #(swap! c inc)))

Let’s break this down:

  • defn defines a new function, named make-counter, that takes a single argument init-val.
  • The let binds the name c to a new atom.
  • The atom creates a threadsafe, deadlock-proof mutable reference to a value.
  • The octothorpe (#) prefix introduces an anonymous function
  • The call to swap! updates the value referenced by c by calling inc on it.
  • The value of the let is the value of its last expression. This let returns a function that increments a counter, which is then the return value of make-counter.

The atom c is private to the function returned by make-counter. The only public thing you can do is increment it by one:

(def c (make-counter))
-> #'user/c

(c)
-> 1

(c)
-> 2

(c)
-> 3

The counter example returned a single function, but nothing stops you from returning multiple functions. These multiple functions can then share private state. The new version of make-counter below returns two functions: one to increment the counter, and one to reset it.

(defn make-counter [init-val] 
  (let [c (atom init-val)] 
    {:next #(swap! c inc)
     :reset #(reset! c init-val)}))

This new make-counter returns a map whose :next value increments the counter, and whose :reset value resets it:

(def c (make-counter 10))
-> #'user/c

((c :next))
-> 11

((c :next))
-> 12

((c :reset))
-> 10

Why the double parentheses above? Two functions calls: The inner function call looks up the appropriate function, and the outer one calls it.

Closing over data is far more general than the simplistic model offered by private, protected, public, friend, et al. in OO languages. By combining multiple lets and multiple return values from a function, you can create arbitrary encapsulation strategies.

Similar encapsulation possibilities are available in any language that supports closures. Douglas Crockford describes a similar idiom in JavaScript.

Namespaces

A Clojure namespace groups a set of related data and functions. Inside a namespace, a Clojure var can refer to a function or to data, and can be public or private.

For example, Chris Houser’s error-kit library implements a condition/restart system for Clojure.

(with-handler
  (vec (map int-half [2 4 5 8]))
    (handle *number-error* [n]
      (continue-with 0))) 

In the code above, with-handler, handle, and continue-with are public vars of the clojure.contrib.error-kit namespace. The int-half is a demo function that blows up on odd inputs. When a *number-error* occurs, the handler causes execution to continue with the value 0. (Note how this is more flexible than try/catch exception handling, which cannot recover back into the middle of some operation.)

Internally, error-kit keeps track of available handlers and continues using these private vars:

(defvar- *handler-stack* () 
  "Stack of bound handler symbols")
(defvar- *continues* {} 
  "Map of currently available continue forms")

The trailing minus sign on the end of defvar- marks the vars as private. These vars are implementation details, and are invisible to code outside the clojure.contrib.error-kit namespace.

Immutability

In OO languages, another purpose of encapsulation is to prevent object A from modifying or corrupting the private data used by object B.

In Clojure, this problem does not exist. Data structures are immutable. They cannot possibly be corrupted, or changed in any way, period. You can write query functions that return “private” state, without any fear of data corruption.

Polymorphism

For our purposes here, polymorphism is the ability to choose a different method implementation based on the type of the caller. So for example:

Flyer a = new Airplane();
Flyer b = new Bird();
a.fly();
b.fly();

a.fly() and b.fly() do different things because they are called on different concrete types.

Clojure provides a generalization of polymorphism called multimethods. A multimethod definition begins with defmulti, and then has a name, plus a dispatch function that is used to select the actual implementation: To mimic polymorphism, simply dispatch on the class of the argument:

(defmulti fly class)

Individual methods of a multimethod begin with defmethod, then the multimethod name, then the object that must match the dispatch function. Finally, you get the argument list in a vector, followed by the implementation of the method. For example:

(defmethod fly Bird [b] (flap-wings b))
(defmethod fly Airplane [a] (turn-propeller a))

Unlike polymorphism, multimethods do not limit you to dispatching on class. You can dispatch based on any arbitrary function of the method arguments. So for example, a bank account might have a :type entry that is used to determine the interest rate:

(defmulti interest :type)
(defmethod interest :checking [a] 0)
(defmethod interest :savings [a] 0.05M)

The :type attribute is a convention, but nothing prevents you from dispatching on a different attribute, or even dispatching on more than one at the same time! For example, the service-charge multimethod below dispatches on two different facets of the same object: the object’s account-level (::Basic or ::Premium) and its :tag: (::Checking or ::Savings)

(defmulti service-charge 
  (fn [acct] [(account-level acct) (:tag acct)]))
(defmethod service-charge [::Basic ::Checking]   [_] 25)
(defmethod service-charge [::Basic ::Savings]    [_] 10)
(defmethod service-charge [::Premium ::Checking] [_] 0)
(defmethod service-charge [::Premium ::Savings]  [_] 0)

The _ is a legal name, and is used idiomatically to indicate that an argument will be ignored. (There is no need to even look at the argument, since all the work has been done in choosing which method to dispatch to!) This example also demonstrates two other concepts:

  • The double-colon prefix resolves a keyword in a namespace. This prevents name collisions among keywords, just as object-oriented langauges use namespaces to prevent name collisions between type names.
  • account-level is a function (not shown here), not a simple key lookup. It returns ::Premium or ::Basic based on the the account type and the current balance. Thus an account can dynamically change its account level as its balance changes.

As you can see, multimethods are far more general than polymorphism. Instead of being limited to type-based dispatch, multimethods can dispatch on any arbitrary function of an argument list. This allows programming models that more closely resemble reality: after all, what real-world entities are limited to a single type hierarchy, and forbidden to change types over time?

Inheritance

In OO languages, inheritance allows you to create a derived type that reuses the behavior of a base type. For example:

class Person {
  String fullName() { /* impl details */ }
}
class Employee extends Person {
  AddressBookItem companyDirectoryEntry() { /* impl details */ }
}

This kind of reuse is so natural in Clojure that it doesn’t even have a name. For example, here is a function that returns the full name of a person, based on first and last names:

(defn full-name [p]
  (str (:first-name p) " " (:last-name p)))

Employees are like people, but have other properties and behaviors, such as a telephone extension. The company-directory-entry returns a vector of an employee's full name and telephone extension, like this:

(defn company-directory-entry [p]
  [(full-name p) (:extension p)])

Notice that company-directory-entry “reuses” the person-ness of its argument p by calling full-name on it. There is no special inheritance ceremony required to set this up, you just call functions when you need them.

You can pass either a person or an employee to full-name. For company-directory-entry, though, you must have an employee. Or, more accurately, you must have something that resembles an employee, to the extent of having a :first-name, :last-name, and :extension. This is an example of duck typing: if it walks like a duck and quacks like a duck, we assume it is a duck, without asking it to present its IDuck papers.

Many Functions, Few Types

The example above demonstrates another negative consequence of idiomatic OO style: the over-specification of data types. The return value of companyDirectoryEntry is given its own unique type, AddressBookItem. Each new data type like AddressBookItem requires its own life-support system: constructors, accessors, equals, hashCode, and so on.

In Clojure, an address book item would simply be a vector or a map. No new types, and no life support system required. Moreover, an address book item can be manipulated with any of the large arsenal of functions in Clojure's sequence library.

To see the problem with overspecifying types, consider this method from the Apache Commons:

// From Apache Commons Lang, http://commons.apache.org/lang/
public static int indexOfAny(String str, char[] searchChars) {
    if (isEmpty(str) || ArrayUtils.isEmpty(searchChars)) {
	return -1;
    }
    for (int i = 0; i < str.length(); i++) {
	char ch = str.charAt(i);
	for (int j = 0; j < searchChars.length; j++) {
	    if (searchChars[j] == ch) {
		return i;
	    }
	}
    }
    return -1;
}

The purpose of indexOfAny is to find the index of the first occurrence of one of the searchChars that appears in str. Note the unnecessary specificity of types: it works only with strings and character arrays.

Here's the Clojure version, using the sequence library's map, iterate, and for forms:

(defn indexed [coll] (map vector (iterate inc 0) coll))
(defn index-filter [pred coll]
  (when pred 
    (for [[idx elt] (indexed coll) :when (pred elt)] idx)))

Here is an example calling index-filter:

(index-filter #{\a \e \i \o \u} "Lts f cnsnts nd n vwel")
-> (20)

The expression above finds the index of the first vowel in the string "Lts f cnsnts nd n vwel", that is, 20. But index-filter is more general than the Commons version in several ways:

1. index-filter returns all the matches, not just one.

(index-filter #{\a \e \i \o \o} "The quick brown fox")
-> (2 6 12 17)

2. index-filter works with any sequence, not just a string of characters. For example, the call below works against a range of integers:

(index-filter #{2 3 5 7} (range 6))
-> (2 3 5)

3. index-filter works with any predicate, not just a test against a character array. In the example below, the predicate is an anonymous function that tests for strings longer than three characters:

(index-filter #(> (.length %) 3) ["The" "quick" "brown" "fox"])
-> (1 2)

That is a lot of extra power, especially given that the function is shorter, easier to write, and easier to read (given some Clojure experience, of course) than the Commons version.

Conclusion

Clojure solves the same problems that OO solves, but it solves them in different ways. Instead of encapsulation, polymorphism, and inheritance, you have closures, namespaces, pure functions, immutable data, and multimethods. Idiomatic OO gives you a bloated type system with duplicated code hidden away behind encapsulation boundaries and little hope for thread safety. Clojure offers a radical alternative: a lean type system, a rich function library, and language-level concurrency support that is usable by mere mortals.

There is a lot more to Clojure than we have covered here: lazy and infinite sequences, destructuring, macros, software transactional memory, agents, seamless Java interop, and more. But those are topics for another day.

[This article was originally published in the May 2009 issue of NFJS, the Magazine. I will be speaking about Clojure at several upcoming NFJS events, come join the fun.]

Picture of jgehtland

RunCodeRun now supports private builds

  • Posted By Justin Gehtland on August 04, 2009

We are pleased to announce that RunCodeRun is now accepting private builds. This means that you can now connect your private repositories on GitHub to RunCodeRun for your continuous integration needs. You can drop by our list of plans to see which best suits your situation.

We feel it important to note that RunCodeRun remains, as always, free for open source developers. If you are already an open source customer and want to upgrade, just sign in and head to the plans page and pick the option that works for you. You can keep all your open source projects active, now and forever, regardless of which plan you are on. And if you are just interested in getting started with an open source project? That’s easy: just sign up for an open source account. You can always upgrade later if you want to add private builds.

We look forward to seeing your projects clean and green!

Corey Haines was in our neck of the woods recently, and we were delighted to host him for three days of pairing and great conversations. We’re very fond of the craftsmanship model of software development, especially as a method of training. Although we haven’t gone about it as explicitly as Corey has in his journeyman tours, we all feel that we learned our skills largely through working with great programmers. (And if we had it to do over again, we’d seriously consider following Corey’s example and really being journeymen for a while.) Our interview process here involves a full day on-site, pair programming with members of our team, and we often learn cool things from even that amount of cross-pollination. So we felt especially fortunate having three days with Corey.

Corey arrived with an interest in Clojure, so he spent most of his time pairing with Stuart on one of our Clojure projects. And he stayed with Muness, in his apartment right upstairs from our office. The result? Two cool video interviews:

We couldn’t be happier with how these turned out. They highlight Stuart and Muness and their passions, but they show a lot about the rest of us here at Relevance as well. Thanks, Corey!