Explanation needed scala fixedpoint from coursera - scala

I was going through videos of Functional Programming in Scala taught in coursera. I came across these code
def averageDamp(f: Double => Double)(x: Double) = (x + f(x)) / 2
and its implementation as
def sqrt(x: Double): Double = fixedPoint(averageDamp(y => y / x))(1)
but couldn't use it in the form
averageDamp(x => x)
It says that argument is missing. Isn't the argument missing in above case as well. Somebody help. Thanks in advance :)

The keyword for this is currying. When averageDamp defined as above, averageDamp will expect two parameters. When you write it with only first paramater it will return a functional (closure) which takes another argument. Thats why it says argument is missing when you call it like averageDamp(x => x). You just calling a function without parameter which expects one. To actually evaluate the value you should call it like averageDamp(some_function)(double_value).
Checkout this: http://www.codecommit.com/blog/scala/function-currying-in-scala

Related

What does an underscore after a scala method call mean?

The scala documentation has a code example that includes the following line:
val numberFunc = numbers.foldLeft(List[Int]())_
What does the underscore after the method call mean?
It's a partially applied function. You only provide the first parameter to foldLeft (the initial value), but you don't provide the second one; you postpone it for later. In the docs you linked they do it in the next line, where they define squares:
val numberFunc = numbers.foldLeft(List[Int]())_
val squares = numberFunc((xs, x) => xs:+ x*x)
See that (xs, x) => xs:+ x*x, that's the missing second parameter which you omitted while defining numberFunc. If you had provided it right away, then numberFunc would not be a function - it would be the computed value.
So basically the whole thing can also be written as a one-liner in the curried form:
val squares = numbers.foldLeft(List[Int]())((xs, x) => xs:+ x*x)
However, if you want to be able to reuse foldLeft over and over again, having the same collection and initial value, but providing a different function every time, then it's very convinient to define a separate numbersFunc (as they did in the docs) and reuse it with different functions, e.g.:
val squares = numberFunc((xs, x) => xs:+ x*x)
val cubes = numberFunc((xs, x) => xs:+ x*x*x)
...
Note that the compiler error message is pretty straightforward in case you forget the underscore:
Error: missing argument list for method foldLeft in trait
LinearSeqOptimized Unapplied methods are only converted to functions
when a function type is expected. You can make this conversion
explicit by writing foldLeft _ or foldLeft(_)(_) instead of
foldLeft. val numberFunc = numbers.foldLeft(ListInt)
EDIT: Haha I just realized that they did the exact same thing with cubes in the documentation.
I don't know if it helps but I prefer this syntax
val numberFunc = numbers.foldLeft(List[Int]())(_)
then numberFunc is basically a delegate corresponding to an instance method (instance being numbers) waiting for a parameter. Which later comes to be a lambda expression in the scala documentation example

Why is scala.collection.immutable.List[Object] not GenTraversableOnce[?]

Simple question, and sorry if this is a stupid question as I am just beginning in scala. I am getting a type mismatch error that says:
found : (AnyRef, org.apache.tinkerpop.gremlin.hadoop.structure.io.VertexWritable) => List[Object]
required: ((AnyRef, org.apache.tinkerpop.gremlin.hadoop.structure.io.VertexWritable)) => scala.collection.GenTraversableOnce[?]
But according to this post (I have a Scala List, how can I get a TraversableOnce?), a scala.collection.immutable.List is an Iterable and therefore also a GenTraversableOnce. And yet this error seems to indicate otherwise. And furthermore, when I actually look at the link in the accepted answer of that post, I don't see any reference to the word "traversable".
If the problem has to do with my inner class not being correct, then I have to say this error is extremely uninformative, since requiring that the inner class be of type "?" is obviously a vacuous statement ... Any help in understanding this would be appreciated.
Function2[X, Y, Z] is not the same thing as Function1[(X, Y), Z].
Compare these two definitions:
val f: ((Int, Int)) => Int = xy => xy._1 + xy._2
val f: (Int, Int) => Int = (x, y) => x + y
The first could also be written with a pattern-matching, that first decomposes the tuple:
val f: ((Int, Int)) => Int = { case (x, y) => x + y }
This is exactly what the error message asks you to do: provide an unary function that takes a tuple as argument, not a binary function. Note that there is the tupled-method, that does exactly that.
The return types of the functions are mostly irrelevant here, the compiler doesn't get to unify them, because it fails on the types of the inputs.
Also related:
Same story with eta-expansions: Why does my implementation of Haskell snd not compile in Scala

Is scala disregading type in function signatures?

I am going through lectures from excellent Martin Odersky's FP course and one of the lectures demonstrates higher-order functions through Newton's method for finding fixed points of certain functions. There is a cruicial step in the lecture where I think type signature is being violated so I would ask for an explanation. (Apologies for the long intro that's inbound - it felt it was needed.)
One way of implementing such an algorithm is given like this:
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)
}
Next, we try to compute the square root via fixedPoint function, but the naive attempt through
def sqrt(x: Double) = fixedPoint(y => x / y)(1)
is foiled because such an approach oscillates (so, for sqrt(2), the result would alternate indefinitely between 1.0 and 2.0).
To deal with that, we introduce average damping, so that essentially we compute the mean of two nearest calculated values and converge to solution, therefore
def sqrt(x: Double) = fixedPoint(y => (y + x / y) / 2)(1)
Finally, we introduce averageDamp function and the task is to write sqrt with fixedPoint and averageDamp. The averageDamp is defined as follows:
def averageDamp(f: Double => Double)(x: Double) = (x + f(x)) / 2
Here comes the part I don't understand - my initial solution was this:
def sqrt(x: Double) = fixedPoint(z => averageDamp(y => x / y)(z))(1)
but prof. Odersky's solution was more concise:
def sqrt(x: Double) = fixedPoint(averageDamp(y => x / y))(1)
My question is - why does it work? According to function signature, the fixedPoint function is supposed to take a function (Double => Double) but it doesn't mind being passed an ordinary Double (which is what averageDamp returns - in fact, if you try to explicitly specify the return type of Double to averageDamp, the compiler won't throw an error).
I think that my approach follows types correctly - so what am I missing here? Where is it specified or implied(?) that averageDamp returns a function, especially given the right-hand side is clearly returning a scalar? How can you pass a scalar to a function that clearly expects functions only? How do you reason about code that seems to not honour type signatures?
Your solution is correct, but it can be more concise.
Let's scrutinize the averageDamp function more closely.
def averageDamp(f: Double => Double)(x: Double): Double = (x + f(x)) / 2
The return type annotation is added to make it more clearly. I think what you are missing is here:
but it doesn't mind being passed an ordinary Double (which is what averageDamp returns - in fact, if you try to explicitly specify the
return type of Double to averageDamp, the compiler won't throw an
error).
But averageDamp(y => y/x) does return a Double => Double function! averageDamp requires to be passed TWO argument lists to return a Double.
If the function receive just one argument, it still wants the other one to be completed. So rather than returning the result immediately, it returns a function, saying that "I still need an argument here, feed me that so I will return what you want".
Prof MO did pass ONE function argument to it, not two, so averageDamp is partially applied, in the sense that it returns a Double => Double function.
The course will also tell you functions with multiple argument lists are syntactical sugar form of this:
def f(arg1)(arg2)(arg3)...(argN-1)(argN) = (argN) => f(arg1)(arg2)(arg3)...(argN-1)
If you give one less argument than f needs, it just return the right side of equation, that is, a function. So, heeding that averageDamp(y => x / y), the argument passed to fixPoint, is actually a function should help you understand the question.
Notice: There is some difference between partially applied function(or function currying) and multiple argument list function
For example you cannot declare like this
val a = averageDamp(y => y/2)
The compiler will complain about this as 'method is not a partially applied function'.
The difference is explained here: What's the difference between multiple parameters lists and multiple parameters per list in Scala?.
Multiple parameter lists are syntactic sugar for a function that returns another function. You can see this in the scala shell:
scala> :t averageDamp _
(Double => Double) => (Double => Double)
We can write the same function without the syntactic sugar - this is the way we'd do it in e.g. Python:
def averageDamp(f: Double => Double): (Double => Double) = {
def g(x: Double): Double = (x + f(x)) / 2
g
}
Returning a function can look a bit weird to start with, but it's complementary to passing a function as an argument and enables some very powerful programming techniques. Functions are just another type of value, like Int or String.
In your original solution you were reusing the variable name y, which I think makes it slightly confusing; we can translate what you've written into:
def sqrt(x: Double) = fixedPoint(z => averageDamp(y => x / y)(z))(1)
With this form, you can hopefully see the pattern:
def sqrt(x: Double) = fixedPoint(z => something(z))(1)
And hopefully it's now obvious that this is the same as:
def sqrt(x: Double) = fixedPoint(something)(1)
which is Odersky's version.

Currying in scala

w.r.t Currying in scala, partly I understood below sample code.
def product1(f:Int => Int )(a:Int, b:Int):Int = {
println()
if(a > b ) 1
else
f(a) * product1(f)(a+1, b)
}
product(x => x * x) (3, 4)
Out of it., I am bit confused with
product1(f)
in
product1(f)(a+1, b)
Just need explanation, what goes on here.... :( and how to pronounce verbally while explaining...
Thanks in advance..
product1 has two parameter lists. product1(f) is the application of f which is a function of kind Int => Int. If you were only to call product1(f) like so:
product1(f)
without the second parameter list, you'd get a so-called partially-applied function, i.e. a function which doesn't have all of its parameters bound (you'd still need to provide it with a and b)
Look at the parameter declaration:
f:Int => Int
f is a function that maps an Int to an Int -- it takes an Int as an argument and returns an Int. An example is given:
x => x * x
returns the square of its argument.
product1(x => x * x) (3, 4)
returns the product of f(3) .. f(4) = 3*3 * 4*4
BTW, this isn't really an example of currying, since all the arguments are given. Currying would be something like
val prodSquare = product1(x => x * x)
Then,
prodSquare(1, 5)
yields 1*1 * 2*2 * 3*3 * 4*4 * 5*5
For most idiomatic purposes I've seen, you may as well think of your function as having just one parameter list. Multiple parameter lists are used mostly for type inference purposes in generic functions, since type inference is done one parameter list at a time, rather than using Hindley-Milner/Algorithm W to infer the type of everything at once. Some other language features work on individual parameter lists, such as implicit parameters and implicit use of braces in place of parentheses for single-parameter parameter lists, etc.
Functions with multiple parameter lists are called in a similar way to a curried functions from a syntactic perspective, but by default, the intermediate functions aren't created. In fully curried style, each function takes only at most one argument and returns one result (which might happen to be another function, which expects on argument, and so forth). Technically, currying the function would be:
def product2(f: Int => Int): Int => Int => Int = {
a: Int => {
b: Int => {
if(a > b ) 1
else f(a) * product2(f)(a+1)(b)
}
}
}
For completeness, you can treat a function with multiple parameter lists as a curried function by using an underscore after a complete parameter list. In your original example, you'd do product1(f)_, which would return a function of type (Int, Int) => Int.
In researching this question, I came upon another SO question worth checking out to understand this aspect of the language better.

Scala underscore minimal function

Let's create a value for the sake of this question:
val a = 1 :: Nil
now, I can demonstrate that the anonymous functions can be written in shorthand form like this:
a.map(_*2)
is it possible to write a shorthand of this function?:
a.map((x) => x)
my solution doesn't work:
a.map(_)
For the record, a.map(_) does not work because it stands for x => a.map(x), and not a.map(x => x). This happens because a single _ in place of a parameter stands for a partially applied function. In the case of 2*_, that stands for an anonymous function. These two uses are so close that is very common to get confused by them.
Your first shorthand form can also be written point-free
a map (2*)
Thanks to multiplication being commutative.
As for (x) => x, you want the identity function. This is defined in Predef and is generic, so you can be sure that it's type-safe.
You should use identity function for this use case.
a.map(identity)
identity is defined in scala.Predef as:
implicit def identity[A](x: A): A = x