SpringOne Americas

Private Events

Blogs

View all Blogs >>
  • Howard Lewis Ship

    Creator of Tapestry and HiveMind

    It took a lot of ferreting out, but I eventually learned that you can put a <version/> tag in your site.xml, and Maven will put the... more»

  • Brian Pontarelli

    Founder of Inversoft

    Just figured out how to get git tab completion working in zsh on a Mac. Turns out that the completion scripts use a bunch of extra git... more»

  • Stuart Halloway

    CEO of Relevance

    Steve Yegge's most recent post takes more»

  • Mike Levin

    Software Developer specializing in Web2.0 websites

    more»

  • Erik Doernenburg

    Principal Consultant @ Thoughtworks

    If you are somebody who writes code you probably know that moment when you look at some code you didn’t write, or some code you wrote a... more»

  • Kirk Knoernschild

    Software Developer & Mentor

    more»

  • Richard Monson-Haefel

    VP of Developer Relations, Curl Inc.

    more»

  • Alex Miller

    Sr. Engineer with Terracotta Inc.

    Start your engines kids - the JavaOne 2009 more»

  • Brian Goetz

    Author of Java Concurrency in Practice

    I live in an AT&T-free state, so I have not had access to the cult that is iPhone. But recently, in preparation for AT&T moving... more»

  • Matthew Bass

    Software Developer & Entrepreneur

    Can Sphinx and foxy fixtures place nicely together? Due to the way Sphinx indexing works, foxy fixtures will often slow down the indexing... more»

  • Jason Rudolph

    Author of Getting Started with Grails

    I had the more»

  • Ryan Shriver

    Business and Technology Consulting

    more»

  • Neal Ford

    Application Architect at ThoughtWorks, Inc.

    One of the techniques I more»

  • Michael Nygard

    Agile technology leader and dynamicist

    Patrick Muellr has an interesting post about being more»

  • Nathaniel Schutta

    Author, speaker, software engineer focused on user interface design.

    Today we learned something important, the NTSB announced the more»

  • Jeff Brown

    SpringSource Engineering And Professional Services - Groovy and Grails Developer

    Strange enough title.Let's start with a hypothetical conversation between a geeky developer and his much less geeky wife: more»

  • Ted Neward

    Enterprise, Virtual Machine and Language Wonk

    ... Corey Vidal, you have outdone every YouTube video I've ever seen, and I was a hug more»

  • Pratik Patel

    Enterprise Architect

    SpringSource today announced that it has purchased G2One, the folks who have been driving the development of Groovy and Grails. The following... more»

  • Graeme Rocher

    Project Lead of the Grails Project & CTO of G2One

    You may have already read about it in the various news outlets and blogs covering the announcement, but if you haven’t I’m excited to spread... more»

  • Andrew Glover

    Co-author of "Continuous Integration"

    more»

  • Matt Raible

    Creator of AppFuse and author of Spring Live

    This morning, my co-workers and I discovered that Link edIn decided to trim 10% of its employees. The Denver Offi more»

  • Jared Richardson

    Agile coach and co-author of Ship It

    Jurgen Appelo has an ongoing interview series on his blog. He's published a lot of very smart people and I'm honored to squeak in too! ;) more»

  • David Bock

    Principal Consultant, CodeSherpas Inc.

    I have been setting up a rock-solid server cluster for a client and ran into an interesting issue trying to install Phusion Passenger onto... more»

  • Pramod Sadalage

    Co-author of "Refactoring Databases:Evolutionary Database Development"

    Consider this Hibernate mapping @Column(name = "qReferenceId") public Long getQReferenceId() { return qReferenceId; more»

  • Craig Walls

    Author of Spring in Action

    At one time not too long ago, I wasn't a big fan of annotations. But then I let my guard down and even started liking them. But now I'm... more»

  • Scott Leberknight

    Chief Architect at Near Infinity

    In late 2006 Neal Ford wrote about Polyglot Programming and predicted more»

  • Kenneth Kousen

    President of Kousen IT, Inc.

    In this entry in my “Making Swing Groovy” series, I want to talk about threading issues. Specifically, more»

  • Venkat Subramaniam

    Founder of Agile Developer, Inc.

    I wrote a four part article for Java World on creating DSLs in Java and Groovy. For your convenience, I decided to list the links to those... more»

  • Jason Harwig

    Senior Software Engineer at Near Infinity

    The most popular entry I've written at Near Infinity has been the more»

  • John Heintz

    Principal Consultant with New Aspects of Software

    In a recent discussion interview questions came up, here's my favorite one.To set some context this question is designed to gauge the abst more»

  • Mark Johnson

    Director of Consulting at CGI

    At the Columbus NFJS show held on July 25-27th during one of the BOF sessions Dave Bock, Scott Davis and I discussed unit tests vs functional... more»

  • Joseph Nusairat

    Author of Beginning JBoss Seam & Co-Author of Beginning Groovy & Grails

    Well i am assuming Apress has the most random site in the world at times.But today only they have our recent book, Beginning Groovy & Grai more»

  • Keith Donald

    Lead of Spring Web and Creator of Spring Web Flow

    I am pleased to announce that Developing Rich Web Applications with Spring, a three-day bootcamp lead by SpringSource engineers on web... more»

  • Vladimir Vivien

    Software Engineer / Consultant

    Judging from the list of features that will be included in NetBeans 6.5, more»

  • Pete Behrens

    Organizational Agility Coach

    Marti nig & Associates Methods & Tools group recentl more»

  • Brian Sam-Bodden

    Java author, Ruby geek and Open Source Advocate

    In this installment we are going to build the Dashboard page of the Tempo application. T more»

  • Mark Fisher

    Spring Integration Lead

    In my recent post, I had mentio more»

  • Ron Bodkin

    Chief Software Architect, Quantcast

    I'm looking forward to speaking at The Rich Web Experience conference in San Jose next month. The event runs from September 7th through 9th.... more»

  • Mark Goodwin

    Web Application Security Specialist

    We've already looked at one of the two big problems posed by anti DNS pinning on Java applets; because there's rebinding on the applet and... more»

  • Scott Davis

    Author of "Groovy Recipes" & TDD Expert

    Every time I see a live show at the Denver Botanic more»

  • Romain Guy

    Java User Interface expert.

    more»

  • Ramnivas Laddad

    Author of AspectJ in Action, Principal at SpringSource

    InfoQ.com has published my AOP myths and realities talk recorded at a No Fluff Just Stuff conference. InfoQ.com founded by Floyd Marine more»

  • David Geary

    Author of Graphic Java and co-author of Core JSF

    The 2006 NFJS tour kicked off t more»

  • Kito Mann

    Editor-in-chief of JSF Central and the author of JSF in Action

    One of the enhancements added for JSF 1.2 was update of the MethodExpression signature for the action attribute of h:command{Link,Button}. In... more»

  • Jason Hunter

    Author of Java Servlet Programming

    I just posted the JDOM 1.1 release for download. This release includes about 20 improvements and bug fixes. more»

Java.next: Common Ground

Posted by: Stuart Halloway on 08/05/2008

This is Part One of a series of articles on Java.next. In Part One, I will explore the common ground shared by the Java.next languages.

I have chosen four languages which together represent "Java.next": Clojure, Groovy, JRuby, and Scala. At first glance, these languages are wildly different. Clojure is a Lisp. Groovy is the "almost Java" choice. JRuby has the beauty of Ruby, and the mindshare of Rails. Scala, unlike the others, brings the notion that we need more static typing.

As you might imagine, there is heated debate about which of these languages is best for some purpose, or best in general. Lost in the debate is the fact that these languages share a ton of common ground. They all evolved against a shared background, the Java language. Their design decisions are all influenced by what has worked well in Java, and what has failed.

In this article I will demonstrate two important points about the common ground these languages share:

  • Over the last decade of coding in object-oriented, VM-based languages, we have learned a lot about writing expressive, maintainable applications. Java.next incorporates this knowledge, enabling essence over ceremony.
  • The "essence vs. ceremony" design choices add up to a very different way of programming. The mental shift from Java to Java.next is a bigger shift than the previous shift from C/C++ to Java.

I have distilled the shared advantages of Java.next to eight points, which are explored in more detail below.

  • everything is an object
  • low-ceremony property definitions
  • expressive collections
  • functional programming
  • overriding operators
  • maintainable exception handling
  • adding methods to existing objects
  • roll-your-own constructs

Everything is an object

In Java, we live every day with the distinction between objects and primitives. This causes three practical problems:

  1. APIs must be duplicated: one method for objects, and another for primitives. Or worse, septlicated. One method for objects, and one each for different primitive types.
  2. The default (efficient, easy-to-use) numeric types have range limitations. Exceed them and your program breaks in mysterious ways.
  3. You cannot use intuitive math operators (+,-,etc.) with accurate numeric types.

In Java.next, everything is an object. You can invoke methods on all types using the same syntax.

; clojure
(. 1 floatValue)
1.0

// groovy
1.floatValue()
===> 1.0

# ruby
1.to_f
=> 1.0

// scala
1.floatValue
res1: Float = 1.0

Low-ceremony property definitions

In Java, to create a property, you must define a field, a getter, a setter, and (often) a constructor, all with appropriate protection modifiers. In Java.next, you can define all of these in a single step.

; clojure
(defstruct person :first-name :last-name)

// groovy
class Person {
    def firstName
    def lastName
}

# ruby
Person = Struct.new(:first_name, :last_name)

// scala
case class Person(firstName: String, lastName: String) {}

If you need to override (or omit) a getter, setter, or constructor for a class, you can also do that, without having to spell out all boilerplate versions of the other pieces.

And that's not all. All of these languages embrace TMTOWTDI (There's More Than One Way To Do It), so there are multiple variants on the approaches shown above.

Expressive collections

Java.next provides a convenient literal syntax for the most important collections: arrays and maps. In addition, you can string together multiple operations by passing function arguments, without having to write explicit iterators or loops. For example, to find the all the squares under 100 that are also odd:

; clojure
(filter (fn [x] (= 1 (rem x 2))) (map (fn [x] (* x x)) (range 10)))
(1 9 25 49 81)

// groovy
(1..10).collect{ it*it }.findAll { it%2 == 1}
===> [1, 9, 25, 49, 81]

# ruby
(1..10).collect{ |x| x*x }.select{ |x| x%2 == 1}
=> [1, 9, 25, 49, 81]

// scala
(1 to 10).map(x => x*x).filter(x => x%2 == 1)
res20: Seq.Projection[Int] = RangeMF(1, 9, 25, 49, 81)

There are similar conveniences for name/value collections, a.k.a. hashes or dictionaries.

Functional programming

The convenient collections described above are a special case of a more general idea: functional programming. Java.next supports functions as first class objects, allowing function arguments, functions that create new functions, and closures over the current scope. As a simple example, consider creating an adder function that adds some value chosen at runtime:

; clojure
(defn adder [x] (fn [y] (+ x y)))

// groovy
adder = { add -> { val -> val + add } } 

# ruby
def adder(add)
  lambda { |x| x + add }
end

// scala
def sum(a: Int)(b: Int) = a + b

Overriding operators

In Java, you cannot override operators. Math looks like this, for types like BigDecimal:

// Java math
balance.add(balance.multiply(interest));

Java.next allows you to override operators. This allows you to do create new types that feel like built-in types, e.g. you could write a ComplexNumber or RationalNumber that supports +, -, *, and /.

; Clojure
(+ balance (* balance interest))

// Groovy
balance + (balance * interest)

# JRuby
balance + (balance * interest)

// Scala (See [1])
balance + (balance * interest)

Maintainable exception handling

Checked exceptions are a failed experiment. Java code is bloated with checked exception handling code that tends to obscure intent without improving error handling. Worse yet, checked exceptions are a maintenance headache at abstraction boundaries. (New kinds of unrecoverable failures down the dependency chain should not necessitate recompilation!)

Java.next does not require you to declare checked exceptions, or to explicitly deal with checked exceptions from other code. It is a testimony to the power of Java (the platform) that other languages are free to ignore the ugliness of checked exceptions in Java (the language).

Adding methods to existing types

In Java, you cannot add methods to existing types. This leads to absurd object-mismodeling, as developers create utility classes that defy the point of OO:

// Java (from the Jakarta Commons)
public class StringUtils { 
  public static boolean isBlank(String str) { 
    int strLen; 
    if (str == null || (strLen = str.length()) == 0) { 
      return true; 
    }  
    for (int i = 0; i < strLen; i++) { 
    if ((Character.isWhitespace(str.charAt(i)) == false)) { 
      return false; 
    } 
  }
}

In Java.next, you can add methods to existing types:

; Clojure
(defn blank? [x] 
  (cond (string? x) (= (.length x) 0)
    (nil? x) true
    (throw (new Exception "time to support some new types"))))

// Groovy
String.metaClass.isBlank = {
  length() == 0 || every { Character.isWhitespace(it.charAt(0)) }
}

# Ruby (from Rails)
class String 
  def blank? 
    empty? || strip.empty? 
  end 
end 

// Scala
class CharWrapper(ch: Char) {
  def isWhitespace = Character.isWhitespace(ch)
}
implicit def charWrapper(ch: Character) = new CharWrapper(ch)
class BlankWrapper(s: String) {
  def isBlank = s.isEmpty || s.forall(ch => ch.isWhitespace)
}
implicit def stringWrapper(s: String) = new BlankWrapper(s)

Roll-your-own constructs

In Java, you have the language and the libraries. The two are clearly distinct: you can write new libraries, but you cannot add language features.

In Java.next, the line between language and libraries is blurry. You can create new constructs that work like core language features. For example, Clojure provides an and function.

; clojure
(and 1 2) => 2

But maybe your problem domain isn't so binary. You need a most function, that returns true if most of its arguments evaluate to true. Clojure doesn't have this, but you can write one:

; clojure
(most 1 2) => true
(most 1 2 nil) => true
(most 1 nil nil) => false

The point here is not "Does my language need a 'most' conditional?" Probably not. The point is that different domains have different needs. In Java.next, the boundary between the language and the libraries is a minimized. You can adapt the language to your domain, instead of the other way around.

As another example, consider Ruby's attribute syntax:

# Ruby
class Account
  attr_accessor :name
  dsl_attribute :type
end

attr_accessor is built into the language. dsl_attribute is a library method that I wrote, which allows you to omit the "=" when assigning values, e.g.

# normal attributes
account.name = "foo"

# equals-free attributes
account.type checking

Conclusions

The Java.next languages share a ton of common ground. Although I've used small isolated examples for explanation, the real power comes from using these features together. Combining all the Java.next features leads to an entirely different style of coding.

  • You do not have to code defensively, using a slew of factories, patterns, and dependency injection to keep your code testable and adaptable. Instead, you can build a minimal solution and evolve it.
  • Instead of coding in your Java.next language, you can develop internal Domain-Specific Languages (DSLs) that better match your problem domain.

In my experience, this style of coding tends to reduce the size of a codebase by an order of magnitude, while improving readability.

Many people are looking for the "next big language." The next big language is already here, but it isn't a single language. It is the collection of ideas above (plus probably some I missed) as manifested in Java.next.

Does the transition to Java.next deserve the name "big"? Absolutely. In my experience, the move from Java to Java.next is every bit as big as the previous tectonic shifts in the industry, both in learning curve and in productivity advantages once you make the transition.

As an industry, we need to reset the bar to include Java.next. Once we have, we can have a conversation about the differences in these languages. I will take up the unique aspects of the Java.next languages in future installments of this series.

Notes

  • This article is taken from the first half of the JVM Language Shootout talk that I wrote for NFJS. Check the schedule for a talk near you.
  • Suggestions for improving the code samples above are most welcome.
  • Thanks to Justin Gehtland, Jason Rudolph, Rob Sanheim, Glenn Vanderburg, and Greg Vaughn for reading an earlier draft of this article.

Footnotes

  1. The BigDecimal example does not work as I would expect on the Scala build I have (2.7.1.final). But the important point is that I could make it work by adding an implicit conversion. I am not dependent on the language designers, I can improve the language myself.

Revisions

  • 2008/08/04: fixed errata, better Clojure example for expressive collections.

  • Currently 5.0/5
  • 1
  • 2
  • 3
  • 4
  • 5
5.0 rating out of 2 votes


About Stuart Halloway

Stuart Halloway is the CEO of Relevance, Inc. (www.thinkrelevance.com). With co-founder Justin Gehtland, Stuart helps enterprises adopt emerging best practices such as Ruby on Rails. Justin and Stuart founded the Streamlined Framework (www.streamlinedframework.org), and authored Rails for Java Developers. Stuart is also the author of Component Development for the Java Platform. Prior to founding Relevance, Stuart was the Chief Architect at Near-Time, and the Chief Technical Officer at DevelopMentor.