Scala
Puzz ers
Andrew Phillips & Nermin Šerifovic
Scala
Puzz ers
Andrew Phillips & Nermin Šerifovic
Scala
Puzz ers
Andrew Phillips & Nermin Šerifovic
What is a Puzzler?
●
Intentional language feature
www.scalapuzzlers.com
What is a Puzzler?
●
Intentional language feature
●
So no bugs
www.scalapuzzlers.com
What is a Puzzler?
●
Intentional language feature
●
●
So no bugs
Not just weird because you don't know Scala
www.scalapuzzlers.com
What is a Puzzler?
●
Intentional language feature
●
●
So no bugs
Not just weird because you don't know Scala
●
So no "what is this weird operator?!?"
www.scalapuzzlers.com
What is a Puzzler?
●
Intentional language feature
●
●
Not just weird because you don't know Scala
●
●
So no bugs
So no "what is this weird operator?!?"
Should be "surprising" or "non-intuitive" to a
reasonably skilled Scala developer
www.scalapuzzlers.com
What is a Puzzler?
●
Intentional language feature
●
●
Not just weird because you don't know Scala
●
●
So no bugs
So no "what is this weird operator?!?"
Should be "surprising" or "non-intuitive" to a
reasonably skilled Scala developer
●
For suitable definitions of "reasonably skilled"
www.scalapuzzlers.com
What is a Puzzler?
●
Tested against the Scala 2.11.2 REPL
www.scalapuzzlers.com
It'll be More Fun if...
www.scalapuzzlers.com
Having Said That...
www.scalapuzzlers.com
Init You, Init Me
object XY {
object X { val value: Int = Y.value + 1 }
object Y { val value: Int = X.value + 1 }
}
println(if (math.random > 0.5) XY.X.value else XY.Y.value)
www.scalapuzzlers.com
Init You, Init Me
object XY {
object X { val value: Int = Y.value + 1 }
object Y { val value: Int = X.value + 1 }
}
println(if (math.random > 0.5) XY.X.value else XY.Y.value)
A. Prints
1
B. Prints
2
C. Prints either
1
or
2
D. Throws a runtime exception
www.scalapuzzlers.com
Init You, Init Me
object XY {
object X { val value: Int = Y.value + 1 }
object Y { val value: Int = X.value + 1 }
}
println(if (math.random > 0.5) XY.X.value else XY.Y.value)
A. Prints
1
B. Prints
2
C. Prints either
1
or
2
D. Throws a runtime exception
www.scalapuzzlers.com
Well, In This Case...
case class Toy(squeezeMsg: String = this.toString) {
override def toString = squeezeMsg
}
println(Toy("My name is Fido!") == new Toy("My name is Fido!"))
println(Toy() == new Toy())
www.scalapuzzlers.com
Well, In This Case...
case class Toy(squeezeMsg: String = this.toString) {
override def toString = squeezeMsg
}
println(Toy("My name is Fido!") == new Toy("My name is Fido!"))
println(Toy() == new Toy())
A. Fails to compile
B. Prints
true
false
C. Prints
D. The first statement prints
true
and the second throws a runtime
exception
true
true
www.scalapuzzlers.com
Well, In This Case...
case class Toy(squeezeMsg: String = this.toString) {
override def toString = squeezeMsg
}
println(Toy("My name is Fido!") == new Toy("My name is Fido!"))
println(Toy() == new Toy())
A. Fails to compile
B. Prints
true
false
C. Prints
D. The first statement prints
true
and the second throws a runtime
exception
true
true
www.scalapuzzlers.com
Trial and Error
def divideThenSqrt(n: Int, d: Int) =
Try(n / d) map {
value => if (value < 0)
Failure(new ArithmeticException(
"square root of negative number"))
else Success(math.sqrt(value))
} map {
value => s"sqrt(${n} / ${d}) = ${value}”
}
println(divideThenSqrt(18, 2))
println(divideThenSqrt(18, -2))
www.scalapuzzlers.com
Trial and Error
A. Prints
B. Prints
Success(sqrt(18 / 2) = 3.0)
Success(sqrt(18 / 2) = 3.0)
Success(java.lang.ArithmeticE
xception: square root of
negative number)
Failure(java.lang.ArithmeticE
xception: square root of
negative number)
C. Prints
D. Prints
Success(sqrt(18 / 2) =
Success(3.0))
Success(sqrt(18 / -2) =
Failure(java.lang.ArithmeticE
xception: square root of
negative number))
Success(sqrt(18 / 2) = 3.0)
www.scalapuzzlers.com
Success(sqrt(18 / -2) =
java.lang.ArithmeticException
: square root of negative
number)
Trial and Error
A. Prints
B. Prints
Success(sqrt(18 / 2) = 3.0)
Success(sqrt(18 / 2) = 3.0)
Success(java.lang.ArithmeticE
xception: square root of
negative number)
Failure(java.lang.ArithmeticE
xception: square root of
negative number)
C. Prints
D. Prints
Success(sqrt(18 / 2) =
Success(3.0))
Success(sqrt(18 / -2) =
Failure(java.lang.ArithmeticE
xception: square root of
negative number))
Success(sqrt(18 / 2) = 3.0)
www.scalapuzzlers.com
Success(sqrt(18 / -2) =
java.lang.ArithmeticException
: square root of negative
number)
Partially Even
val isEven = PartialFunction[Int, String] {
case n if n % 2 == 0 => "Even"
}
val isOdd = PartialFunction[Int, String] {
case n if n % 2 == 1 => "Odd"
}
println(Seq(0, 2) map (isEven orElse isOdd))
println(Seq(0, 1, 2) map (isEven orElse isOdd))
www.scalapuzzlers.com
Partially Even
A. Prints
List(Even, Even)
List(Even, Even, Even)
B. Prints
List(Even, Even)
List(Even, Odd, Even)
C. Prints
D. The first statement prints
List(Even, Even)
and the second throws a runtime
exception
List("0", "2")
List("0", "1", "2")
www.scalapuzzlers.com
Partially Even
A. Prints
List(Even, Even)
List(Even, Even, Even)
B. Prints
List(Even, Even)
List(Even, Odd, Even)
C. Prints
D. The first statement prints
List(Even, Even)
and the second throws a runtime
exception
List("0", "2")
List("0", "1", "2")
www.scalapuzzlers.com
Information Overload
object Oh {
def overloadA(u: Unit) = "I accept a Unit"
def overloadA(u: Unit, n: Nothing) =
"I accept a Unit and Nothing"
def overloadB(n: Unit) = "I accept a Unit"
def overloadB(n: Nothing) = "I accept Nothing"
}
println(Oh overloadA 99)
println(Oh overloadB 99)
www.scalapuzzlers.com
Information Overload
A. The first statement prints
I accept a Unit
and the second fails to compile
B. The first statement fails to
compile and the second prints
I accept Nothing
C. Both statements fail to
compile
D. Prints
I accept a Unit
I accept a Unit
www.scalapuzzlers.com
Information Overload
A. The first statement prints
I accept a Unit
and the second fails to compile
B. The first statement fails to
compile and the second prints
I accept Nothing
C. Both statements fail to
compile
D. Prints
I accept a Unit
I accept a Unit
www.scalapuzzlers.com
Extract or Fail?
val n = null
val nObj: Object = null
println(n match { case Symbol(x) => x; case _ => "Not a symbol" })
println(nObj match { case Symbol(x) => x; case _ => "Not a symbol" })
www.scalapuzzlers.com
Extract or Fail?
val n = null
val nObj: Object = null
println(n match { case Symbol(x) => x; case _ => "Not a symbol" })
println(nObj match { case Symbol(x) => x; case _ => "Not a symbol" })
A. Prints
Not a symbol
Not a symbol
B. Both statements throw a
NullPointerException
C. Prints
null
Not a symbol
D. The first statement throws a
NullPointerException and
the second prints
Not a symbol
www.scalapuzzlers.com
Extract or Fail?
val n = null
val nObj: Object = null
println(n match { case Symbol(x) => x; case _ => "Not a symbol" })
println(nObj match { case Symbol(x) => x; case _ => "Not a symbol" })
A. Prints
Not a symbol
Not a symbol
B. Both statements throw a
NullPointerException
C. Prints
null
Not a symbol
D. The first statement throws a
NullPointerException and
the second prints
Not a symbol
www.scalapuzzlers.com
Think of 1 Card
case class Card(number: Int, suit: String = "clubs") {
val value = (number % 13) + 1 // ace = 1, king = 13
def isInDeck(implicit deck: List[Card]) = deck contains this
}
implicit val deck = List(Card(1, "spades"))
implicit def intToCard(n: Int) = Card(n)
println(1.isInDeck)
www.scalapuzzlers.com
Think of 1 Card
case class Card(number: Int, suit: String = "clubs") {
val value = (number % 13) + 1 // ace = 1, king = 13
def isInDeck(implicit deck: List[Card]) = deck contains this
}
implicit val deck = List(Card(1, "spades"))
implicit def intToCard(n: Int) = Card(n)
println(1.isInDeck)
A. Throws a runtime exception
B. Prints
false
C. Prints
D. Fails to compile
true
www.scalapuzzlers.com
Think of 1 Card
case class Card(number: Int, suit: String = "clubs") {
val value = (number % 13) + 1 // ace = 1, king = 13
def isInDeck(implicit deck: List[Card]) = deck contains this
}
implicit val deck = List(Card(1, "spades"))
implicit def intToCard(n: Int) = Card(n)
println(1.isInDeck)
A. Throws a runtime exception
B. Prints
false
C. Prints
D. Fails to compile
true
www.scalapuzzlers.com
Implicit Kryptonite
trait Messages { def greeting: String }
trait Printer { def print(msg: String) }
object NormalDay {
implicit val EverydayMessages =
new Messages { val greeting = "Hello, world!" }
implicit val ConsolePrinter = new Printer {
def print(msg: String) { println(msg) }
}
}
object SunnyDay {
implicit val HappyMessages =
new Messages { val greeting = "What a nice day!" }
implicit val ConsolePrinter = new Printer {
def print(msg: String) { println(s"$msg :-)") }
}
}
import NormalDay._
implicitly[Printer] print implicitly[Messages].greeting
{
import SunnyDay._
implicitly[Printer] print implicitly[Messages].greeting
}
www.scalapuzzlers.com
Implicit Kryptonite
A. The first statement prints
Hello, world!
and the second fails to compile
B. Prints
Hello, world!
What a nice day! :-)
C. Prints
Hello, world!
What a nice day!
D. Prints
Hello, world! :-)
What a nice day! :-)
www.scalapuzzlers.com
Implicit Kryptonite
A. The first statement prints
Hello, world!
and the second fails to compile
B. Prints
Hello, world!
What a nice day! :-)
C. Prints
Hello, world!
What a nice day!
D. Prints
Hello, world! :-)
What a nice day! :-)
www.scalapuzzlers.com
Before You Go…
www.scalapuzzlers.com
www.scalapuzzlers.com
scalapuzzlers.com/buy-the-book
© Copyright 2026 Paperzz