PROGRAMMING IN PAIN
ENNO RUNNE
Wednesday, February 16, 2011
WHAT MAKES ME FEEL PAIN
Coding Scala made me value new things.
I reconsidered old Java truths about what is good code, and I
try to take some of Scala’s goodness home to Java – at the
price of more noise.
Some concepts can’t be translated easily.
Wednesday, February 16, 2011
MANY METHOD ARGUMENTS
Wednesday, February 16, 2011
MANY METHOD ARGUMENTS
new Person("Enno", "Runne") Java
new Person("Enno", "Runne", "Sweden")
new Person("Enno", "Runne", "Sweden", "Stockholm")
Wednesday, February 16, 2011
MANY METHOD ARGUMENTS
new Person("Enno", "Runne") Java
new Person("Enno", "Runne", "Sweden")
new Person("Enno", "Runne", "Sweden", "Stockholm")
new Person("Enno", "Runne", null, "Stockholm")
Wednesday, February 16, 2011
MANY METHOD ARGUMENTS
new Person("Enno", "Runne") Java
new Person("Enno", "Runne", "Sweden")
new Person("Enno", "Runne", "Sweden", "Stockholm")
new Person("Enno", "Runne", null, "Stockholm")
p = new Person("Enno", "Runne", city = "Stockholm") Scala
Wednesday, February 16, 2011
MANY METHOD ARGUMENTS
new Person("Enno", "Runne") Java
new Person("Enno", "Runne", "Sweden")
new Person("Enno", "Runne", "Sweden", "Stockholm")
new Person("Enno", "Runne", null, "Stockholm")
p = new Person("Enno", "Runne", city = "Stockholm") Scala
p = new Builder("Enno", "Runne").city("Stockholm").build();
Wednesday, February 16, 2011
MANY METHOD ARGUMENTS
new Person("Enno", "Runne") Java
new Person("Enno", "Runne", "Sweden")
new Person("Enno", "Runne", "Sweden", "Stockholm")
new Person("Enno", "Runne", null, "Stockholm")
p = new Person("Enno", "Runne", city = "Stockholm") Scala
p = new Builder("Enno", "Runne").city("Stockholm").build();
rel i eve m y pai n
builders
Wednesday, February 16, 2011
MANY METHOD ARGUMENTS
new Person("Enno", "Runne") Java
new Person("Enno", "Runne", "Sweden")
new Person("Enno", "Runne", "Sweden", "Stockholm")
new Person("Enno", "Runne", null, "Stockholm")
p = new Person("Enno", "Runne", city = "Stockholm") Scala
p = new Builder("Enno", "Runne").city("Stockholm").build();
Wednesday, February 16, 2011
FLUENT INTERFACE
class Builder {
String fn, ln, co, ci;
Java class Person( Scala
val fn: String,
val ln: String,
Builder(String fn, String ln) {
[Link] = fn; val country: String = null,
[Link] = ln; val city: String = null)
}
Person build() {
return new Person(fn, ln, co, ci);
}
Builder city(String ci) {
[Link] = ci;
return this;
}
Builder country(String co) {
[Link] = co;
return this;
}
Wednesday, February 16, 2011
FLUENT INTERFACE
class Builder {
String fn, ln, co, ci;
Java class Person( Scala
val fn: String,
val ln: String,
Builder(String fn, String ln) {
[Link] = fn; val country: String = null,
[Link] = ln; val city: String = null)
}
Person build() {
return new Person(fn, ln, co, ci);
}
Builder city(String ci) {
[Link] = ci;
return this;
}
Builder country(String co) {
[Link] = co;
return this;
}
Wednesday, February 16, 2011
VARIABLES AND VALUES
Wednesday, February 16, 2011
VARIABLES AND VALUES
var count = 6 variable, multiple assignment Scala
val count = 6 value, single assignment Scala
Wednesday, February 16, 2011
VARIABLES AND VALUES
var count = 6 variable, multiple assignment Scala
val count = 6 value, single assignment Scala
Wednesday, February 16, 2011
VARIABLES AND VALUES
var count = 6 variable, multiple assignment Scala
int count = 6; Java
val count = 6 value, single assignment Scala
final int count = 6; Java
Wednesday, February 16, 2011
VARIABLES AND VALUES
var count = 6 variable, multiple assignment Scala
int count = 6; Java
val count = 6 value, single assignment Scala
final int count = 6; Java
o r d can m i m i c
final keyw
Scala’s val
Wednesday, February 16, 2011
VARIABLES AND VALUES
var count = 6 variable, multiple assignment Scala
int count = 6; Java
val count = 6 value, single assignment Scala
final int count = 6; Java
Wednesday, February 16, 2011
VALUES AT LARGE
Scala Java
• stresses immutability • JavaBean
standard: get and
set methods for all fields
• can’t accidentally change the
wrong object • easy:
• no mutable state, convenient • remove all setters
in multi-threaded apps
• make fields final
• just as String class in Java,
value objects in DDD
Wednesday, February 16, 2011
VALUES AT LARGE
Scala Java
• stresses immutability • JavaBean
standard: get and
set methods for all fields
• can’t accidentally change the
wrong object • easy:
• no mutable state, convenient • remove all setters
in multi-threaded apps
• make fields final
• just as String class in Java,
value objects in DDD
Wednesday, February 16, 2011
VALUES AT LARGE
Scala Java
• stresses immutability • JavaBean
standard: get and
set methods for all fields
• can’t accidentally change the
wrong object • easy:
• no mutable state, convenient • remove all setters
in multi-threaded apps
• make fields final
• just as String class in Java,
value objects in DDD
Wednesday, February 16, 2011
VALUES AT LARGE
Scala Java
• stresses immutability • JavaBean
standard: get and
set methods for all fields
• can’t accidentally change the
wrong object • easy:
• no mutable state, convenient • remove all setters
in multi-threaded apps
• make fields final
• just as String class in Java,
value objects in DDD v i ct i o n
d iffere nt co n
Wednesday, February 16, 2011
VALUES AT LARGE
Scala Java
• stresses immutability • JavaBean
standard: get and
set methods for all fields
• can’t accidentally change the
wrong object • easy:
• no mutable state, convenient • remove all setters
in multi-threaded apps
• make fields final
• just as String class in Java,
value objects in DDD
Wednesday, February 16, 2011
SMALL CLASSES
Wednesday, February 16, 2011
SMALL CLASSES
Scala Java
class Xyz(val s: String) public class Xyz {
public final String s;
public Xyz(String s) {
• very little code required this.s = s;
}
• no requirement on matching }
file names
• quite a bit of text
• even several packages in one
file • one public class per file
Wednesday, February 16, 2011
SMALL CLASSES
Scala Java
class Xyz(val s: String) public class Xyz {
public final String s;
public Xyz(String s) {
• very little code required this.s = s;
}
• no requirement on matching }
file names
• quite a bit of text
• even several packages in one
file • one public class per file
o s pl i t c o d e
more work t
into s m aller c la s se s
Wednesday, February 16, 2011
SMALL CLASSES
Scala Java
class Xyz(val s: String) public class Xyz {
public final String s;
public Xyz(String s) {
• very little code required this.s = s;
}
• no requirement on matching }
file names
• quite a bit of text
• even several packages in one
file • one public class per file
Wednesday, February 16, 2011
COLLECTIONS
Wednesday, February 16, 2011
COLLECTIONS
val words = List("one", "two", "three") Scala
val wordsWithTs = [Link](elem => [Link]("t"))
Wednesday, February 16, 2011
COLLECTIONS
val words = List("one", "two", "three") Scala
val wordsWithTs = [Link](elem => [Link]("t"))
List<String> words = [Link]("one", "two", "three"); Java
List<String> wordsWithTs = new ArrayList<String>();
for (String elem : words) {
if ([Link]("t")) {
[Link](elem);
}
}
Wednesday, February 16, 2011
COLLECTIONS
val words = List("one", "two", "three") Scala
val wordsWithTs = [Link](elem => [Link]("t"))
Wednesday, February 16, 2011
COLLECTIONS
val words = List("one", "two", "three") Scala
val wordsWithTs = [Link](elem => [Link]("t"))
List<String> words = [Link]("one", "two", "three"); Java
Collection<String> wordsWithTs = filter(words,
new Predicate<String>() {
(with Google
public boolean apply(String elem) { Guava)
return [Link]("t");
}
});
Wednesday, February 16, 2011
COLLECTIONS
val words = List("one", "two", "three") Scala
val wordsWithTs = [Link](elem => [Link]("t"))
List<String> words = [Link]("one", "two", "three"); Java
Collection<String> wordsWithTs = filter(words,
new Predicate<String>() {
(with Google
public boolean apply(String elem) { Guava)
return [Link]("t");
}
});
Wednesday, February 16, 2011
COLLECTIONS
val words = List("one", "two", "three") Scala
val wordsWithTs = [Link](elem => [Link]("t"))
List<String> words = [Link]("one", "two", "three"); Java
Collection<String> wordsWithTs = filter(words,
new Predicate<String>() {
(with Google
public boolean apply(String elem) { Guava)
return [Link]("t");
}
}); G o o g le’s G u ava
eases the pain
Wednesday, February 16, 2011
COLLECTIONS
val words = List("one", "two", "three") Scala
val wordsWithTs = [Link](elem => [Link]("t"))
List<String> words = [Link]("one", "two", "three"); Java
Collection<String> wordsWithTs = filter(words,
new Predicate<String>() {
(with Google
public boolean apply(String elem) { Guava)
return [Link]("t");
}
});
Wednesday, February 16, 2011
COMPOSITION
Wednesday, February 16, 2011
COMPOSITION
Scala Java
class A class A
abstract class B abstract class B
trait C interface C
trait D interface D
A extends B A extends B
A extends B with C with D A extends B implements C, D
Wednesday, February 16, 2011
COMPOSITION
Scala
trait HasName {
var name: String = ""
def getName() = name +
getOther()
def getOther(): String
}
Wednesday, February 16, 2011
COMPOSITION
Scala
trait HasName {
var name: String = ""
def getName() = name +
getOther()
def getOther(): String
}
Wednesday, February 16, 2011
COMPOSITION
Scala Java
trait HasName { interface HasName {
var name: String = "" String getName();
def getName() = name + String getOther();
getOther() }
def getOther(): String
} abstract class HasNameImpl
implements HasName {
String name;
public String getName() {
return name + getOther();
}
}
Wednesday, February 16, 2011
COMPOSITION
class User
Scala
extends HasName {
def getOther() = "!"
}
val u = new User
[Link] = "name"
[Link]()
Wednesday, February 16, 2011
COMPOSITION
class User
Scala class User implements HasName { Java
extends HasName { HasName outer = this;
HasNameImpl impl = new HasNameImpl() {
def getOther() = "!"
String getOther() {
}
return [Link]();
}};
String getName() {
val u = new User return [Link]();
[Link] = "name" }
[Link]() String getOther() { return "!"; }
void setName(String s) { [Link] = s; }
}
User uc = new User();
[Link]("name");
[Link]();
Wednesday, February 16, 2011
ADVANCED SWITCH
Wednesday, February 16, 2011
ADVANCED SWITCH
Java
if (o instanceof Xyz) {
doThis();
}
else if (o instanceof Rst) {
doThat();
}
Wednesday, February 16, 2011
ADVANCED SWITCH
Java Java
if (o instanceof Xyz) { catch (Xyz o) {
doThis(); doThis();
} }
else if (o instanceof Rst) { catch (Rst o) {
doThat(); doThat();
} }
Wednesday, February 16, 2011
ADVANCED SWITCH
Java
catch (Xyz o) {
doThis();
}
catch (Rst o) {
doThat();
}
Wednesday, February 16, 2011
ADVANCED SWITCH
Scala Java
catch { catch (Xyz o) {
case o: Xyz => { doThis();
doThis(); }
} catch (Rst o) {
case o: Rst => { doThat();
doThat(); }
}
}
Wednesday, February 16, 2011
ADVANCED SWITCH
Scala
o match {
case o: Xyz => {
doThis();
}
case o: Rst => {
doThat();
}
case "hi" => {
doSomething();
}
}
Wednesday, February 16, 2011
ADVANCED SWITCH
Scala
o match {
case o: Xyz => {
doThis();
}
case o: Rst => {
doThat();
}
case "hi" => {
doSomething();
}
}
Wednesday, February 16, 2011
ADVANCED SWITCH
Scala Java
o match { match(o,
case_instanceOf([Link],
case o: Xyz => { new Code<String>() {
doThis(); public void run(String obj) {
} doThis(obj);
case o: Rst => { }
}),
doThat(); case_instanceOf([Link],
} new Code<String>() {
case "hi" => { public void run(String obj) {
doThat(obj);
doSomething();
}
} }),
} case_eq("hi",
new Code<String>() {
public void run(String obj) {
doSomething(obj);
Wednesday, February 16, 2011
ADVANCED SWITCH
Scala Java
o match { match(o,
case_instanceOf([Link],
case o: Xyz => { new Code<String>() {
doThis(); public void run(String obj) {
} doThis(obj);
case o: Rst => { }
}),
doThat(); case_instanceOf([Link],
} new Code<String>() {
case "hi" => { public void run(String obj) {
doThat(obj);
doSomething();
}
} }),
} case_eq("hi",
new Code<String>() {
public void run(String obj) {
doSomething(obj);
Wednesday, February 16, 2011
Wednesday, February 16, 2011
Thank you for listening.
Enno Runne
Wednesday, February 16, 2011
Wednesday, February 16, 2011