SlideShare une entreprise Scribd logo
1  sur  27
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 Scalastyle, the style checker for Scala
 Contributor to various open source projects, Junit
 Co-author of "sbt in Action" with Josh Suereth
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)
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);
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
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; }
}
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
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);
}
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);
}
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
}
}
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);
}
}
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
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
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
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...
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
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")
}
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"))
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());
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
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"
}
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)
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
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
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.
Me again
Matthew Farwell
Twitter: @matthewfarwell
Blog: http://randomallsorts.blogspot.ch/
Scalastyle: http://www.scalastyle.org
sbt in Action: http://manning.com/suereth2

Contenu connexe

Tendances

Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングscalaconfjp
 
Djangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 Minutes
Djangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 MinutesDjangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 Minutes
Djangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 MinutesNina Zakharenko
 
Mobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveMobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveepamspb
 
Web注入+http漏洞等描述
Web注入+http漏洞等描述Web注入+http漏洞等描述
Web注入+http漏洞等描述fangjiafu
 
Solid And Sustainable Development in Scala
Solid And Sustainable Development in ScalaSolid And Sustainable Development in Scala
Solid And Sustainable Development in ScalaKazuhiro Sera
 
Laravel Design Patterns
Laravel Design PatternsLaravel Design Patterns
Laravel Design PatternsBobby Bouwmann
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghStuart Roebuck
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentationipolevoy
 
Recipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with XtendRecipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with XtendKarsten Thoms
 
ActiveJDBC - ActiveRecord implementation in Java
ActiveJDBC - ActiveRecord implementation in JavaActiveJDBC - ActiveRecord implementation in Java
ActiveJDBC - ActiveRecord implementation in Javaipolevoy
 
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don GriffinSenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don GriffinSencha
 
Introduction to Protractor
Introduction to ProtractorIntroduction to Protractor
Introduction to ProtractorJie-Wei Wu
 
Modern, Scalable, Ambitious apps with Ember.js
Modern, Scalable, Ambitious apps with Ember.jsModern, Scalable, Ambitious apps with Ember.js
Modern, Scalable, Ambitious apps with Ember.jsMike North
 
Oleksandr Tolstykh
Oleksandr TolstykhOleksandr Tolstykh
Oleksandr TolstykhCodeFest
 

Tendances (20)

Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
 
Djangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 Minutes
Djangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 MinutesDjangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 Minutes
Djangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 Minutes
 
Scala active record
Scala active recordScala active record
Scala active record
 
Mobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveMobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast dive
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Presentation
PresentationPresentation
Presentation
 
PL/SQL Unit Testing Can Be Fun!
PL/SQL Unit Testing Can Be Fun!PL/SQL Unit Testing Can Be Fun!
PL/SQL Unit Testing Can Be Fun!
 
Web注入+http漏洞等描述
Web注入+http漏洞等描述Web注入+http漏洞等描述
Web注入+http漏洞等描述
 
Ant
AntAnt
Ant
 
Solid And Sustainable Development in Scala
Solid And Sustainable Development in ScalaSolid And Sustainable Development in Scala
Solid And Sustainable Development in Scala
 
Laravel Design Patterns
Laravel Design PatternsLaravel Design Patterns
Laravel Design Patterns
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentation
 
Recipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with XtendRecipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with Xtend
 
ActiveJDBC - ActiveRecord implementation in Java
ActiveJDBC - ActiveRecord implementation in JavaActiveJDBC - ActiveRecord implementation in Java
ActiveJDBC - ActiveRecord implementation in Java
 
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don GriffinSenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
 
KAAccessControl
KAAccessControlKAAccessControl
KAAccessControl
 
Introduction to Protractor
Introduction to ProtractorIntroduction to Protractor
Introduction to Protractor
 
Modern, Scalable, Ambitious apps with Ember.js
Modern, Scalable, Ambitious apps with Ember.jsModern, Scalable, Ambitious apps with Ember.js
Modern, Scalable, Ambitious apps with Ember.js
 
Oleksandr Tolstykh
Oleksandr TolstykhOleksandr Tolstykh
Oleksandr Tolstykh
 

En vedette

Haskell vs. F# vs. Scala
Haskell vs. F# vs. ScalaHaskell vs. F# vs. Scala
Haskell vs. F# vs. Scalapt114
 
What's Next in Growth? 2016
What's Next in Growth? 2016What's Next in Growth? 2016
What's Next in Growth? 2016Andrew Chen
 
The Six Highest Performing B2B Blog Post Formats
The Six Highest Performing B2B Blog Post FormatsThe Six Highest Performing B2B Blog Post Formats
The Six Highest Performing B2B Blog Post FormatsBarry Feldman
 
The Outcome Economy
The Outcome EconomyThe Outcome Economy
The Outcome EconomyHelge Tennø
 
Negotiation skills (2)
Negotiation skills (2)Negotiation skills (2)
Negotiation skills (2)Jayati Poddar
 

En vedette (6)

Scala XML
Scala XMLScala XML
Scala XML
 
Haskell vs. F# vs. Scala
Haskell vs. F# vs. ScalaHaskell vs. F# vs. Scala
Haskell vs. F# vs. Scala
 
What's Next in Growth? 2016
What's Next in Growth? 2016What's Next in Growth? 2016
What's Next in Growth? 2016
 
The Six Highest Performing B2B Blog Post Formats
The Six Highest Performing B2B Blog Post FormatsThe Six Highest Performing B2B Blog Post Formats
The Six Highest Performing B2B Blog Post Formats
 
The Outcome Economy
The Outcome EconomyThe Outcome Economy
The Outcome Economy
 
Negotiation skills (2)
Negotiation skills (2)Negotiation skills (2)
Negotiation skills (2)
 

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

pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
Scala - en bedre og mere effektiv Java?
Scala - en bedre og mere effektiv Java?Scala - en bedre og mere effektiv Java?
Scala - en bedre og mere effektiv Java?Jesper Kamstrup Linnet
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecLoïc Descotte
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?Tomasz Wrobel
 
여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala Language여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala LanguageAshal aka JOKER
 
A Brief Intro to Scala
A Brief Intro to ScalaA Brief Intro to Scala
A Brief Intro to ScalaTim Underwood
 
An Introduction to Scala (2014)
An Introduction to Scala (2014)An Introduction to Scala (2014)
An Introduction to Scala (2014)William Narmontas
 
Scala uma poderosa linguagem para a jvm
Scala   uma poderosa linguagem para a jvmScala   uma poderosa linguagem para a jvm
Scala uma poderosa linguagem para a jvmIsaias Barroso
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Jonas Bonér
 

Similaire à Softshake 2013: 10 reasons why java developers are jealous of Scala developers (20)

Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
Scala - en bedre og mere effektiv Java?
Scala - en bedre og mere effektiv Java?Scala - en bedre og mere effektiv Java?
Scala - en bedre og mere effektiv Java?
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
 
A bit about Scala
A bit about ScalaA bit about Scala
A bit about Scala
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
 
Scala - en bedre Java?
Scala - en bedre Java?Scala - en bedre Java?
Scala - en bedre Java?
 
Workshop Scala
Workshop ScalaWorkshop Scala
Workshop Scala
 
Scala
ScalaScala
Scala
 
여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala Language여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala Language
 
Scala in Places API
Scala in Places APIScala in Places API
Scala in Places API
 
A Brief Intro to Scala
A Brief Intro to ScalaA Brief Intro to Scala
A Brief Intro to Scala
 
An Introduction to Scala (2014)
An Introduction to Scala (2014)An Introduction to Scala (2014)
An Introduction to Scala (2014)
 
Scala uma poderosa linguagem para a jvm
Scala   uma poderosa linguagem para a jvmScala   uma poderosa linguagem para a jvm
Scala uma poderosa linguagem para a jvm
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 

Dernier

Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...itnewsafrica
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 

Dernier (20)

Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 

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

  • 1. 10 reasons why Java developers are jealous of Scala developers
  • 2.  Or 10 things which are not in Java but are in modern languages  Inspired by Graham Lea, thanks to him
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. Me again Matthew Farwell Twitter: @matthewfarwell Blog: http://randomallsorts.blogspot.ch/ Scalastyle: http://www.scalastyle.org sbt in Action: http://manning.com/suereth2