The Importance of Language

I needed to write a new test that would prove that I had unique entries in an array and I’d long grown tired of adding items through Rails’ fixtures. I wanted to create a number of articles in my test that I could use as the sample data. My first shot was roughly as follows:




123456789101112131415161718192021222324252627282930
def test_can_load_unique_articles  number_of_iterations = 8   existing = Article.find_all.length      article = create_articles(number_of_iterations)  assert_equal number_of_iterations - 1, article.related_articles.sizeend  def create_articles(number_of_iterations)  test_article = nil  1.upto number_of_iterations do |n|    a = create_valid_article    a.save!          test_article = a  end    test_articleenddef create_valid_article  a = Article.new()  a.user_id = 1  a.body = "Foo"  a.title = "Zzz"  a.keywords = 'testing1 testing2 testing3'  a.published = true        a.keywords_to_tagsend

It’s a pretty beastly piece of Ruby code, but it worked. I then took a stab at tidying it up, after a few iterations of smaller refactorings I ended up with:




1234567891011121314151617181920212223242526272829
def test_can_load_unique_articles  number_of_iterations = 8  existing = Article.find_all.length         articles = create_articles(number_of_iterations) do     create_valid_article  end      assert_equal number_of_iterations - 1, articles.first.related_articles.sizeend    privatedef create_articles(number_of_iterations)  created = []  1.upto number_of_iterations do |n|    a = yield          a.keywords_to_tags    a.save!          created << a  end  createdend  def create_valid_article(*args)  options = Hash === args.last ? args.pop : {}      defaults = {:user_id => 1, :body => 'foo', :title => 'bar', :keywords => 'testing1', :published => true}  Article.new(defaults.merge(options))end

Ah, that’s a little more Ruby like, and definitely feels a lot more succinct. More importantly, it does so without becoming too complicated to understand and it raises the importance of what I’m creating into the test method. For me it’s equivalent to why I dislike putting JMock expectations anywhere other than inside the test—clarity!

What’s even more remarkable is I ended up there by trying to make it easier to re-use the code and create different types of articles in bulk for other tests I was writing. Almost by accident, and by taking small baby steps, I refactored to a drastically more communicative test.

I mention all this because I also just today read a brilliant, if somewhat flamebaiting, post about how Java’s slant had actually hurt it’s ability to communicate a model by shifting emphasis away from verbs into nouns, with many ‘verbs’ in the domain becoming wrapped by ‘noun’ classes:


The King [of the Kingdom of Java], consulting with the Sun God on the matter, has at times threatened to banish entirely all Verbs from the Kingdom of Java. If this should ever to come to pass, the inhabitants would surely need at least one Verb to do all the chores, and the King, who possesses a rather cruel sense of humor, has indicated that his choice would be most assuredly be “execute”.


The Verb “execute”, and its synonymous cousins “run”, “start”, “go”, “justDoIt”, “makeItSo”, and the like, can perform the work of any other Verb by replacing it with an appropriate Executioner and a call to execute(). Need to wait? Waiter.execute(). Brush your teeth? ToothBrusher(myTeeth).go(). Take out the garbage? TrashDisposalPlanExecutor.doIt(). No Verb is safe; all can be replaced by a Noun on the run.

It’s definitely an interesting point though. Whether Java’s emphasis on objects actually makes code less communicative. The writer made the point that features in other languages (such as closures in Ruby and function pointers in C) meant that it was easier to write code that was focused more on actions and (what he believes) is more communicative code.

What was even more interesting was that today I also just read fellow ThoughtWorker and team-mate, George Malamidis’ post about Closures for an upcoming release of Java.

He raises a very, very good point (and one I believe is more important than the one raised in the previous article) about there being more pressing issues at hand in Java (and probably ‘enterprise’/business software development in general), than worrying about adding things such as Closures:


I’d like to see focus shifted to the core characteristics of Java that made it such an interesting prospect at first, and these, in my opinion, boil down to good software design, powered by fundamental OO principles, not bells and whistles like Continuations, which, according to the Ruby FAQ, can be used to implement complex control structures, but are typically more useful as ways of confusing people.

And, although I agree there are bigger issues, I’m not so sure it’s one that conflicts with language features like the ones I mentioned earlier.

The more I think about things, the more I think of examples where I’ve been on teams that have diverged from attempting to deal with the business model at the heart of the software, and moreso with just being able to get stuff done. The result is (in my opinion) not a problem with verbs being replaced by nouns, but with using bad nouns, and putting them in bad places.

Through making compromises and not exploring the domain deeply and often enough (and collaborating with domain experts more) the code that represents the domain grows into one of those scary gardens that your ball would fall into and you’d play paper, rock, scissors with your friends to decide who had to knock on the door of the owner to ask for it back.

You end up in a situation where the ubiquitous language is still not ubiquitous and knowledge has not been sufficiently crunched for effective working (to borrow from Domain Driven Design’s glossary). Going forward, the code doesn’t help developers understand the domain, and people find themselves making further shortcut hacks to get some breathing space rather than having a potentially clearer path already visible.

I don’t think this problem is one uniquely squared at Java, but I am intrigued to see how different languages allow for different opportunities to solve the same problem in different ways and how that affects a developer’s ability to handle domain complexity effectively.

Going back to the code sample that prompted this post, it used a block to raise the importance of what we were creating into the test. If I were trying to do something functionally (and communicatively) equivalent in Java, I think I’d probably have ended up somewhere around here:




1234567891011121314151617181920212223242526
public void testShouldOnlyIncludeDistinctArticles() {  List articles = createArticles(8, validArticleFactory, articleSpecification);  Article firstArticle = articles.get(0);  assertEquals(7, firstArticle.relatedArticles.length);}private List createArticles(Integer count, ArticleFactory factory, ArticleSpecification spec) {  List articles = new ArrayList();  for (int i = 0; i < count; i++) {    articles.put(factory.createArticleFrom(spec));  }  return articles;}private static class ArticleWithTag1Specification implements ArticleSpecification {  ...  public String keywords = "tag1";}private static class ArticleWithTag2Specification implements ArticleSpecification {  ...  public String keywords = "tag2";}

We’ve created a fair few objects there. And although it is (arguably) just as intentful, it’s certainly more wordy. Going back to Steve Yegge’s post about the Nouns taking over in Javaland. Although this is arguably the case in the above, the naming of the nouns to an extent structure it to describe the domain.

It’s also important to consider that (by definition) giving an action a name is to describe it, that is, we describe a verb with a noun. So the two aren’t completely unrelated :)

But, although the above Java code is explicit with it’s intent and it does provide a domain language focused attempt at describing the problem, I still think the Ruby code is easier and clearer, and perhaps closer to how I (as an English speaking human) would attempt to describe an action.

The bigger question is not whether one language supports funky things like Closures or Blocks (which I do present a risk to over complicating code when developers get too far into the beautifying zone) but is one of how we use the language to address the problems of the domain. And, ultimately, I’d be happier working with code that did that in Java, than code that didn’t in Ruby. But don’t hate me for that :)

Anyway, I’m off to the wine bar to meet some of the team for dinner having received a little too many comments for being unsociable!