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
Matthew Farwell
 Senior developer @ Nexthink SA in Lausanne
 > 20 years development experience

 Project lead on Scalas...
Type inference
Java: verbose: type safe, static compilation
Verbose<Verbose> verbose = new Verbose<>()

Groovy – succinct,...
Less syntax - Java
final BigDecimal principle = new BigDecimal("100000");
final BigDecimal interestRate = new BigDecimal("...
Less syntax - Scala
val principle = new BigDecimal("100000")
// semi-colons optional, except where it's ambiguous
val inte...
Definition of classes - Java
public abstract class AbstractObject {
private Long id;
public AbstractObject(Long id) { this...
Definition of classes - Scala
abstract class AbstractObject(var id: Long)
class Customer(var id: Long, var first: String, ...
Closures – Java7
public interface FunctionInt {
int evaluate(int parameter);
}
private static List<Integer> doLoop(List<In...
Closures – Java8
public interface FunctionInt {
int evaluate(int parameter);
}
private static List<Integer> doLoop(List<In...
Closures - Scala
private def doLoop(inputs: Seq[Int], fn: (Int) => Int): Seq[Int] = {
val result = ListBuffer[Int]()
for (...
Collections – Java7
List<Integer> numbers = Arrays.asList(1, 2, 3);
// static imports make our lives easier
// but there a...
Collections - Scala
// simple things are simple
val numbers = List(1, 2, 3)
val moreNumbers = numbers ::: List(4, 5, 6) //...
Collections – Java 8 vs Scala
// Java 8
List<Integer> primes = Arrays.asList(1, 2, 3, 5, 7, 11, 13, 17);
List<Integer> pos...
Interoperability – Java / Scala
// we can call Java methods and classes without any problems
val list = List("1", "2", "4....
Implicit conversions
// we can 'add' methods to existing classes, but not really
class MyBigDecimal(value: BigDecimal) {
d...
DIY operators
// we can define methods with non-alphanumerique names, such as +
class BigDecimalWithOperators(val value: B...
Pattern matching
// like switch, but much more powerful
val interestRate = accountType match { // match returns a value
ca...
Pattern matching
// and even better
case class Name(names: List[String])
case class Languages(languages: List[String])
def...
Named parameters / default values
// JAVA
public class FunctionalException extends Exception {
// etc.
}
public class Func...
Named parameters / default values
// Scala
class FunctionalException(message: String,
cause: Throwable = null,
val errorCo...
Traits – multiple inheritance
// like interface, but we can define concrete methods, and inherit them
trait Foo { def foo(...
Simplified concurrency – one thread
List(1, 2, 3, 4).map(i => {
println("calculating " + i)
Thread.sleep(1000)
println("do...
Simplified concurrency – >1 thread
List(1, 2, 3, 4).par.map(i => {
println("calculating " + i)
Thread.sleep(1000)
println(...
And more…
For comprehensions
Lazy evaluation
Futures and promises
Currying
Value classes
String interpolation
Implicit cla...
Advantages / disadvantages
Advantages
The language is much less verbose than Java – we can express the same thing
in fewer...
Me again
Matthew Farwell
Twitter: @matthewfarwell
Blog: http://randomallsorts.blogspot.ch/
Scalastyle: http://www.scalasty...
Upcoming SlideShare
Loading in...5
×

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

1,420

Published on

10 reasons why java developers are jealous of Scala developers

java vs Scala comparison

Published in: Technology, Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,420
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
7
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

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

  1. 1. 10 reasons why Java developers are jealous of Scala developers
  2. 2.  Or 10 things which are not in Java but are in modern languages  Inspired by Graham Lea, thanks to him
  3. 3. 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
  4. 4. Type inference Java: 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)
  5. 5. 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);
  6. 6. 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
  7. 7. Definition of classes - Java public 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; } }
  8. 8. Definition of classes - Scala abstract 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
  9. 9. Closures – Java7 public 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); }
  10. 10. Closures – Java8 public 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); }
  11. 11. Closures - Scala private 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 } }
  12. 12. Collections – Java7 List<Integer> numbers = Arrays.asList(1, 2, 3); // static imports make our lives easier // but there are always things which aren't easy Map<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 them map(entry("one", 1), entry("two", 2), entry("three", 3)); // filter List<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); } }
  13. 13. Collections - Scala // simple things are simple val numbers = List(1, 2, 3) val moreNumbers = numbers ::: List(4, 5, 6) // concatenation val 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
  14. 14. 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()); // Scala val primes = List(1, 2, 3, 5, 7, 11, 13, 17) val possiblePrimes = primes.map(n => n * 2 - 1) // or val 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
  15. 15. Interoperability – Java / Scala // we can call Java methods and classes without any problems val 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
  16. 16. 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 = 1000000 val interestRate: BigDecimal = 0.065 val result = principle steal interestRate // but be careful...
  17. 17. 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 = 10 val interestEarned = (principle * ((ONE + interestRate) ^ depositTerm) principle).to$ println("interestEarned=" + interestEarned) // but again be careful ... // note that this is NOT operator overloading
  18. 18. 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") }
  19. 19. 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"))
  20. 20. 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());
  21. 21. Named parameters / default values // Scala class 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
  22. 22. 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 override class 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" }
  23. 23. Simplified concurrency – one thread List(1, 2, 3, 4).map(i => { println("calculating " + i) Thread.sleep(1000) println("done " + i) i * 2 }) calculating 1 done 1 calculating 2 done 2 calculating 3 done 3 calculating 4 done 4 res14: List[Int] = List(2, 4, 6, 8)
  24. 24. Simplified concurrency – >1 thread List(1, 2, 3, 4).par.map(i => { println("calculating " + i) Thread.sleep(1000) println("done " + i) i * 2 }) calculating 1 calculating 4 calculating 2 calculating 3 done 1 done 4 done 3 done 2 res14: List[Int] = List(2, 4, 6, 8) // and futures, promises, actors
  25. 25. And more… For comprehensions Lazy evaluation Futures and promises Currying Value classes String interpolation Implicit classes Actors / AKKA Options XML Literals Parser combinators Partial functions Higher kinded types Scala REPL / Scala IDE Worksheet
  26. 26. 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.
  27. 27. Me again Matthew Farwell Twitter: @matthewfarwell Blog: http://randomallsorts.blogspot.ch/ Scalastyle: http://www.scalastyle.org sbt in Action: http://manning.com/suereth2
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×