Scala code is less redundant than Java code

For example, consider the following Java class (written in the Java language in the first version below) which duplicates the name of the class three times (i.e. duplicates it two extra times in the two constructors, except from the class declaration), and for example declares the int type five times for the field age:

class PersonImplementedWithJava implements Person {
    private int age;
    private String name;
    private String countryOfBirth;

    public PersonImplementedWithJava(String name, int age, String countryOfBirth) {
        this.age = age;
        this.name = name;
        this.countryOfBirth = countryOfBirth;
    }

    /**
     * Constructor using sweden as default country
     */
    public PersonImplementedWithJava(String name, int age) {
        this(name, age, "SWEDEN");
    }


    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCountryOfBirth() {
        return countryOfBirth;
    }

    public void setCountryOfBirth(String countryOfBirth) {
        this.countryOfBirth = countryOfBirth;
    }
}

The above class implements the following Java interface, i.e. setter and getter methods for three fields:

public interface Person {
    int getAge();
    void setAge(int age);
    String getName();
    void setName(String name);
    String getCountryOfBirth();
    void setCountryOfBirth(String countryOfBirth);    
}

Below is a Scala implementation of the same interface. Your first reaction, when looking at the small class below may be that it can not implement the above interface, since there are no get/set methods defined, but indeed they will become available, thanks to the @BeanProperty annotation.

You will be able to see the getters/setters in the client test code further down, which can uses either implementation from a polymorhpic method (i.e. a method receiving an instance of the Person interface which is either implemented with Java or Scala) to verify the same behaviour (and the existance of the getter/setter methods which would cause compiling problems if they would not exist) for the two implementations (one Java and one Scala) of the Person interface.

import reflect.BeanProperty
class PersonImplementedWithScala(
  @BeanProperty var name: String,
  @BeanProperty var age: Int,
  @BeanProperty var countryOfBirth: String
)
  extends Person // Scala does not use the Java keyword "implements" 
{
    /**
     * Constructor using sweden as default country
     */
    def this(name: String, age: Int) = this(name, age, "SWEDEN")
}

As you can see above, the Scala implementation was much shorter, even for such a small class with only three fields.

The below test class proves that the above Scala class indeed works in the same way as the Java implementation of the Java class:

import static junit.framework.TestCase.assertEquals;
import org.junit.Test;
public class PersonTest {
    @Test
    public void testingGettersAndSetters() {
        // the main constructors, using all three fields:
        verifyGettersAndSetters(new PersonImplementedWithJava("Tomas", 37, "SWEDEN"));
        verifyGettersAndSetters(new PersonImplementedWithScala("Tomas", 37, "SWEDEN"));

        // the other constructors, using a default value for the country field (SWEDEN)
        verifyGettersAndSetters(new PersonImplementedWithJava("Tomas", 37));
        verifyGettersAndSetters(new PersonImplementedWithScala("Tomas", 37));
    }

    /**
     * This method contains trivial code, but verifies that the Scala class indeed will have get/set-methods
     * available (through the @BeanProperty annotations) as declared in the Java interface it implements.
     * If it would not have those getters and setters, the code would not even compile, but this test
     * also verifies the same behaviour , i.e. that the values that was sent to the constructor and
     * that was set with setter methods can be retrieved back with the getters.
     */
    private void verifyGettersAndSetters(final Person person) {
        // The person instance might be implemented with either Java or Scala

        // first verify the constructor (e.g. that one of the constructors above provided SWEDEN as default) 
        assertEquals("Tomas", person.getName());
        assertEquals(37, person.getAge());
        assertEquals("SWEDEN", person.getCountryOfBirth());

        // then use the setters and verify with the getters
        person.setName("Tom");
        person.setAge(38);
        person.setCountryOfBirth("USA");
        assertEquals("Tom", person.getName());
        assertEquals(38, person.getAge());
        assertEquals("USA", person.getCountryOfBirth());
    }
}

Finally, regarding the topic of this page, i.e. that Scala code is less redundant than Java code, the type inference should also be mentioned.

In Scala code, the "variables" is declared with the keywords "var" or "val" but that does not mean that it uses dynamic typing, but Scala is indeed statically typed, i.e. you can get help from the compiler when you are trying to use types in an incorrect way.

However, Scala uses type inference, i.e. does not require duplicated type specification as in Java code, as the example below illustrates.

As in the last declaration example below, you can see that it is indeed possible to define type, when you really want to, but it is not always enforced as in Java.

The usage of "val" corresponds to Java's "final", and when "var" is used instead of "val", it corresponds to declaring a Java variable without specifying it as final.

    // Java method with type duplication:
    private void methodIllustratingVariableDeclarations() {
        final StringBuffer stringBuffer = new StringBuffer();
        final File file = new File("someFile.txt");
        final HashMap<String, List<Integer>> hashMap = new HashMap<String, List<Integer>>();
	final Map<String, List<Integer>> map = new HashMap<String, List<Integer>>();

    }

	
    // Similar Scala method without type duplication, using type inference:
    private def methodIllustratingVariableDeclarations: Unit = {
      val stringBuffer = new StringBuffer
      val file = new File("someFile.txt")
      val hashMap  = new HashMap[String, List[Integer]]
      // the above "variable" got the same type as the concrete instance,
      // but if we really want to specify the type (e.g. a basetype)
      // we can indeed do that as below:
      val map: Map[String, List[Integer]] = new HashMap[String, List[Integer]]
      // ...
    }





/ Tomas Johansson, Stockholm, Sweden, 2010-01-23