Scala Assert Testing Expectations - scala

I am creating some tests in Scala and am trying to better understand some behavior I am seeing.
When I write my method as so, with a return Type, my test passes.
def cube(x: Int): Int ={
x * x * x
}
test("CubeTest") {
assert(CubeCalculator.cube(3) === 27)
}
However, when I do not specify the return type the test fails:
def cube(x: Int){
x * x * x
}
I was under the impression that The Scala compiler can infer return types for methods so why do I need to state it for the test to pass?

Omitting the return type isn't the problem with your code, it's omitting the = sign.
def cube(x: Int){
x * x * x
}
Is equivalent to:
def cube(x: Int): Unit = {
x * x * x
}
Since a Unit cannot possibly be an Int, the comparison in your test cannot pass; presumably the === is a "typesafe equality operator" which prevents impossible comparisons like this from compiling.
This syntax for defining Unit-resulting methods is dropped in Scala 3.
It's worth noting what exactly this procedure does:
It calculates x * x * x
It throws away that result and returns the singleton value of Unit: ()
This throwing away of the result is at the very least wasteful; there's a compiler option which makes such discarding of a value a warning: -Ywarn-discard. With this option in force, you would have to write
def cube(x: Int) {
x * x * x
()
}
Which at least makes it clear that you want x * x * x computed and thrown away.
def cube(x: Int) = x * x * x
Should have an inferred result type of Int. That said, using an explicit return type on (at least) externally visible non-constant methods may serve a useful documentation function, improve compiler speed, and prevent situations where you think you're returning one type but are actually returning another.

Related

why does eclipse complain "recursive method loop needs result type"?

I am editing following code in eclipse but it complains that "recursive method loop needs result type", so what's the error? Thanks.
package week2
object exercise {
def factorial(n: Int): Int = {
def loop(acc: Int, n: Int) =
if (n == 0) acc
else loop(acc * n, n - 1)
loop(1, n)
}
factorial(4)
}
Thanks for the answer. Yes, I missed something here. The correct is:
package week2
object exercise {
def factorial(n: Int): Int = {
def loop(acc: Int, n: Int): Int =
if (n == 0) acc
else loop(acc * n, n - 1)
loop(1, n)
} //> factorial: (n: Int)Int
factorial(4) //> res0: Int = 24
}
As sepp2k indicated, it's restricted by compiler. Just wanted to add more info for clarification.
According to Scala's local type inference mechanism
return types of methods can often be omitted since they correspond to the type of the body, which gets inferred by the compiler
Consider non-recursive function
def f(n: Int) = n % 2 == 0
where compiler can infer a result type, since it knows that expression x % 2 == 0 will always produce type Boolean.
But when you deal with a recursive function, like
def f(n: Int) = if (n == 0) 1 else n * f(n-1)
Scala compiler won't infer the result type of if (x == 0) 1 else x * f(x-1) since that leads to an infinite loop. It can't even know that f(x-1) is an eligible operand for * operation, thus will give you an error Cannot resolve reference * with such signature.
The rules of the Scala language that any recursive method needs to be declared with a return type. loop is a recursive method and you didn't declare a return type for it (you only declared one for factorial, which doesn't necessarily need one). Therefore scalac (and by extension Eclipse) is telling you that the recursive method loop needs a return type.

How to define a function as generic across all numbers in scala?

I thought I needed to parameterise my function across all Ordering[_] types. But that doesn't work.
How can I make the following function work for all types that support the required mathematical operations, and how could I have found that out by myself?
/**
* Given a list of positive values and a candidate value, round the candidate value
* to the nearest value in the list of buckets.
*
* #param buckets
* #param candidate
* #return
*/
def bucketise(buckets: Seq[Int], candidate: Int): Int = {
// x <= y
buckets.foldLeft(buckets.head) { (x, y) =>
val midPoint = (x + y) / 2f
if (candidate < midPoint) x else y
}
}
I tried command clicking on the mathematical operators (/, +) in intellij, but just got a notice Sc synthetic function.
If you want to use just the scala standard library, look at Numeric[T]. In your case, since you want to do a non-integer division, you would have to use the Fractional[T] subclass of Numeric.
Here is how the code would look using scala standard library typeclasses. Note that Fractional extends from Ordered. This is convenient in this case, but it is also not mathematically generic. E.g. you can't define a Fractional[T] for Complex because it is not ordered.
def bucketiseScala[T: Fractional](buckets: Seq[T], candidate: T): T = {
// so we can use integral operators such as + and /
import Fractional.Implicits._
// so we can use ordering operators such as <. We do have a Ordering[T]
// typeclass instance because Fractional extends Ordered
import Ordering.Implicits._
// integral does not provide a simple way to create an integral from an
// integer, so this ugly hack
val two = (implicitly[Fractional[T]].one + implicitly[Fractional[T]].one)
buckets.foldLeft(buckets.head) { (x, y) =>
val midPoint = (x + y) / two
if (candidate < midPoint) x else y
}
}
However, for serious generic numerical computations I would suggest taking a look at spire. It provides a much more elaborate hierarchy of numerical typeclasses. Spire typeclasses are also specialized and therefore often as fast as working directly with primitives.
Here is how to use example would look using spire:
// imports all operator syntax as well as standard typeclass instances
import spire.implicits._
// we need to provide Order explicitly, since not all fields have an order.
// E.g. you can define a Field[Complex] even though complex numbers do not
// have an order.
def bucketiseSpire[T: Field: Order](buckets: Seq[T], candidate: T): T = {
// spire provides a way to get the typeclass instance using the type
// (standard practice in all libraries that use typeclasses extensively)
// the line below is equivalent to implicitly[Field[T]].fromInt(2)
// it also provides a simple way to convert from an integer
// operators are all enabled using the spire.implicits._ import
val two = Field[T].fromInt(2)
buckets.foldLeft(buckets.head) { (x, y) =>
val midPoint = (x + y) / two
if (candidate < midPoint) x else y
}
}
Spire even provides automatic conversion from integers to T if there exists a Field[T], so you could even write the example like this (almost identical to the non-generic version). However, I think the example above is easier to understand.
// this is how it would look when using all advanced features of spire
def bucketiseSpireShort[T: Field: Order](buckets: Seq[T], candidate: T): T = {
buckets.foldLeft(buckets.head) { (x, y) =>
val midPoint = (x + y) / 2
if (candidate < midPoint) x else y
}
}
Update: spire is very powerful and generic, but can also be somewhat confusing to a beginner. Especially when things don't work. Here is an excellent blog post explaining the basic approach and some of the issues.

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)
}

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.

How does one write the Pythagoras Theorem in Scala?

The square of the hypotenuse of a right triangle is equal to the sum of the squares on the other two sides.
This is Pythagoras's Theorem. A function to calculate the hypotenuse based on the length "a" and "b" of it's sides would return sqrt(a * a + b * b).
The question is, how would you define such a function in Scala in such a way that it could be used with any type implementing the appropriate methods?
For context, imagine a whole library of math theorems you want to use with Int, Double, Int-Rational, Double-Rational, BigInt or BigInt-Rational types depending on what you are doing, and the speed, precision, accuracy and range requirements.
This only works on Scala 2.8, but it does work:
scala> def pythagoras[T](a: T, b: T, sqrt: T => T)(implicit n: Numeric[T]) = {
| import n.mkNumericOps
| sqrt(a*a + b*b)
| }
pythagoras: [T](a: T,b: T,sqrt: (T) => T)(implicit n: Numeric[T])T
scala> def intSqrt(n: Int) = Math.sqrt(n).toInt
intSqrt: (n: Int)Int
scala> pythagoras(3,4, intSqrt)
res0: Int = 5
More generally speaking, the trait Numeric is effectively a reference on how to solve this type of problem. See also Ordering.
The most obvious way:
type Num = {
def +(a: Num): Num
def *(a: Num): Num
}
def pyth[A <: Num](a: A, b: A)(sqrt: A=>A) = sqrt(a * a + b * b)
// usage
pyth(3, 4)(Math.sqrt)
This is horrible for many reasons. First, we have the problem of the recursive type, Num. This is only allowed if you compile this code with the -Xrecursive option set to some integer value (5 is probably more than sufficient for numbers). Second, the type Num is structural, which means that any usage of the members it defines will be compiled into corresponding reflective invocations. Putting it mildly, this version of pyth is obscenely inefficient, running on the order of several hundred thousand times slower than a conventional implementation. There's no way around the structural type though if you want to define pyth for any type which defines +, * and for which there exists a sqrt function.
Finally, we come to the most fundamental issue: it's over-complicated. Why bother implementing the function in this way? Practically speaking, the only types it will ever need to apply to are real Scala numbers. Thus, it's easiest just to do the following:
def pyth(a: Double, b: Double) = Math.sqrt(a * a + b * b)
All problems solved! This function is usable on values of type Double, Int, Float, even odd ones like Short thanks to the marvels of implicit conversion. While it is true that this function is technically less flexible than our structurally-typed version, it is vastly more efficient and eminently more readable. We may have lost the ability to calculate the Pythagrean theorem for unforeseen types defining + and *, but I don't think you're going to miss that ability.
Some thoughts on Daniel's answer:
I've experimented to generalize Numeric to Real, which would be more appropriate for this function to provide the sqrt function. This would result in:
def pythagoras[T](a: T, b: T)(implicit n: Real[T]) = {
import n.mkNumericOps
(a*a + b*b).sqrt
}
It is tricky, but possible, to use literal numbers in such generic functions.
def pythagoras[T](a: T, b: T)(sqrt: (T => T))(implicit n: Numeric[T]) = {
import n.mkNumericOps
implicit val fromInt = n.fromInt _
//1 * sqrt(a*a + b*b) Not Possible!
sqrt(a*a + b*b) * 1 // Possible
}
Type inference works better if the sqrt is passed in a second parameter list.
Parameters a and b would be passed as Objects, but #specialized could fix this. Unfortuantely there will still be some overhead in the math operations.
You can almost do without the import of mkNumericOps. I got frustratringly close!
There is a method in java.lang.Math:
public static double hypot (double x, double y)
for which the javadocs asserts:
Returns sqrt(x2 +y2) without intermediate overflow or underflow.
looking into src.zip, Math.hypot uses StrictMath, which is a native Method:
public static native double hypot(double x, double y);