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

`val`functions, 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)