Types of parameters in functions that accept functions - scala

I am trying to learn Scala using SICP, but I am having a hard time with type definitions of functions and got stuck at SICP. Here a generalized expression is build to find the square root of a number (through fixed-point search or Newton's method) where instead of:
def sqrt_damp(x: Double) =
fixed_point(average_damp(y => x / y))(1)
def sqrt_newton(x: Double) =
fixed_point(newton_method(y => square(y) - x))(1)
Based on the functions:
def square(x: Double) = x * x
def average(x: Double, y: Double) = (x + y) / 2
def abs(x: Double) = if (x < 0) -x else x
val tolerance = 0.00001
def fixed_point(f: Double => Double)(first_guess: Double) = {
def close_enough(v1: Double, v2: Double): Boolean = abs(v1 - v2) < tolerance
def attempt(guess: Double): Double = {
val next = f(guess)
if (close_enough(guess, next)) next else attempt(next)
}
attempt(first_guess)
}
def average_damp(f: Double => Double): Double => Double =
x => average(x, f(x))
val dx = 0.00001
def deriv(g: Double => Double): Double => Double =
x => (g(x + dx) - g(x)) / dx
def newton_transform(g: Double => Double): Double => Double =
x => x - g(x) / deriv(g)(x)
def newton_method(g: Double => Double)(guess: Double): Double =
fixed_point(newton_transform(g))(guess)
The square functions can be generalized in the form:
(define (fixed-point-of-transform g transform guess)
(fixed-point (transform g) guess))
Which I attempted to express as follows in Scala:
def fixed_point_of_transform(g: Double => Double, transform: Double => Double)(guess: Double): Double =
fixed_point(transform(g))(guess)
Yet the above does not compile and generates the error
type mismatch; found : Double => Double required: Double
Edit, the following works:
def fixed_point_of_transform(g: Double => Double, transform: (Double => Double) => (Double => Double))(guess: Double): Double =
fixed_point(transform(g))(guess)
So now the previous functions can be defined as:
def sqrt_damp(x: Double) =
fixed_point_of_transform(y => x / y, average_damp)(1)
def sqrt_newton(x: Double) =
fixed_point_of_transform(y => square(y) - x, newton_method)(1)

transform takes a Double and returns a Double. You cannot apply it to g, because g is a a function Double => Double. You can apply it to g(x), where x: Double. I think this is what you want: fixed_point((x: Double) => transform(g(x)))(guess)

Related

How to declare in scala a default param in a method of an implicit class

In order to use infix notation, I have the following example of scala code.
implicit class myclass(n:Int ){
private def mapCombineReduce(map : Int => Double, combine: (Double,Double) => Double, zero: Double )(a:Int, b:Double): Double =
if( a > b) zero else combine ( map(a), mapCombineReduce(map,combine,zero)(a+1,b) )
var default_value_of_z : Int = 0
def sum( z : Int = default_value_of_z) = mapReduce( x=>x , (x,y) => x+y+z, 0)(1,n)
def ! = mapCombineReduce( x=> x, (x,y) => x*y, 1)(1,n)
}
4 !
4 sum 1 //sum the elements from 1 to 7 and each time combine the result, add 1 to the result.
4 sum
Is there any way in scala 2.12 to run 4 sum without have a double declaration of the sum method inside myclass ?
No, because default arguments are only used if argument list is provided
def f(x: Int = 1) = x
f // interpreted as trying to do eta-expansion
In fact starting Scala 3 it will indeed eta-expand
scala> def f(x: Int = 1) = x
def f(x: Int): Int
scala> f
val res1: Int => Int = Lambda$7473/1229666909#61a1990e
so in your case you will have to write 4.sum() with argument list present.

Calculating Square Root recursively in Scala

The following code works but I don't quite understand how the arguments are mapped to the parameter lists. Please be aware Im new to Scala.
import Math.abs
val tolerance = 0.0001
def isCloseEnough(x: Double, y: Double) =
abs((x - y) / x) / x < tolerance
def fixedPoint(f: Double => Double)(firstGuess: Double) = {
def iterate(guess: Double): Double = {
val next = f(guess)
if (isCloseEnough(guess, next)) next
else iterate(next)
}
iterate(firstGuess)
}
def averageDamp(f: Double => Double)(x: Double) = (x + f(x)) / 2
def sqrt(x: Double) =
fixedPoint(averageDamp(y => x / y))(1.0)
sqrt(2.0)
The body of the sqrt function above is fixedPoint(averageDamp(y => x / y))(1.0)
where
(y => x / y) maps to (f: Double => Double) of the averageDamp function and
(1.0) maps to (firstGuess: Double) of the fixedPoint function but
looks like nothing maps to (x: Double) of the averageDamp function.
Thank you in advance.
This is called currying. What's really happening is that averageDamp(y => x / y) is being interpreted as a function: Double => Double, because once you set the first parameter list to a particular set of values, you obtain a function that takes the second parameter list.
For example, consider the following code:
def multiply(x: Double)(y: Double) = x * y
val multiplyByFive: Double => Double = multiply(5)
println(multiplyByFive(2)) // 10
println(multiplyByFive(6)) // 30
As you see, the fact of applying multiply with only one parameter list out of two creates a new function of the second parameter list (here (y: Double)) that has a fixed set of values for the first parameter list (here (5)).
Another equivalent way to write this, which perhaps will be more explicit for you, is the following :
val multiplyByFive: Double => Double = multiply(5)(_)
Here we explicitly apply the function with two parameters lists, but using a wildcard for the second, which is a way to tell to the compiler to create a function that replaces the underscore by a parameter of the function.

when testing for convergence using successive approximation technique, why does this code divide by the guess twice?

While working through the coursera class on scala I ran into the code below (from another question asked here by Sudipta Deb.)
package src.com.sudipta.week2.coursera
import scala.math.abs
import scala.annotation.tailrec
object FixedPoint {
println("Welcome to the Scala worksheet") //> Welcome to the Scala worksheet
val tolerance = 0.0001 //> tolerance : Double = 1.0E-4
def isCloseEnough(x: Double, y: Double): Boolean = {
abs((x - y) / x) / x < tolerance
} //> isCloseEnough: (x: Double, y: Double)Boolean
def fixedPoint(f: Double => Double)(firstGuess: Double): Double = {
#tailrec
def iterate(guess: Double): Double = {
val next = f(guess)
if (isCloseEnough(guess, next)) next
else iterate(next)
}
iterate(firstGuess)
} //> fixedPoint: (f: Double => Double)(firstGuess: Double)Double
def myFixedPoint = fixedPoint(x => 1 + x / 2)(1)//> myFixedPoint: => Double
myFixedPoint //> res0: Double = 1.999755859375
def squareRoot(x: Double) = fixedPoint(y => (y + x / y) / 2)(1)
//> squareRoot: (x: Double)Double
squareRoot(2) //> res1: Double = 1.4142135623746899
def calculateAverate(f: Double => Double)(x: Double) = (x + f(x)) / 2
//> calculateAverate: (f: Double => Double)(x: Double)Double
def myNewSquareRoot(x: Double): Double = fixedPoint(calculateAverate(y => x / y))(1)
//> myNewSquareRoot: (x: Double)Double
myNewSquareRoot(2) //> res2: Double = 1.4142135623746899
}
My puzzlement concerns the isCloseEnough function.
I understand that for guesses which are large numbers, the difference between a guess and
the large value that the function returns could potentially be very big all the time, so we may never converge.
Conversely, if the guess is small, and if what f(x) produces is small then we will likely converge too quickly.
So dividing through by the guess like this:
def isCloseEnough(x: Double, y: Double): Boolean = {
abs((x - y) / x) / x < tolerance
}
makes perfect sense. (here is 'x' is the guess, and y is f_of_x.)
My question is why do why does the solution given divide by the guess TWICE ?
Wouldn't that undo all the benefits of dividing through by the guess the first time ?
As an example... let's say that my current guess and the value actually returned by the
function given my current x is as shown below:
import math.abs
var guess=.0000008f
var f_of_x=.00000079999f
And lets' say my tolerance is
var tolerance=.0001
These numbers look pretty close, and indeed, if i divide through by x ONCE, i see that the result
is less than my tolerance.
( abs(guess - f_of_x) / guess)
res3: Float = 1.2505552E-5
However, if i divide through by x TWICE the result is much greater than my tolerance, which would suggest
we need to keep iterating.. which seems wrong since guess and observed f(x) are so close.
scala> ( abs(guess - f_of_x) / guess) / guess
res11: Float = 15.632331
Thanks in advance for any help you can provide.
You are completely right, it does not make sense. Further, the second division is outside of the absolute value rendering the inequality true for any negative x.
Perhaps someone got confused with testing for quadratic convergence.

Function parameters evaluation in Scala (functional programming)

please find below a piece of code from Coursera online course (lecture 2.3) on functional programming in Scala.
package week2
import math.abs
object lecture2_3_next {
def fixedPoint(f: Double => Double)(firstGuess: Double): Double = {
val tolerance = 0.0001
def isCloseEnough(x: Double, y: Double): Boolean = abs((x - y) / x) / x < tolerance
def iterate(guess: Double): Double = {
val next = f(guess)
if (isCloseEnough(guess, next)) next
else iterate(next)
}
iterate(firstGuess)
}
def averageDamp(f: Double => Double)(x: Double): Double = (x + f(x)) / 2
def sqrt(x: Double): Double = fixedPoint(averageDamp(y => x / y))(1)
sqrt(2)
}
A few points blocked me while I'm trying to understand this piece of code.
I'd like your help to understanding this code.
The 2 points that annoying me are :
- when you call averageDamp, there are 2 parameters 'x' and 'y' in the function passed (eg. averageDamp(y => x / y)) but you never specify the 'y' parameter in the definition of the averageDamp function (eg. def averageDamp(f: Double => Double)(x: Double): Double = (x + f(x)) / 2). Where and how do the scala compiler evaluate the 'y' parameter.
- second point may be related to the first, I don't know in fact. When I call the averageDamp function, I pass only the function 'f' parameter (eg. y => x / y) but I don't pass the second parameter of the function which is 'x' (eg. (x: Double) second parameter). How the scala compiler is evaluating the 'x' parameter in this case to render the result of the averageDamp call.
I think I missed something about the evaluation or substitution model of scala and functional programming.
Thank's for your help and happy new year !
Hervé
1) You don't pass an x and an y parameter as f, you pass a function. The function is defined as y => x / y, where y is just a placeholder for the argument of this function, while x is a fixed value in this context, as it is given as argument for the sqrt method (in the example x is 2). Instead of the fancy lambda-syntax, you could write as well
def sqrt(x: Double): Double = fixedPoint(averageDamp(
new Function1[Double,Double] {
def apply(y:Double):Double = x / y
}
))(1)
Nothing magic about this, just an abbreviation.
2) When you have a second parameter list, and don't use it when calling the method, you do something called "currying", and you get back a partial function. Consider
def add(x:Int)(y:Int) = x + y
If you call it as add(2)(3), everything is "normal", and you get back 5. But if you call add(2), the second argument is still "missing", and you get back a function expecting this missing second argument, so you have something like y => 2 + y
The x is not a parameter of the (anonymous) function, it is a parameter of the function sqrt. For the anonymous function it is a bound closure.
To make it more obvious, let's rewrite it and use a named instead of an anonymous function:
def sqrt(x: Double): Double = fixedPoint(averageDamp(y => x / y))(1)
will can be rewritten as this:
def sqrt(x: Double): Double = {
def funcForSqrt(y: Double) : Double = x / y // Note that x is not a parameter of funcForSqrt
// Use the function fundForSqrt as a parameter of averageDamp
fixedPoint(averageDamp(funcForSqrt))(1)
}

Why is this function called multiple times?

In this function "f" :
def f(x: => Int) : Int = x * x * x //> f: (x: => Int)Int
var y = 0 //> y : Int = 0
f {
y += 1
println("invoked")
y
} //> invoked
//| invoked
//| invoked
//| res0: Int = 6
"f" is invoked same amount of times as "x" parameter is multiplied.
But why is function invoked multiple times ?
Should "f" not expand to 1 * 1 * 1 not 1 * 2 * 3 ?
Your x is not a function, it is a by-name parameter, and its type is a parameterless method type.
Parameterless method type means the same as def x, something that is evaluated every time you reference it. By reference, we mean x and not x.apply() or x().
The expression you're passing to your function f is evaluated every time x is referenced in f. That expression is the whole thing in braces, a block expression. A block is a sequence of statements followed by the result expression at the end.
Here's another explanation: https://stackoverflow.com/a/13337382/1296806
But let's not call it a function, even if it behaves like one under the covers.
Here is the language used in the spec:
http://www.scala-lang.org/files/archive/spec/2.11/04-basic-declarations-and-definitions.html#by-name-parameters
It's not a value type because you can't write val i: => Int.
It was a big deal when they changed the implementation so you could pass a by-name arg to another method without evaluating it first. There was never a question that you can pass function values around like that. For example:
scala> def k(y: => Int) = 8
k: (y: => Int)Int
scala> def f(x: => Int) = k(x) // this used to evaluate x
f: (x: => Int)Int
scala> f { println("hi") ; 42 }
res8: Int = 8
An exception was made to "preserve the by-name behavior" of the incoming x.
This mattered to people because of eta expansion:
scala> def k(y: => Int)(z: Int) = y + y + z
k: (y: => Int)(z: Int)Int
scala> def f(x: => Int) = k(x)(_) // normally, evaluate what you can now
f: (x: => Int)Int => Int
scala> val g = f { println("hi") ; 42 }
g: Int => Int = <function1>
scala> g(6)
hi
hi
res11: Int = 90
The question is how many greetings do you expect?
More quirks:
scala> def f(x: => Int) = (1 to 5) foreach (_ => x)
f: (x: => Int)Unit
scala> def g(x: () => Int) = (1 to 5) foreach (_ => x())
g: (x: () => Int)Unit
scala> var y = 0
y: Int = 0
scala> y = 0 ; f { y += 1 ; println("hi") ; y }
hi
hi
hi
hi
hi
y: Int = 5
scala> y = 0 ; g { y += 1 ; println("hi") ; () => y }
hi
y: Int = 1
scala> y = 0 ; g { () => y += 1 ; println("hi") ; y }
hi
hi
hi
hi
hi
y: Int = 5
Functions don't cause this problem:
scala> object X { def f(i: Int) = i ; def f(i: => Int) = i+1 }
defined object X
scala> X.f(0)
res12: Int = 0
scala> trait Y { def f(i: Int) = i }
defined trait Y
scala> object X extends Y { def f(i: => Int) = i+1 }
defined object X
scala> X.f(0)
<console>:11: error: ambiguous reference to overloaded definition,
both method f in object X of type (i: => Int)Int
and method f in trait Y of type (i: Int)Int
match argument types (Int)
X.f(0)
^
Compare method types:
http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#method-types
This is not a pedantic distinction; irrespective of the current implementation, it can be confusing to think of a by-name parameter as "really" a function.
Another way of saying what has already been said is that inside f you invoke the function x three times. The first time it increments the y var and returns 1. The second time it again increments y returning 2 and the third time it again increments y and returns 3.
If you want it invoked only once then you may want to do something like this:
def f(x: => Int) : Int = x * x * x
var y = 0
lazy val xx = {
y += 1
println("invoked")
y
}
f {xx}
This will print 'invoked' only once and result in a returned value of 1.
x: T means need a T value.
x: => T means need a T value, but it is call by name.
x: () => T This means need a function given nothing to T
However, this question is not related to the difference between function and method.
The reason is call by name is invoked every time you try to use it.
change to call by value def f(x: Int) : Int, it will only invoke once.
Because you increment y by 1 every time the argument is used inside f
The result which your function f() returns is changing, because there is a global variable that is incremented with every subsequent call to that function.
the x in f(x: => Int) is interpreted as "some function that returns Int". So it has to be called 3 times to evaluate the x*x*x expression. With every call, you increment the global variable and return the result, which is how you arrive at three subsequent natural numbers (because the global variable is initialized to 0). Hence 1*2*3.