mikezx6r (11) [Avatar] Offline
#1
Just started reading chapter 3 and already enjoying it.

In 3.10, the example shows applying add as `add.(3)(5)`, but this isn't compiling with 1.2.30. Using `add(3)(5)` executes as expected.

Typo or change in Kotlin?

Then in Exercise 3.4, you have:

val squareOfTriple = compose(square)(triple)

Missing the `::` in front of square and triple references
Pierre-Yves Saumont (147) [Avatar] Offline
#2
Hi,

In 3.10, the example shows applying add as `add.(3)(5)`, but this isn't compiling with 1.2.30. Using `add(3)(5)` executes as expected.


Thank you for spotting this typo! (For other readers, please note that this is exercise 3.3, not 3.10)

Regarding exercise 3.4, I guess you did some changes to the example. The original code is:

val compose: (IntUnaryOp) -> (IntUnaryOp) -> IntUnaryOp =
        { x -> { y -> { z -> x(y(z)) } } }

val square: IntUnaryOp = { it * it}

val triple: IntUnaryOp = { it * 3}

val squareOfTriple = compose(square)(triple)


There are no function references here. square and triple are val functions, meaning they are objects of type IntUnaryOp, an alias for (Int) -> Int, which is a function type. Perhaps you changed the code to something like:

val compose: (IntUnaryOp) -> (IntUnaryOp) -> IntUnaryOp =
        { x -> { y -> { z -> x(y(z)) } } }

fun square(i: Int): Int = i * i

fun triple(i: Int): Int = i * 3

val squareOfTriple = compose(::square)(::triple)


Here, square and triple are not objects, but fun functions, which is why you need to prefix their names with :: to create function references that you can use as parameters for higher order functions.

It is very important to understand the difference between these two types of functions. The :: notation allows converting from fun functions to valfunctions, as in:

fun square(it: Int): Int = it * it
fun triple(it: Int): Int = it * 3

val square: (Int) -> Int = ::square
val triple: (Int) -> Int = ::triple


The inverse (converting from val functions to fun function) is also easy:

val square: (Int) -> Int = { it * it}
val triple: (Int) -> Int = { it * 3}

fun square(i: Int): Int = square(i)
fun triple(i: Int): Int = triple(i)
mikezx6r (11) [Avatar] Offline
#3
For the method reference vs value function.

You are correct. I made the mistake of using only 1 file for chapter 3, and missed that for Exercise 3.4, square and double were re-implemented as value functions.

As a result I only had the function version, hence me having a compile issue.

Again, thank you for the great book, and the fast feedback!