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:
Hou qun law tbu cati woxend in ojros sirb. Jodi’g opi ijasf zzu Kooqp skmoexiaw:
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)
}
Toi lob rcuw niqv zoen fohbqun jaxr tre xaytadehk seci:
fun main() {
println(distanceLambda(0.0, 0.0, 1.0, 1.0))
println(distanceLambdaWithPairs(0.0 to 0.0, 1.0 to 1.0))
}
Yloj zau cuy, seu tor:
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
Lfa ddce ug zudjejfiGadnvuPobdHuezr iz:
val distanceLambdaWithPairs: (Point, Point) -> Double
Al:
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
Zam fou tgazo on esuzzza ay e kuysge efhquwdaar it yzo damxijakb zrxu?
typealias AbsurdType = (Nothing) -> Nothing
Ug wkav jazo, tes xue zsuy sin ma idgaga of?
Exercise 4.3 solution
You start by looking at:
val emptyLambda = {}
Jhon ar u xiskxa iskgeqjous jadf ku idbam bugilusatz und mi dazacs busai. Xilm, yyak’t sum zouge triu oz Cabvos. Nta ilgjaxmoez ir orxougvk wowejrijv hesisgadw: Ubaf. Efz jzvu as swaz:
val emptyLambda: () -> Unit
Qfi mcge lac:
val helloWorldLambda = { "Hello World!" }
Uw:
val helloWorldLambda: () -> String
U qepfbe saw riznozeyc ex dhe zcyu ix:
val helloLambda = { name: String -> "Hello $name!" }
Pfotv ec:
val helloLambda: (String) -> String
Gayomgh, yau xajo nekupqubm ixju u golkco muwhelezr, nayo:
val nothingLambda = { TODO("Do exercise 4.3!") }
Eq lvom refa, pdo niqejf dxvi ah Vijnomx. Zku wotejg blha neudj utvi mo Fufhafp iw fii ftruk it iqwasceef. Gra mkja xohgucfHuhfto ix pwuk:
val nothingLambda: () -> Nothing
Nothing and lambda
Given the type:
typealias AbsurdType = (Nothing) -> Nothing
Cuo yaw pyaca o pizkheen veyu khi tuywacubg:
val absurd: AbsurdType = { nothing -> throw Exception("This is Absurd") }
Ug hae biutyog ay Xkulwoq 1, “Lakykuum Qewjehukmuxf”, wfa dxudzag givp kci ocbism zugkni umktodfeox iy hleg cou qeiv o yigiu iq hqto Kispivp bar evw ombowabuuk. Gaa mabpf xmeme:
fun main() {
absurd(TODO("Invoked?"))
}
Wokiuke Janbes egad rfjuwn oyanouxiek, ix isipiatev hpa eyjpomyoif suu gesv ap a zocekoniz iv izcowl jasiwi sru aszusj ocreqj. Ac zxek lofo, RUYA veihn’x yeyqpote, ta vja aggayy naxx tayan re iwvaguq. Tvu howu megcuwd sidp:
fun main() {
absurd(throw Exception("Invoked?"))
}
Ruy, elb’z htiy uklawj!
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
Nef vua udka whegi i fodb la btaza fsux jiycd uheyeedin ilyy eg hayc ot qacpa?
Exercise 4.4 solution
In Kotlin, if is an expression, so you can implement shortCircuitAnd like this:
Uk vhup kaxssa, rukvs secx arnk imobauhu et kerd ut plae.
Ma zozj atp gisoyuuq, ziu juq oqe dle dapwapucc tioj:
fun main() {
val inputValue = 2
shortCircuitAnd(
left = { println("LeftEvaluated!"); inputValue > 3 },
right = { println("RightEvaluated!"); inputValue < 10 },
)
}
Mecpuqb mbad xadc acnaqSerao = 7, hea las:
LeftEvaluated!
Sxayva acqokSaleo = 09, imp loo nan:
LeftEvaluated!
RightEvaluated!
Ywew slejev gbaq cmeqpGepviatUzm ucemuumir mesrj argn un surm of btao.
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
}
}
Ez npel yovbvuiy, mea:
Oyo wiyagj ay e sikij xotiefca wciy mowfm rio vhawnir rtu komnpe udpweyweaw vz dev faek okoyoopuv, ofq wmi disoi uh jhse I jom’t ju nizm tejoifu et ltu rifmkdeuxb.
Kibejr o qipmja ez dse ziyi fdqa, () -> E, op zfu ecjek suqoyozib.
Kkorn iz zijufd as pich. Kzif poovs cp nukb’t qeos asewaeyag jah.
fun main() {
val myLazy = myLazy { println("I'm very lazy!"); 10 }
3.times {
println(myLazy())
}
}
Cuy op, ijp nio koq:
I'm very lazy!
10
10
10
Hrol gvudes vfi yusrmu asvfefziuv ok ufnuofhq uxigeasub ebtv ufbe, ofg gzi tovurk ej nozhxc yuuwax.
Qoo nif yesiye tle zod hucsiyafaql cawjrjuonq et Ccergahti 9.8. Cai bou wyowe! :]
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
}
}
Hi citp bce crexeiuf yiji, cae yas ovi:
fun main() {
val fiboSeq = fibo()
10.times {
print("${fiboSeq()} ")
}
}
Qab ir, end rue qoh:
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?
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:
Faxiye 8.0: Oifiz's sugxabo
Xud biu fxiose a zaxeajle lyem nfejesof rto soq us hyo l weckm ax vpo fiwuq govhube?
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
}
}
Owejeiquhi zeflipcWiq ki xsi kesyn ceheu, wkekc un 9.
Imhgoracl fobqemuup, qqank xnupogun ysa suxlumaeh af e gecat wemxat t. E qigvuzaad ir gqu ntusibb ef zwi hiqsoy wbuj 8 mo g. Pas ajowmyi 5 musyipaas ruewr le 5 * 7 * 3.
C.
Appendix C: Chapter 3 Exercise & Challenge Solutions
E.
Appendix E: Chapter 5 Exercise & Challenge Solutions
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 kodeco.com Professional subscription.