+ All Categories
Home > Technology > Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Date post: 06-May-2015
Category:
Upload: matthew-farwell
View: 1,334 times
Download: 0 times
Share this document with a friend
Description:
10 reasons why java developers are jealous of Scala developers java vs Scala comparison
27
10 reasons why Java developers are jealous of Scala developers
Transcript
Page 1: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

10 reasons why Java developers are jealous of Scala developers

Page 2: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Or 10 things which are not in Java but are in modern languages

Inspired by Graham Lea, thanks to him

Page 3: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Matthew Farwell

Senior developer @ Nexthink SA in Lausanne

> 20 years development experience

Project lead on Scalastyle, the style checker for Scala

Contributor to various open source projects, Junit

Co-author of "sbt in Action" with Josh Suereth

Page 4: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Type inferenceJava: verbose: type safe, static compilation

Verbose<Verbose> verbose = new Verbose<>()

Groovy – succinct, we find errors "in production"

def dynamic = 1

Scala – succinct, type safe, static compilation

val intValue = 1

val list = List("foo", "bar", "baz")

No compromise (well, compilation is slower)

Page 5: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Less syntax - Java

final BigDecimal principle = new BigDecimal("100000");

final BigDecimal interestRate = new BigDecimal("0.065");

final int depositTerm = 10;

final BigDecimal interestEarned = principle.multiply(interestRate.add(ONE).pow(depositTerm)).subtract(principle).setScale(2, ROUND_HALF_UP);

Page 6: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Less syntax - Scala

val principle = new BigDecimal("100000")

// semi-colons optional, except where it's ambiguous

val interestRate = new BigDecimal("0.065")

// val == final, should be default choice

val interestEarned = principle multiply

(( ONE add interestRate)

pow depositTerm) subtract

principle setScale(2, ROUND_HALF_UP)// . optional

// parens optional for methods with zero or 1 params

// If we combine the two, methods look like operators

Page 7: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Definition of classes - Javapublic abstract class AbstractObject { private Long id; public AbstractObject(Long id) { this.id = id; } public Long getId() { return id; } public void setId(Long id) { this.id = id; }}

public class Customer extends AbstractObject { private String first; private String last;

public Customer(Long id, String first, String last) { super(id); this.first = first; this.last = last; } public String getFirst() { return first; } public void setFirst(String first) { this.first = first; } public String getLast() { return last; } public void setLast(String last) { this.last = last; }}

Page 8: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Definition of classes - Scalaabstract class AbstractObject(var id: Long)

class Customer(var id: Long, var first: String, var last: String) extends AbstractObject(id)

// Yes, these classes do the same thing// déclarations include constructor// properties are var/val, name and type,// accessors are generated automatically

// even better

case class Person(first: String, last: String)

Person("Boba", "Fett")Person("John", "Doe").equals(Person("John", "Doe"))Person("John", "Doe").copy(first = "Freddy")

// and pattern matching for free

Page 9: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Closures – Java7public interface FunctionInt { int evaluate(int parameter);}

private static List<Integer> doLoop(List<Integer> inputs, FunctionInt f) { ArrayList<Integer> result = new ArrayList<>(inputs.size()); for (int input : inputs) { result.add(f.evaluate(input)); }

return result;}

public static void main(String[] args) { List<Integer> primes = Arrays.asList(1, 2, 3, 5, 7, 11, 13, 17); List<Integer> possiblePrimes = doLoop(primes, new FunctionInt() { public int evaluate(int n) { return n * 2 - 1; } }); System.out.println("possiblePrimes=" + possiblePrimes);}

Page 10: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Closures – Java8public interface FunctionInt { int evaluate(int parameter);}

private static List<Integer> doLoop(List<Integer> inputs, FunctionInt f) { ArrayList<Integer> result = new ArrayList<>(inputs.size()); for (int input : inputs) { result.add(f.evaluate(input)); }

return result;}

public static void main(String[] args) { List<Integer> primes = Arrays.asList(1, 2, 3, 5, 7, 11, 13, 17); List<Integer> possiblePrimes = doLoop(primes, (n -> n * 2 - 1 )); System.out.println("possiblePrimes=" + possiblePrimes);}

Page 11: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Closures - Scalaprivate def doLoop(inputs: Seq[Int], fn: (Int) => Int): Seq[Int] = { val result = ListBuffer[Int]() for (input <- inputs) { result += fn(input) // not the best, use map instead } result}

def main(args: Array[String]) { val primes = List(1, 2, 3, 5, 7, 11, 13, 17, 19, 23)

val possiblePrimes = doLoop(primes, {n => n * 2 - 1})

println("possiblePrimes=" + possiblePrimes)}

// (Int) => Int is how we declare a function// { n => n * 2 - 1 } is effectively:new Function1[Int, Int] { def apply(n: Int): Int = { n * 2 - 1 }}

Page 12: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Collections – Java7List<Integer> numbers = Arrays.asList(1, 2, 3);// static imports make our lives easier

// but there are always things which aren't easyMap<String, Integer> map = new HashMap<>();map.put("one", 1);map.put("two", 2);map.put("three", 3);

// We can add our own methods, but we need to write themmap(entry("one", 1), entry("two", 2), entry("three", 3));

// filterList<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);ArrayList<Integer> oddNumbers = new ArrayList<>(inputs.size());for (int input : list) { if (input % 2 != 0) { oddNumbers.add(input); }}

Page 13: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Collections - Scala// simple things are simple

val numbers = List(1, 2, 3)val moreNumbers = numbers ::: List(4, 5, 6) // concatenationval map = Map("one" -> 1, "two" -> 2, "three" -> 3)

// filter

val numbers = List(1, 2, 3, 4, 5, 6)val oddNumbers = numbers.filter(_ % 2 != 0)

// map (transform a list of X into a list of Y)

val numbers = List(1, 2, 3, 4, 5, 6)def oddOrEven(i: Int) = n + " is " + (if (n % 2 != 0) "odd" else "even")val statements = numbers.map(oddOrEven)

// N.B. statements = List[String]

// sum

val numbers = List(1, 2, 3, 4, 5, 6)val sum = numbers.sum

Page 14: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Collections – Java 8 vs Scala// Java 8

List<Integer> primes = Arrays.asList(1, 2, 3, 5, 7, 11, 13, 17);List<Integer> possiblePrimes = primes.stream() .map(n -> n * 2 - 1) .collect(Collectors.toList());// Scalaval primes = List(1, 2, 3, 5, 7, 11, 13, 17)val possiblePrimes = primes.map(n => n * 2 - 1)

// orval possiblePrimes = primes.map(_ * 2 – 1)

// possiblePrimes is a List[Int]

// can't do the following in Java:

val primes = Array(1, 2, 3, 5, 7, 11, 13, 17)val possiblePrimes = primes.map(n => n * 2 – 1)

// possiblePrimes is an Array[Int]// same performance as Java

Page 15: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Interoperability – Java / Scala

// we can call Java methods and classes without any problemsval list = List("1", "2", "4.5").

map(s => new java.math.BigDecimal(s)).map(bd => bd.add(ONE))

// to call Scala from Java, sometimes gets hard because of closures,// but most of the time, it's OK

Page 16: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Implicit conversions

// we can 'add' methods to existing classes, but not really

class MyBigDecimal(value: BigDecimal) { def steal(bd: BigDecimal): BigDecimal = value + (bd * 0.9)}implicit def bigDecimal2MyBigDecimal(value: BigDecimal): MyBigDecimal = new MyBigDecimal (value)

val principle: BigDecimal = 1000000val interestRate: BigDecimal = 0.065val result = principle steal interestRate

// but be careful...

Page 17: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

DIY operators

// we can define methods with non-alphanumerique names, such as +

class BigDecimalWithOperators(val value: BigDecimal) { def + (bd: BigDecimal): BigDecimal = value add bd def - (bd: BigDecimal): BigDecimal = value subtract bd def * (bd: BigDecimal): BigDecimal = value multiply bd def ^ (bd: Int): BigDecimal = value pow bd def to$: BigDecimal = value setScale(2, HALF_UP)}implicit def bigDecimal2BigDecimalWithOperators(value: BigDecimal): BigDecimalWithOperators = new BigDecimalWithOperators(value)

val principle = new BigDecimal("1000000")val interestRate = new BigDecimal("0.065")val depositTerm = 10val interestEarned = (principle * ((ONE + interestRate) ^ depositTerm) - principle).to$

println("interestEarned=" + interestEarned)

// but again be careful ...// note that this is NOT operator overloading

Page 18: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Pattern matching

// like switch, but much more powerful

val interestRate = accountType match { // match returns a value case Poor => new BigDecimal("0.0001") case Average => new BigDecimal("0.001") case Rich => new BigDecimal("0.01") case _ => throw new IllegalArgumentException("Unknown account type")}

Page 19: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Pattern matching

// and even better

case class Name(names: List[String])case class Languages(languages: List[String])

def interpret(strings: List[String]): Any = { strings match { case Nil => null case "Name:" :: tail => Name(tail) case "Languages:" :: tail => Languages(tail) case List("Hello:", x, y) => List(x, y) case label :: _ => throw new Exception("Unknown label: " + label) }}

interpret(List("Name:", "Matthew", "Farwell"))interpret(List("Hello:", "All", "There"))interpret(List("Hello:", "Too", "Many", "Items"))interpret(List("Languages:", "Java", "Scala", "Javascript", "Groovy"))interpret(List())interpret(List("Unknown:", "Hello"))

Page 20: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Named parameters / default values

// JAVA

public class FunctionalException extends Exception { // etc.}

public class FunctionalExceptionBuilder { public FunctionalExceptionBuilder(String message) {...} public FunctionalExceptionBuilder setCause(Exception cause) {...} public FunctionalExceptionBuilder setErrorCode(String errorCode) {...} public FunctionalException build() { return new FunctionalException(message, cause, errorCode); }}

// we use like:

new FunctionalExceptionBuilder("message").setErrorCode("001").build());

Page 21: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Named parameters / default values

// Scalaclass FunctionalException(message: String,

cause: Throwable = null,val errorCode: String = null) extends Exception(message, cause)

// we use like:

new FunctionalException("hello", new Exception(), "001")new FunctionalException("hello", cause = new Exception())new FunctionalException("hello", errorCode = "001")

// downside – names are part of the API now

Page 22: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Traits – multiple inheritance

// like interface, but we can define concrete methods, and inherit them

trait Foo { def foo() = "foo" }trait Bar { def bar() = "bar" }class Baz extends Foo with Bar {}

new Baz().foo // "foo"new Baz().bar // "bar"

// and overrideclass Baz extends Foo with Bar { override def bar() = "not bar“}

new Baz().bar // "not bar"

// can also have values / state

trait Foo { var foo = 1 def foo() = "foo"}

Page 23: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Simplified concurrency – one thread

List(1, 2, 3, 4).map(i => { println("calculating " + i) Thread.sleep(1000) println("done " + i) i * 2})calculating 1done 1calculating 2done 2calculating 3done 3calculating 4done 4res14: List[Int] = List(2, 4, 6, 8)

Page 24: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Simplified concurrency – >1 thread

List(1, 2, 3, 4).par.map(i => { println("calculating " + i) Thread.sleep(1000) println("done " + i) i * 2})calculating 1calculating 4calculating 2calculating 3done 1done 4done 3done 2res14: List[Int] = List(2, 4, 6, 8)

// and futures, promises, actors

Page 25: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

And more…

For comprehensionsLazy evaluationFutures and promisesCurryingValue classesString interpolationImplicit classesActors / AKKAOptionsXML LiteralsParser combinatorsPartial functionsHigher kinded types

Scala REPL / Scala IDE Worksheet

Page 26: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Advantages / disadvantages

Advantages

The language is much less verbose than Java – we can express the same thing in fewer lines of code.

We don't need to do everything at once - we can mix Java and Scala.

Disadvantages

The tools aren't the same level as for Java, for example Eclipse, Maven, but they are totally usable.

The major releases are not binary compatible – so when we change from 2.9 to 2.10, we need to recompile.

Sometimes we need to 'bridge' between object orientation and the functional world – the people don't always speak the same language

The documentation is sometimes difficult to read.

Page 27: Softshake 2013: 10 reasons why java developers are jealous of Scala developers

Me again

Matthew Farwell

Twitter: @matthewfarwell

Blog: http://randomallsorts.blogspot.ch/

Scalastyle: http://www.scalastyle.org

sbt in Action: http://manning.com/suereth2


Recommended