The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

143
Scala The learning curve Aleksandar Prokopec

Transcript of The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Page 1: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Scala The learning curve

Aleksandar Prokopec

Page 2: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Sometime back in 2008…

beans

Page 3: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Sometime back in 2008…

List<AbstractSingletonProxyFactoryBean> beans =

Page 4: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Sometime back in 2008…

List<AbstractSingletonProxyFactoryBean> beans =

new ArrayList<AbstractSingletonProxyFactoryBean>();

Page 5: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…
Page 6: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

List<AbstractSingletonProxyFactoryBean> beans =

new ArrayList<AbstractSingletonProxyFactoryBean>();

beans.add(myBean);

Sometime back in 2008…

Page 7: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…
Page 8: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

List<AbstractSingletonProxyFactoryBean> beans =

new ArrayList<AbstractSingletonProxyFactoryBean>();

beans.add(myBean);

for (b : oldBeans) {

}

Sometime back in 2008…

Page 9: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

List<AbstractSingletonProxyFactoryBean> beans =

new ArrayList<AbstractSingletonProxyFactoryBean>();

beans.add(myBean);

for (b : oldBeans) {

beans.add(modernizeBean(b));

}

Sometime back in 2008…

Page 10: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

List<AbstractSingletonProxyFactoryBean> beans =

new ArrayList<AbstractSingletonProxyFactoryBean>();

beans.add(myBean);

for (b : oldBeans) {

beans.add(modernizeBean(b));

}

singletonBeanMap.put(“myBeanKey”, beans);

Sometime back in 2008…

Page 11: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

List<AbstractSingletonProxyFactoryBean> beans =

new ArrayList<AbstractSingletonProxyFactoryBean>();

beans.add(myBean);

for (b : oldBeans) {

beans.add(modernizeBean(b));

}

singletonBeanMap.put(“myBeanKey”, beans);

Map<

String,

List<AbstractSingletonProxyFactoryBean>>

singletonBeanMap = new HashMap<

String,

List<AbstractSingletonProxyFactoryBean>>();

Sometime back in 2008…

Page 12: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…
Page 13: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…
Page 14: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…
Page 15: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

5 golden features …that got me hooked

Page 16: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

JVM

List<AbstractSingletonProxyFactoryBean> beans =

new ArrayList<AbstractSingletonProxyFactoryBean>();

beans.add(myBean);

for (b : oldBeans) {

beans.add(modernizeBean(b));

}

Page 17: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

No semicolon

List<AbstractSingletonProxyFactoryBean> beans =

new ArrayList<AbstractSingletonProxyFactoryBean>()

beans.add(myBean)

for (b : oldBeans) {

beans.add(modernizeBean(b))

}

Page 18: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Local type inference

val beans =

new ArrayList<AbstractSingletonProxyFactoryBean>()

beans.add(myBean)

for (b : oldBeans) {

beans.add(modernizeBean(b))

}

Page 19: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Local type inference

val beans =

new ArrayList[AbstractSingletonProxyFactoryBean]()

beans.add(myBean)

for (b : oldBeans) {

beans.add(modernizeBean(b))

}

Page 20: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Collections

val beans =

Buffer[AbstractSingletonProxyFactoryBean]()

beans.add(myBean)

for (b : oldBeans) {

beans.add(modernizeBean(b))

}

Page 21: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Collections

val beans =

Buffer[AbstractSingletonProxyFactoryBean]()

beans += myBean

for (b : oldBeans) {

beans += modernizeBean(b)

}

Page 22: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Collections

val beans =

Buffer[AbstractSingletonProxyFactoryBean]()

beans += myBean

for (b <- oldBeans) {

beans += modernizeBean(b)

}

Page 23: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Collections

val beans =

Buffer[AbstractSingletonProxyFactoryBean](myBean)

for (b <- oldBeans) {

beans += modernizeBean(b)

}

Page 24: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Collections

val beans =

Buffer(myBean)

for (b <- oldBeans) {

beans += modernizeBean(b)

}

Page 25: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Collections

val beans = Buffer(myBean)

for (b <- oldBeans) {

beans += modernizeBean(b)

}

Page 26: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Lambdas

val beans = Buffer(myBean)

beans ++= oldBeans.map(modernizeBean)

Page 27: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Lambdas

val beans = Buffer(myBean)

beans ++= oldBeans.map(modernizeBean)

Page 28: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

knowledge

time

Page 29: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Best way to learn a language

Solve a problem

Page 30: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Best way to learn a language

Solve a problem

Implement a user input API

for a command-line client

Page 31: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Best way to learn a language

Solve a problem

Implement a user input API

for a command-line SSH client

Page 32: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Best way to learn a language

Solve a problem

Ask if custom host needed

If yes, ask to enter custom host

Page 33: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

print(“Custom [Y/N]: “)

val yn = readln()

Page 34: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

print(“Custom [Y/N]: “)

val yn = readln()

var host = “”

Page 35: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

print(“Custom [Y/N]: “)

val yn = readln()

var host = “”

if (yn.trim == “Y”) {

} else ...

Page 36: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

print(“Custom [Y/N]: “)

val yn = readln()

var host = “”

if (yn.trim == “Y”) {

print(“Enter host: “)

host = readln()

} else ...

Page 37: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

print(“Custom [Y/N]: “)

val yn = readln()

var host = “”

if (yn.trim == “Y”) {

print(“Enter host: “)

host = readln()

} else host = “server.lan:22”

Page 38: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

print(“Custom [Y/N]: “)

val yn = readln()

var host = “”

if (yn.trim == “Y”) {

print(“Enter host: “)

host = readln()

} else host = “server.lan:22”

connect(new Remote(host))

Page 39: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

print(“Custom [Y/N]: “)

val yn = readln()

var host = “”

if (yn.trim == “Y”) {

print(“Enter host: “)

host = readln()

} else host = “server.lan:22”

connect(new Remote(host))

> Custom [Y/N]:

java.lang.NullPointerException

Page 40: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Fundamental problem

readln() returns null for empty entries

Page 41: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

I call it my billion-dollar mistake. It was the

invention of the null reference in 1965.

Tony Hoare

Page 42: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

abstract class Option[T]

Page 43: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

abstract class Option[T]

class Some[T](x: T) extends Option[T]

class None[T] extends Option[T]

Page 44: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

abstract class Option[T] {

def get: T

}

class Some[T](x: T) extends Option[T]

class None[T] extends Option[T]

Page 45: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

abstract class Option[T] {

def get: T

}

class Some[T](x: T) extends Option[T] {

def get = x

}

class None[T] extends Option[T]

Page 46: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

abstract class Option[T] {

def get: T

}

class Some[T](x: T) extends Option[T] {

def get = x

}

class None[T] extends Option[T] {

def get = sys.error(“None.get”)

}

Page 47: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def text(q: String): Option[String] = {

print(q)

val input = readln()

if (input != null) Some(input)

else None

}

Page 48: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val yn = text(“Custom [Y/N]: “)

Page 49: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val yn = text(“Custom [Y/N]: “)

var host = “”

if (yn.trim == “Y”) {

host = text(“Enter host: “)

}

Page 50: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val yn = text(“Custom [Y/N]: “)

var host = “”

if (yn.trim == “Y”) {

host = text(“Enter host: “)

} else host = “server.lan:22”

connect(new Remote(host))

Page 51: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val yn = text(“Custom [Y/N]: “)

var host = “”

if (yn.trim == “Y”) {

host = text(“Enter host: “)

} else host = “server.lan:22”

connect(new Remote(host))

error: trim not a member of Option[String]

yn.trim

^

Page 52: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val yn: Option[String] = text(“Custom: “)

var host = “”

if (yn.trim == “Y”) {

host = text(“Enter host: “)

} else host = “server.lan:22”

connect(new Remote(host))

error: trim not a member of Option[String]

yn.trim

^

Page 53: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val yn = text(“Custom [Y/N]: “).get

var host = “”

if (yn.trim == “Y”) {

host = text(“Enter host: “).get

} else host = “server.lan:22”

connect(new Remote(host))

Page 54: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val yn = text(“Custom [Y/N]: “).get

var host = “”

if (yn.trim == “Y”) {

host = text(“Enter host: “).get

} else host = “server.lan:22”

connect(new Remote(host))

> Custom [Y/N]:

java.lang.RuntimeError: None.get

Page 55: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val yn = text(“Custom [Y/N]: “)

if (yn == None) return

var host: Option[String] = None

if (yn.get.trim == “Y”) {

val h = text(“Enter host: “)

if (h == None) return else host = h

} else host = Some(“server.lan:22”)

connect(new Remote(host.get))

Page 56: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val yn = text(“Custom [Y/N]: “)

if (yn == None) return

var host: Option[String] = None

if (yn.get.trim == “Y”) {

val h = text(“Enter host: “)

if (h == None) return else host = h

} else host = Some(“server.lan:22”)

return new Remote(host.get)

def startClient() {

val remote: Option[Remote] = query()

connect(remote)

}

Page 57: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def query(): Option[Remote] = {

val yn = text(“Custom [Y/N]: “)

if (yn == None) return None

var host: Option[String] = None

if (yn.get.trim == “Y”) {

val h = text(“Enter host: “)

if (h == None) return None

else host = h

} else host = Some(“server.lan:22”)

return Some(new Remote(host.get))

}

def startClient() {

val remote: Option[Remote] = query()

connect(remote)

}

Page 58: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def query(): Option[Remote] = {

val yn = text(“Custom [Y/N]: “)

if (yn == None) return None

var host: Option[String] = None

if (yn.get.trim == “Y”) {

val h = text(“Enter host: “)

if (h == None) return None

else host = h

} else host = Some(“server.lan:22”)

return Some(new Remote(host.get))

}

def startClient() {

val remote: Option[Remote] = query()

connect(remote)

}

Page 59: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def startClient() {

println(“Now selecting remote.“)

val remote: Option[Remote] = query()

remote match {

}

}

Page 60: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def startClient() {

println(“Now selecting remote.“)

val remote: Option[Remote] = query()

remote match {

case Some(r) => connect(r)

}

}

Page 61: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def startClient() {

println(“Now selecting remote.“)

val remote: Option[Remote] = query()

remote match {

case Some(r) => connect(r)

case None => println(“Can’t connect.”)

}

}

Page 62: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def startClient() {

println(“Now selecting remote.“)

val remote: Option[Remote] = query()

remote match {

case Some(r) => connect(r)

case None => println(“Can’t connect.”)

}

}

if (flag_testing)

startClient(() => Some(localhost))

else

startClient(query)

Page 63: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def startClient(q: () => Option[Remote]) {

println(“Now selecting remote.“)

val remote: Option[Remote] = q()

remote match {

case Some(r) => connect(r)

case None => println(“Can’t connect.”)

}

}

if (flag_testing)

startClient(() => Some(localhost))

else

startClient(query)

Page 64: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def query: () => Option[Remote] = {

() =>

val yn = text(“Custom [Y/N]: “)

if (yn == None) return None

var host: Option[String] = None

if (yn.get.trim == “Y”) {

val h = text(“Enter host: “)

if (h == None) return None

else host = h

} else host = Some(“server.lan:22”)

return Some(new Remote(host.get))

}

Page 65: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Token soup

Page 66: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Token soup

An incomprehensible jumble

of characters which it is

difficult or impossible to discern

the meaning from.

Page 67: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Plan to throw one away; you will, anyhow.

Fred Brooks

The Mythical Man-Month

Page 68: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

() => Option[T]

Page 69: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

type Query[T] = () => Option[T]

Page 70: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

type Query[T] = () => Option[T]

def const[T](x: T): Query[T] =

Page 71: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

type Query[T] = () => Option[T]

def const[T](x: T): Query[T] =

() => Some(x)

Page 72: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

type Query[T] = () => Option[T]

def const[T](x: T): Query[T] =

() => Some(x)

startClient(

const(new Remote(“localhost”)))

Page 73: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

type Query[T] = () => Option[T]

def text(q: String): Query[String] = {

}

Page 74: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

type Query[T] = () => Option[T]

def text(q: String): Query[String] = {

() =>

}

Page 75: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

type Query[T] = () => Option[T]

def text(q: String): Query[String] = {

() =>

print(q)

}

Page 76: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

type Query[T] = () => Option[T]

def text(q: String): Query[String] = {

() =>

print(q)

val input = readln()

}

Page 77: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

type Query[T] = () => Option[T]

def text(q: String): Query[String] = {

() =>

print(q)

val input = readln()

if (input != null) Some(input)

else None

}

Page 78: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val hostQuery = text(“Enter host: “)

Page 79: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val hostQuery: Query[String] =

text(“Enter host: “)

Page 80: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val hostQuery: Query[String] =

text(“Enter host: “)

val remoteQuery: Query[Remote]

Page 81: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val hostQuery: Query[String] =

text(“Enter host: “)

val remoteQuery: Query[Remote] =

host => new Remote(host)

Page 82: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val hostQuery: Query[String] =

text(“Enter host: “)

val remoteQuery: Query[Remote] =

hostQuery.map(host => new Remote(host))

Page 83: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val hostQuery: Query[String] =

text(“Enter host: “)

val hostOption: Option[String] =

hostQuery()

val remoteOption: Option[Remote] =

hostOption.map(host => new Remote(host))

Page 84: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val hostQuery: Query[String] =

text(“Enter host: “)

val hostOption: Option[String] =

hostQuery()

val remoteOption: Option[Remote] =

hostOption.map(host => new Remote(host))

for (host <- hostOption) yield {

new Remote(host)

}

Page 85: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def map[T, S](q: Option[T], f: T => S):

Option[S] =

Page 86: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def map[T, S](q: Option[T], f: T => S):

Option[S] =

t s

Page 87: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def map[T, S](q: Option[T], f: T => S):

Option[S] = q match {

}

t s

Page 88: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def map[T, S](q: Option[T], f: T => S):

Option[S] = q match {

case Some(v) => Some(f(v))

case None => None

}

t s

Page 89: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def map[T, S]

(q: Query[T], f: T => S): Query[S] =

type Query[T] = () => Option[T]

Page 90: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def map[T, S]

(q: Query[T], f: T => S): Query[S] =

() =>

type Query[T] = () => Option[T]

Page 91: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def map[T, S]

(q: Query[T], f: T => S): Query[S] =

() => q()

type Query[T] = () => Option[T]

Page 92: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def map[T, S]

(q: Query[T], f: T => S): Query[S] =

() => q() match {

}

type Query[T] = () => Option[T]

Page 93: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def map[T, S]

(q: Query[T], f: T => S): Query[S] =

() => q() match {

case Some(v) => Some(f(v))

case None => None

}

type Query[T] = () => Option[T]

Page 94: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val hostQuery: Query[String] =

text(“Enter host: “)

val remoteQuery: Query[String] =

for (host <- hostQuery) yield {

new Remote(host)

}

Page 95: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

for (host <- hostQuery) yield {

new Remote(host)

}

Page 96: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val yn = text(“Custom [Y/N]: “)

for {

host <- if (???) text(“Host: “)

else const(“server.lan:22”)

} yield new Remote(host)

Page 97: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val yn: Query[String] =

text(“Custom [Y/N]: “)

for {

host <- if (???) text(“Host: “)

else const(“server.lan:22”)

} yield new Remote(host)

Page 98: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

for {

yn <- text(“Custom [Y/N]”)

host <- if (???) text(“Host: “)

else const(“server.lan:22”)

} yield new Remote(host)

Page 99: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

for {

yn <- text(“Custom [Y/N]”)

host <- if (yn == “Y”) text(“Host: “)

else const(“server.lan:22”)

} yield new Remote(host)

Page 100: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

for {

yn <- Some(“Y”)

host <- if (yn == “Y”) Some(“localhost”)

else Some(“server.lan:22”)

} yield new Remote(host)

Page 101: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

for {

yn <- Some(“Y”)

host <- Some(“localhost”)

} yield new Remote(host)

Page 102: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

for {

yn <- Some(“Y”)

host <- Some(“localhost”)

} yield new Remote(host)

Some(“Y”).map(yn =>

)

Page 103: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

for {

yn <- Some(“Y”)

host <- Some(“localhost”)

} yield new Remote(host)

Some(“Y”).map(yn =>

Some(“localhost”)

)

Page 104: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

for {

yn <- Some(“Y”)

host <- Some(“localhost”)

} yield new Remote(host)

Some(“Y”).map(yn =>

Some(“localhost”).map(host =>

new Remote(host)

)

)

Page 105: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

for {

yn <- Some(“Y”)

host <- Some(“localhost”)

} yield new Remote(host)

Some(“Y”).map(yn =>

Some(“localhost”).map(host =>

new Remote(host)

)

): Option[???]

Page 106: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

for {

yn <- Some(“Y”)

host <- Some(“localhost”)

} yield new Remote(host)

Some(“Y”).map(yn =>

Some(“localhost”).map(host =>

new Remote(host)

)

): Option[Option[Remote]]

Page 107: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def map[T, S](q: Option[T],

f: T => S): Option[S]

Page 108: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def map[T, Option[S]](q: Option[T],

f: T => Option[S]): Option[Option[S]]

Page 109: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def flatMap[T, S](q: Option[T],

f: T => Option[S]): Option[S]

Page 110: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def flatMap[T, S](q: Option[T],

f: T => Option[S]): Option[S] = {

q match {

case None => None

}

}

Page 111: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def flatMap[T, S](q: Option[T],

f: T => Option[S]): Option[S] = {

q match {

case None => None

case Some(v) => f(v)

}

}

Page 112: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def flatMap[T, S](q: Option[T],

f: T => Option[S]): Option[S]

for {

yn <- Some(“Y”)

host <- if (yn == “Y”) Some(“localhost”)

else Some(“server.lan:22”)

} yield new Remote(host)

Some(“Y”).flatMap(yn =>

Some(“localhost”).map(host =>

new Remote(host)

)

): Option[Remote]

Page 113: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def flatMap[T, S](q: Option[T],

f: T => Option[S]): Option[S]

for {

yn <- Some(“Y”)

host <- if (yn == “Y”) Some(“localhost”)

else Some(“server.lan:22”)

} yield new Remote(host)

Some(“Y”).flatMap(yn =>

Some(“localhost”).map(host =>

new Remote(host)

)

): Option[Remote]

Page 114: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def flatMap[T, S](q: Option[T],

f: T => Option[S]): Option[S]

for {

yn <- Some(“Y”)

host <- if (yn == “Y”) Some(“localhost”)

else Some(“server.lan:22”)

} yield new Remote(host)

Some(“Y”).flatMap(yn =>

Some(“localhost”).map(host =>

new Remote(host)

)

): Option[Remote]

Page 115: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def flatMap[T, S](q: Query[T],

f: T => Query[S]): Query[S]

type Query[T] = () => Option[T]

Page 116: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

def flatMap[T, S](q: Query[T],

f: T => Query[S]): Query[S] =

() => q() match {

case Some(v) => f(v)()

case None => None

}

type Query[T] = () => Option[T]

Page 117: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

for {

yn <- text(“Custom [Y/N]: “)

host <- if (yn == “Y”) text(“Host: “)

else const(“server.lan:22”)

} yield new Remote(host)

Page 118: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Query[T]

is a monad!

Page 119: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val yn = text(“Custom [Y/N]? ”)()

if (yn == None) return None

var host = null

if (yn.get == “Y”) host = text(“Host: ”)()

else host = const(“server.lan:22”)()

if (host == None) return None

return Some(new Remote(host.get))

for {

yn <- text(“Custom [Y/N]: “)

host <- if (yn == “Y”) text(“Host: “)

else const(“server.lan:22”)

} yield new Remote(host)

VS.

Page 120: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Argument #1 The monad approach is more concise,

more readable and more beautiful.

Page 121: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val yn = text(“Custom [Y/N]? ”)()

if (yn == None) return None

var host = null

if (yn.get == “Y”) host = text(“Host: ”)()

else host = const(“server.lan:22”)()

if (host == None) return None

return Some(new Remote(host.get))

for {

yn <- text(“Custom [Y/N]: “)

host <- if (yn == “Y”) text(“Host: “)

else const(“server.lan:22”)

} yield new Remote(host)

Page 122: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val yn = text(“Custom [Y/N]? ”)()

if (yn == None) return None

var host = null

if (yn.get == “Y”) host = text(“Host: ”)()

else host = const(“server.lan:22”)()

if (host == None) return None

return Some(new Remote(host.get))

for {

yn <- text(“Custom [Y/N]: “)

host <- if (yn == “Y”) text(“Host: “)

else const(“server.lan:22”)

} yield new Remote(host)

Page 123: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

But, beauty is in the eye of the

beholder.

Page 124: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Argument #2 The monad approach is shorter.

Page 125: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val yn = text(“Custom [Y/N]? ”)()

if (yn == None) return None

var host = null

if (yn.get == “Y”) host = text(“Host: ”)()

else host = const(“server.lan:22”)()

if (host == None) return None

return Some(new Remote(host.get))

for {

yn <- text(“Custom [Y/N]: “)

host <- if (yn == “Y”) text(“Host: “)

else const(“server.lan:22”)

} yield new Remote(host)

Page 126: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

But, does shorter code imply

better code?

while(*dst++ = *src++);

Page 127: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Argument #3

In the monad approach,

there is no duplicated code.

Page 128: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val yn = text(“Custom [Y/N]? ”)()

if (yn == None) return None

var host = null

if (yn.get == “Y”) host = text(“Host: ”)()

else host = const(“server.lan:22”)()

if (host == None) return None

return Some(new Remote(host.get))

for {

yn <- text(“Custom [Y/N]: “)

host <- if (yn == “Y”) text(“Host: “)

else const(“server.lan:22”)

} yield new Remote(host)

Page 129: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

val yn = text(“Custom [Y/N]? ”)()

if (yn == None) return None

var host = null

if (yn.get == “Y”) host = text(“Host: ”)()

else host = const(“server.lan:22”)()

if (host == None) return None

return Some(new Remote(host.get))

Not just more boilerplate,

more of the same code.

Page 130: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

DRY principle Reduce repetition of any kind.

Page 131: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Monad Abstracts how the statements in the

program are chained together.

Page 132: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Monad A programmable semicolon.

Page 133: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Congratulations, you understand monads!

Page 134: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

knowledge

time

lambdas, collections, no semicolons

for-comprehensions

flatMap

Page 135: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Abstraction

abstraction concrete code

abstraction concrete code

Page 136: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Abstraction

abstraction concrete code

abstraction concrete code

abstraction concrete code

Page 137: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…
Page 138: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

knowledge

time

lambdas, collections, no semicolons

for-comprehensions

flatMap

knowledge

applied knowledge

Page 139: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Disallow abstractions

Page 140: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Disallow abstractions

Page 141: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Better tooling Programmable lint checkers

Page 142: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

It’s useful to customize your semicolons,

but even more useful to omit them.

Page 143: The learning curve · List beans = new ArrayList(); beans.add(myBean); Sometime back in 2008…

Thank you!