Feb 8, 2010

The Groovy Spaceship Operator Explained

While extending an existing Grails application bits of research around sorting lists using Groovy ensued. My first stop was Groovy In Action wherein the operator <=> was shown in a closure used for sorting, but with no explanation. Under Operators in the index, it became known that <=> is “The Spaceship Operator” – no doubt due to its similarity in look to a flying saucer. Sadly the referenced section of text also offered little in explaining what this bugger did exactly.

The spaceship operator has it’s roots in Perl and has found it’s way in to languages like Groovy and Ruby. The spaceship is a relational operator that performs like Java’s compareTo() comparing two objects and returning -1, 0, or +1 depending on the value of the left argument as compared to the right. If the left argument is greater than the right, the operator returns 1. If the left argument is less than the right, the operator returns −1. If the arguments are equal, 0 is returned. When using Groovy/Grails, if the arguments are not of comparable types, a ClassCastException is thrown.

While the spaceship could be used wherever you would use compareTo(), it seems most references to it are found in sorting. For example the following two lines would have identical results:

things.sort{ Thing a, Thing b -> b.beginDate <=> a.beginDate }

things.sort{ Thing a, Thing b -> b.beginDate.compareTo( a.beginDate ) }

Other examples of its behaviour from the Groovy Console:

groovy> def d = new Date()
groovy> println d <=> d
groovy> println 3 <=> 4
groovy> println “doberman” <=> “dachshund”
groovy> println d <=> new Date()

0
-1
1
-1

Perhaps the greatest advantage of using the Groovy comparison operators is the graceful handling of nulls such that x <=> y will never throw a NullPointerException:

groovy> println “dachshund” <=> null
groovy> println null <=> “dachshund”
groovy> println null <=> null

1
-1
0

In addition when comparing numbers of different types the type coercion rules apply to convert numbers to the largest numeric type before the comparison. So the following is valid in Groovy1:

groovy> Byte a = 27
groovy> Double b = 9
groovy> println a instanceof Byte
groovy> println b instanceof Double
groovy> println a > b

true
true
true

We come in peace – happy comparisons! For more on Groovy operator overloading look here.

1 “Groovy – Operator Overloading” Available at: http://groovy.codehaus.org/Operator+Overloading 26 January 2010

About the Author

Object Partners profile.

One thought on “The Groovy Spaceship Operator Explained

  1. Paras Jain says:

    Thanks. I was not even aware that we have such operator in Groovy. Will try in some places where we have sorting operations.

  2. F.Baube says:

    What’s old is new again. In FORTRAN this was called an “arithmetic IF”, look it up 🙂

  3. cease says:

    what resources do you use for groovy, like did you find this in a book anywhere ?

  4. Brad Karels says:

    I am fortunate that here at Object Partners Inc. we have very solid, core group of developers with a lot of depth in both Groovy and Grails – the whole ‘shoulders of giants’ thing. Beyond that, Groovy In Action, of course is one of my staple resources as well as the information available at http://groovy.codehaus.org/. Also, while Grails centric, http://www.grails.org/doc/latest/ has allowed me to piece together bits of functionality to create my desired outcome.

    Despite the wonderful nature of Groovy and Grails, one of the great frustrations is the holes in the books and online resources, a lot of which is just dead wrong. I find the best course is to ask a lot of questions when you have an expert available, ask thorough and well formed questions with source code in the forums, and find some good bloggers to follow. Some other resources that have helped me along the path are:

    * Follow @groovytweets on twitter
    * The Definitive Guide to Grails, Second Edition
    * Groovy in Action
    * http://groovy.codehaus.org
    * http://www.objectpartners.com/weblog/
    * http://www.grails.org/
    * …and countless hours on ‘the google’, transient blogs, and user groups.

  5. Axel Brinkop says:

    I just was stumpling across the following difference:
    assert ‘aaa’.compareTo(‘aaz’) == -25;
    assert (‘aaa’ ‘aaz’) == -1;

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Blog Posts
Feature Flags in Terraform
Feature flagging any code can be useful to developers but many don’t know how to or even that you can do it in Terraform. Some benefits of Feature Flagging your code You can enable different […]
Infrastructure as Code – The Wrong Way
You are probably familiar with the term “infrastructure as code”. It’s a great concept, and it’s gaining steam in the industry. Unfortunately, just as we had a lot to learn about how to write clean […]
Snowflake CI/CD using Jenkins and Schemachange
CI/CD and Management of Data Warehouses can be a serious challenge. In this blog you will learn how to setup CI/CD for Snowflake using Schemachange, Github, and Jenkins. For access to the code check out […]
How to get your pull requests approved more quickly
TL;DR The fewer reviews necessary, the quicker your PR gets approved. Code reviews serve an essential function on any software codebase. Done right, they help ensure correctness, reliability, and maintainability of code. On many teams, […]