I have been attempting to introduce some low-ceremony programming tools and languages to my programming team at my job and thanks to a series of brown-bags and internal discussions have sold Scala for use in an upcoming project. It wasn’t functional programming, type-inference, case classes, or even the Actor Model that was the biggest win but instead embeddable XML and the fact that Twitter uses it… hey, whatever works right?

I have looked into Scala for a few months and on occasion attempted to put together a nice example of how it compares to Java. However, it turns out that Jim Weirich from Compuware presented a nice example for Groovy that I decided to steal and mangle to work for Scala (standing on the shoulders of giants and all that). The results are below, but bear in mind that it works much better as a presentation. Nonetheless…

Caveat emptor: I am still learning Scala, so I have yet to absorb its idioms, terminology, and nuances

Original Java Class


import java.util.*;

class Clutter {
    public static void main( String[] args) {
        List names = new ArrayList();
        names.add( "Mike");
        names.add( "Marvin");
        names.add( "Bhagat");
        names.add( "Horacio");

        System.out.println( names);

        Clutter e = new Clutter();
        List short_names = e.filterLongerThan( names, 4);

        System.out.println( short_names.size());

        for( String s : short_names) {
            System.out.println( s);
        }
    }
    
    public List filterLongerThan( List strings, int length) {
        List result = new ArrayList();

        for( String s : strings ) {
            if( s.length() < length+1) {
                result.add( s);
            }
        }

        return result;
    }
}

There are no semi-colons and the package wildcard is different in Scala



import java.util._

class Clutter {
    public static void main( String[] args) {
        List names = new ArrayList()
        names.add( "Mike")
        names.add( "Marvin")
        names.add( "Bhagat")
        names.add( "Horacio")

        System.out.println( names);

        Clutter e = new Clutter()
        List short_names = e.filterLongerThan( names, 4)

        System.out.println( short_names.size())

        for( String s : short_names) {
            System.out.println( s)
        }
    }
    
    public List filterLongerThan( List strings, int length) {
        List result = new ArrayList()

        for( String s : strings ) {
            if( s.length() < length+1) {
                result.add( s)
            }
        }

        return result
    }
}

Iterating over a list is elegant

import java.util._

class Clutter {
    public static void main( String[] args) {
        List names = new ArrayList()
        names.add( "Mike")
        names.add( "Marvin")
        names.add( "Bhagat")
        names.add( "Horacio")

        System.out.println( names);

        Clutter e = new Clutter()
        List short_names = e.filterLongerThan( names, 4)

        System.out.println( short_names.size())

        short_name.foreach( s => System.out.println( s) )
    }
    
    public List filterLongerThan( List strings, int length) {
        List result = new ArrayList()

        strings.foreach { s =>
            if( s.length() < length+1) {
                result.add( s)
            }
        }

        return result
    }
}

Let type-inference take care of most of those type annotations, plus Scala doesn’t need the new keyword

 
import java.util._

class Clutter {
    public static void main( args:Array[String]) {
        val names = List()  
        names.add( "Mike")
        names.add( "Marvin")
        names.add( "Bhagat")
        names.add( "Horacio")

        System.out.println( names);

        val e = Clutter() 
        var List short_names = e.filterLongerThan( names, 4)

        System.out.println( short_names.size())

        short_name.foreach( s => System.out.println( s) ) 
    }
    
    public List filterLongerThan( List strings, int length) {
        List result = ArrayList()

        strings.foreach { s =>       
            if( s.length() < length+1) {
                result.add( s)
            }
        }

        return result
    }
}

It should not be this difficult to create a list of strings

 
import java.util._

class Clutter {
    public static void main( args:Array[String]) {
        val names = List("Mike", "Marvin", "Bhagat", "Horacio")

        System.out.println( names);

        val e = Clutter()                                      
        var List short_names = e.filterLongerThan( names, 4)   

        System.out.println( short_names.size())

        short_name.foreach( s => System.out.println( s) )      
    }
    
    public List filterLongerThan( List strings, int length) {
        List result = new ArrayList()

        strings.foreach { s =>                                 
            if( s.length() < length+1) {
                result.add( s)
            }
        }

        return result
    }
}

Filtering can be handled using a for-comprehension

 
import java.util._

class Clutter {
    public static void main( args:Array[String]) {
        val names = List("Mike", "Marvin", "Bhagat", "Horacio") 

        System.out.println( names);

        val e = Clutter()                                       
        var List short_names = e.filterLongerThan( names, 4)    

        System.out.println( short_names.size())

        short_name.foreach( s => System.out.println( s) )       
    }
    
    public List filterLongerThan( List strings, int length) {
        for( n <- strings if( n.length <= length)) yield n     
    }
}

The filtering can occur locally and does not need to be part of a class

 
import java.util._

class Clutter {
    public static void main( args:Array[String]) {
        val names = List("Mike", "Marvin", "Bhagat", "Horacio")

        System.out.println( names);

        var List short_names = for( n <- names if( n.length <= 4)) yield n

        System.out.println( short_names.size())

        short_name.foreach( s => System.out.println( s) )      
    }
}

Why not make our class a singleton?

object Clutter {                                             
    public static void main( args:Array[String]) {
        val names = List("Mike", "Marvin", "Bhagat", "Horacio")

        System.out.println( names);

        List short_names = for( n <- names if( n.length <= 4)) yield n

        System.out.println( short_names.size())

        short_name.foreach( s => System.out.println( s) )      
    }
}

There are no statics in Scala

 
object Clutter {                                               
    def main( args:Array[String]) {                            
        val names = List("Mike", "Marvin", "Bhagat", "Horacio")

        System.out.println( names);

        List short_names = for( n <- names if( n.length <= 4)) yield n

        System.out.println( short_names.size())

        short_name.foreach( s => System.out.println( s) )      
    }
}

We really do not need a main at all, instead make our filter a library function

object Cleaner {
def filterLongerThan( names:List[String], len:int) = {
for( n <- names if( n.length <= len)) yield n } }

val names = List(“Mike”, “Marvin”, “Bhagat”, “Horacio”)