# D Appendix D: Chapter 4 Exercise & Challenge Solutions Written by Massimo Carli

Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.

You can unlock the rest of this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.

## Exercise 4.1

Can you write a lambda expression that calculates the distance between two points given their coordinates, `x1, y1` and `x2, y2`? The formula for the distance between two points is `distance = √(x2−x1)²+(y2−y1)²`.

### Exercise 4.1 solution

You can approach this problem in different ways. Assuming you pass all the coordinates as distinct parameters, you can write the following code:

``````val distanceLambda = { x1: Double, y1: Double, x2: Double, y2: Double -> // 1
val sqr1 = (x2 - x1) * (x2 - x1) // 2
val sqr2 = (y2 - y1) * (y2 - y1) // 2
Math.sqrt(sqr1 + sqr2) // 3
}
``````
``````typealias Point = Pair<Double, Double>

val distanceLambdaWithPairs = { p1: Point, p2: Point ->
val sqr1 = Math.pow(p1.first - p2.first, 2.0)
val sqr2 = Math.pow(p1.second - p2.second, 2.0)
Math.sqrt(sqr1 + sqr2)
}
``````
``````fun main() {
println(distanceLambda(0.0, 0.0, 1.0, 1.0))
println(distanceLambdaWithPairs(0.0 to 0.0, 1.0 to 1.0))
}
``````
``````1.4142135623730951
1.4142135623730951
``````

## Exercise 4.2

What’s the type for the lambda expression you wrote in Exercise 4.1?

### Exercise 4.2 solution

The type of `distanceLambda` is:

``````val distanceLambda: (Double, Double, Double, Double) -> Double
``````
``````val distanceLambdaWithPairs: (Point, Point) -> Double
``````
``````val distanceLambdaWithPairs: (Pair<Double, Double>, Pair<Double, Double>) -> Double
``````

## Exercise 4.3

What are the types of the following lambda expressions?

``````val emptyLambda = {} // 1
val helloWorldLambda = { "Hello World!" } // 2
val helloLambda = { name: String -> "Hello \$name!" } // 3
val nothingLambda = { TODO("Do exercise 4.3!") } // 4
``````
`````` typealias AbsurdType = (Nothing) -> Nothing
``````

### Exercise 4.3 solution

You start by looking at:

``````val emptyLambda = {}
``````
``````val emptyLambda: () -> Unit
``````
``````val helloWorldLambda = { "Hello World!" }
``````
``````val helloWorldLambda: () -> String
``````
``````val helloLambda = { name: String -> "Hello \$name!" }
``````
``````val helloLambda: (String) -> String
``````
``````val nothingLambda = { TODO("Do exercise 4.3!") }
``````
``````val nothingLambda: () -> Nothing
``````

#### Nothing and lambda

Given the type:

``````typealias AbsurdType = (Nothing) -> Nothing
``````
``````val absurd: AbsurdType = { nothing -> throw Exception("This is Absurd") }
``````
``````fun main() {
absurd(TODO("Invoked?"))
}
``````
``````fun main() {
absurd(throw Exception("Invoked?"))
}
``````

## Exercise 4.4

Can you implement a function simulating the short-circuit and operator with the following signature without using `&&`? In other words, can you replicate the short-circuiting behavior of `left && right`:

``````  fun shortCircuitAnd(left: () -> Boolean, right: () -> Boolean): Boolean
``````

### Exercise 4.4 solution

In Kotlin, `if` is an expression, so you can implement `shortCircuitAnd` like this:

``````fun shortCircuitAnd(
left: () -> Boolean,
right: () -> Boolean
): Boolean = if (left()) {
right()
} else {
false
}
``````
``````fun main() {
val inputValue = 2
shortCircuitAnd(
left = { println("LeftEvaluated!"); inputValue > 3 },
right = { println("RightEvaluated!"); inputValue < 10 },
)
}
``````
``````LeftEvaluated!
``````
``````LeftEvaluated!
RightEvaluated!
``````

## Exercise 4.5

Can you implement the function `myLazy` with the following signature, which allows you to pass in a lambda expression and execute it just once?

``````fun <A: Any> myLazy(fn: () -> A): () -> A // ???
``````

### Exercise 4.5 solution

`myLazy` accepts a lambda expression of type `() -> A` as an input parameter. It’s also important to note that `A` has a constraint, which makes it non-null. This makes the exercise a little bit easier, because you can write something like:

``````fun <A : Any> myLazy(fn: () -> A): () -> A {
var result: A? = null // 1
return { // 2
if (result == null) { // 3
result = fn() // 4
}
result!! // 5
}
}
``````
``````fun main() {
val myLazy = myLazy { println("I'm very lazy!"); 10 }
3.times {
println(myLazy())
}
}
``````
``````I'm very lazy!
10
10
10
``````

## Exercise 4.6

Create a function `fibo` returning the values of a Fibonacci sequence. Remember, every value in a Fibonacci sequence is the sum of the previous two elements. The first two elements are `0` and `1`. The first values are, then:

``````0  1  1  2  3  5  8  13  21 ...
``````

### Exercise 4.6 solution

The following is a possible implementation for the Fibonacci sequence using lambda evaluation:

``````fun fibo(): () -> Int {
var first = 0
var second = 1
var count = 0
return {
val next = when (count) {
0 -> 0
1 -> 1
else -> {
val ret = first + second
first = second
second = ret
ret
}
}
count++
next
}
}
``````
``````fun main() {
val fiboSeq = fibo()
10.times {
print("\${fiboSeq()}  ")
}
}
``````
``````0  1  1  2  3  5  8  13  21  34
``````

## Challenge 4.1

In Exercise 4.5, you created `myLazy`, which allowed you to implement memoization for a generic lambda expression of type `()-> A`. Can you now create `myNullableLazy` supporting optional types with the following signature?

``````fun <A> myNullableLazy(fn: () -> A?): () -> A? // ...
``````

### Challenge 4.1 solution

To remove the constraint, you just need to use an additional variable, like this:

``````fun <A> myNullableLazy(fn: () -> A?): () -> A? {
var evaluated = false // HERE
var result: A? = null
return { ->
if (!evaluated) {
evaluated = true
result = fn()
}
result
}
}
``````
``````fun main() {
val myNullableLazy: () -> Int? =
myNullableLazy { println("I'm nullable lazy!"); null }
3.times {
println(myNullableLazy())
}
}
``````
``````I'm nullable lazy!
null
null
null
``````

## Challenge 4.2

You might be aware of Euler’s number e. It’s a mathematical constant of huge importance that you can calculate in very different ways. It’s an irrational number like pi that can’t be represented in the form `n/m`. Here you’re not required to know what it is, but you can use the following formula:

### Challenge 4.2 solution

A possible implementation of the Euler formula is:

``````fun e(): () -> Double {
var currentSum = 1.0 // 1
var n = 1

tailrec fun factorial(n: Int, tmp: Int): Int = // 2
if (n == 1) tmp else factorial(n - 1, n * tmp)

return {
currentSum += 1.0 / factorial(n++, 1).toDouble() // 3
currentSum
}
}
``````
``````fun main() {
val e = e()
10.times {
println(e())
}
}
``````
``````2.0
2.5
2.6666666666666665
2.708333333333333
2.7166666666666663
2.7180555555555554
2.7182539682539684
2.71827876984127
2.7182815255731922
2.7182818011463845
``````
``````fun factSeq(): () -> Int {
var partial = 1
var n = 1
return {
partial *= n++
partial
}
}
``````
``````fun fastE(): () -> Double {
var currentSum = 1.0
val fact = factSeq()
return {
currentSum += 1.0 / fact().toDouble()
currentSum
}
}
``````
``````fun main() {
val e = fastE() // HERE
10.times {
println(e())
}
}
``````
``````2.0
2.5
2.6666666666666665
2.708333333333333
2.7166666666666663
2.7180555555555554
2.7182539682539684
2.71827876984127
2.7182815255731922
2.7182818011463845
``````

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.

© 2022 Razeware LLC You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription. 