Why my expression in StringOps.foreach is not correct - scala

I try to calculate the product of the unicode values of a String using foreach.
scala> var s:Long = 1;"Hello".foreach(s *= _)
s: Long = 9415087488
scala> var s:Long = 1;"Hello".foreach(s = s * _)
<console>:10: error: missing parameter type for expanded function ((x$1) => s.$times(x$1))
"Hello".foreach(s = s * _)
^
I wonder why s = s * _ isn't correct here, what's the difference between s *= _ and s = s * _

The signature for the foreach function is:
def foreach(f: (A) => Unit): Unit
That is, it takes a function from type A to Unit for some appropriate type A.
So this is what I believe is happening:
In the first instance, the compiler interprets the expression s *= _ as the right-hand side of the function f (an expression returning Unit - ie nothing - meaning it is executed only for its side-effect - in this case updating the value of s). Because there is an underscore in this expression, the compiler assumes a suitable left-hand side for f.
In the second instance, the compiler can interpret the expression s = s * _ as both the left and right hand sides of f, so the s of s = should define the type A of the expression, but then it doesn't know what the underscore represents and complains.
I should note also that a more idiomatic, functional style of performing this sort of calculation would be to use a fold:
scala> val s = "Hello".foldLeft(1L)(_ * _)
s: Long = 9415087488

Related

andThen with square brackets and underscore in Scala function

I have two functions
val mul3 = 3*(_: Double)
val pow2 = (x: Double) => x*x
What I don't understand how it works at all is this:
println((pow2.andThen[Double] _ )(mul3)(5))
1) I thought andThen operates with results of the function to the left, but here it is [Double] _ - what is this? (I was expecting something like pow2 andThen mul3)
2) Why is mul3 passed to pow2 if pow2 expects Double? (mul3(pow2) gives an error)
3) What is being passed to pow2? Is it mul3 or 15?
4) What does . mean?
scala fiddle
Lets go step by step.
val mul3 = 3*(_: Double)
Is a Function from a Double to another Double. Thus, is type is Function1[Double, Double].
The same applies to:
val pow2 = (x: Double) => x*x
Now, remember that in Scala, everything is an object. And that there are not operators, only methods. So:
pow2.andThen[Double]
Is calling the andThen on method on the Function1 class.
As you can see on the scaldoc, that method receives another function. Also, it is parametric in the return type of the second function, which determines the return type of the composed function that is returned.
So the [Double] part is just specifying that type.
pow2.andThen[Double] _
Is using the underscore syntax to create another function.
The above line is equivalent to:
f => pow2.andThen[Double](f)
So, it is creating a function that takes another function as input, and returns another function. The resulting function will call pow2 first and then call the function passed as the argument.
Thus, it is of type Function1[Function1[Double, Double], Function[Double, Double]].
Then
(pow2.andThen[Double] _ )(mul3)
Is passing mul3 as the argument of that function, returning a final function (Function1[Double, Doule]) that calls pow2 first and pass the result to mul3.
Finally
(pow2.andThen[Double] _ )(mul3)(5)
Is calling the resulting function with 5 as is input.
After substitution, the code is equivalent to:
x => mul3(pow2(x))
x => 3 * (x * x)
5 => 3 * (x * x)
3 * (5 * 5)
75.0
Side note, IMHO, that code is very cryptic and far for what I would call idiomatic in Scala.

eta/placholders underscores in scala: why does "Console println" work and "Console.println" not?

I am trying to understand the exact details of when eta expansion happens and when param placeholders are expanded.
Going through many examples and SO answers/questions i understand the following:
val xs = (1 to 5)
/*ex1*/ xs.foreach(println)
/*ex2*/ xs.foreach(println _) // eta expansion?
/*ex3*/ xs.foreach(println(_)) // placeholder syntax
/*ex4*/ xs.foreach(println(_ * 2)) // INVALID -> xs.foreach(println(x => x * 2))
/*ex5*/ xs.foreach(Console.println _ * 2) // INVALID same reason?
/*ex6*/ xs.foreach(Console println _ * 2) // works
My quesion is: why does ex6 work?
/*ex5*/ xs.foreach(Console.println _ * 2) // INVALID same reason?
/*ex6*/ xs.foreach(Console println _ * 2) // works
We can try to construct the function value inside foreach (ex6):
val fun1: Int => Unit = x => Console println x * 2
val fun2: Int => Unit = Console println _ * 2 // short form
Note that using infix syntax, Scala would expect exactly one argument to the right, so how comes that x * 2 is (correctly) interpreted as a single argument? This is because the * symbol has higher precedence in the infix notation. If we used an alphabetical method, it would not work:
val fun6: Int => Unit = x => Console println x max 2 // not allowed
So while ex6 works, we can't however write (ex5):
val fun3: Int => Unit = x => Console.println x * 2
Simply because that is not valid Scala syntax:
Console.println 3 // not possible, either infix or parentheses!
So we would have to introduce parentheses:
val fun4: Int => Unit = x => Console.println (x * 2)
But with the extra parentheses, you cannot use the underscore shortcut:
val fun5: Int => Unit = Console.println (_ * 2)
(for the same reason of ex4).

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.

Why can't a variable be assigned placeholder in function literal?

I'm having trouble understanding underscores in function literals.
val l = List(1,2,3,4,5)
l.filter(_ > 0)
works fine
l.filter({_ > 0})
works fine
l.filter({val x=1; 1+_+3 > 0}) // ie you can have multiple statements in your function literal and use the underscore not just in the first statement.
works fine
And yet:
l.filter({val x=_; x > 0})
e>:1: error: unbound placeholder parameter
l.filter({val x=_; x > 0})
I can't assign the _ to a variable, even though the following is legal function literal:
l.filter(y => {val x=y; x > 0})
works fine.
What gives? Is my 'val x=_' getting interpreted as something else? Thanks!
Actually, you have to back up a step.
You are misunderstanding how the braces work.
scala> val is = (1 to 5).toList
is: List[Int] = List(1, 2, 3, 4, 5)
scala> is map ({ println("hi") ; 2 * _ })
hi
res2: List[Int] = List(2, 4, 6, 8, 10)
If the println were part of the function passed to map, you'd see more greetings.
scala> is map (i => { println("hi") ; 2 * i })
hi
hi
hi
hi
hi
res3: List[Int] = List(2, 4, 6, 8, 10)
Your extra braces are a block, which is some statements followed by a result expression. The result expr is the function.
Once you realize that only the result expr has an expected type that is the function expected by map, you wouldn't think to use underscore in the preceding statements, since a bare underscore needs the expected type to nail down what the underscore means.
That's the type system telling you that your underscore isn't in the right place.
Appendix: in comments you ask:
how can I use the underscore syntax to bind the parameter of a
function literal to a variable
Is this a "dumb" question, pardon the expression?
The underscore is so you don't have to name the parameter, then you say you want to name it.
One use case might be: there are few incoming parameters, but I'm interested in naming only one of them.
scala> (0 /: is)(_ + _)
res10: Int = 15
scala> (0 /: is) { case (acc, i) => acc + 2 * i }
res11: Int = 30
This doesn't work, but one may wonder why. That is, we know what the fold expects, we want to apply something with an arg. Which arg? Whatever is left over after the partially applied partial function.
scala> (0 /: is) (({ case (_, i) => _ + 2 * i })(_))
or
scala> (0 /: is) (({ case (_, i) => val d = 2 * i; _ + 2 * d })(_))
SLS 6.23 "placeholder syntax for anonymous functions" mentions the "expr" boundary for when you must know what the underscore represents -- it's not a scope per se. If you supply type ascriptions for the underscores, it will still complain about the expected type, presumably because type inference goes left to right.
The underscore syntax is mainly user for the following replacement:
coll.filter(x => { x % 2 == 0});
coll.filter(_ % 2 == 0);
This can only replace a single parameter. This is the placeholder syntax.
Simple syntactic sugar for a lambda.
In the breaking case you are attempting null initialization/defaulting.
For primitive types with init conventions:
var x: Int = _; // x will be 0
The general case:
var y: List[String] = _; // y is null
var z: Any = _; // z = null;
To get pedantic, it works because null is a ref to the only instance of scala.Null, a sub-type of any type, which will always satisfy the type bound because of covariance. Look HERE.
A very common usage scenario, in ScalaTest:
class myTest extends FeatureTest with GivenWhenThen with BeforeAndAfter {
var x: OAuthToken = _;
before {
x = someFunctionThatReturnsAToken;
}
}
You can also see why you shouldn't use it with val, since the whole point is to update the value after initialization.
The compiler won't even let you, failing with: error: unbound placeholder parameter.
This is your exact case, the compiler thinks you are defaulting, a behaviour undefined for vals.
Various constraints, such as timing or scope make this useful.
This is different from lazy, where you predefine the expression that will be evaluated when needed.
For more usages of _ in Scala, look HERE.
Because in this two cases underscore (_) means two different things. In case of a function it's a syntactic sugar for lambda function, your l.filter(_ > 0) later desugares into l.filter(x => x > 0). But in case of a var it has another meaning, not a lambda function, but a default value and this behavior is defined only for var's:
class Test {
var num: Int = _
}
Here num gonna be initialized to its default value determined by its type Int. You can't do this with val cause vals are final and if in case of vars you can later assign them some different values, with vals this has no point.
Update
Consider this example:
l filter {
val x = // compute something
val z = _
x == z
}
According to your idea, z should be bound to the first argument, but how scala should understand this, or you you have more code in this computation and then underscore.
Update 2
There is a grate option in scala repl: scala -Xprint:type. If you turn it on and print your code in (l.filter({val x=1; 1+_+3 > 0})), this what you'll see:
private[this] val res1: List[Int] = l.filter({
val x: Int = 1;
((x$1: Int) => 1.+(x$1).+(3).>(0))
});
1+_+3 > 0 desugares into a function: ((x$1: Int) => 1.+(x$1).+(3).>(0)), what filter actually expects from you, a function from Int to Boolean. The following also works:
l.filter({val x=1; val f = 1+(_: Int)+3 > 0; f})
cause f here is a partially applied function from Int to Boolean, but underscore isn't assigned to the first argument, it's desugares to the closes scope:
private[this] val res3: List[Int] = l.filter({
val x: Int = 1;
val f: Int => Boolean = ((x$1: Int) => 1.+((x$1: Int)).+(3).>(0));
f
});

Unexpected Scala pattern matching syntax

I had a List of Scala tuples like the following:
val l = List((1,2),(2,3),(3,4))
and I wanted to map it in a list of Int where each item is the sum of the Ints in a the corresponding tuple. I also didn't want to use to use the x._1 notation so I solved the problem with a pattern matching like this
def addTuple(t: (Int, Int)) : Int = t match {
case (first, second) => first + second
}
var r = l map addTuple
Doing that I obtained the list r: List[Int] = List(3, 5, 7) as expected. At this point, almost by accident, I discovered that I can achieve the same result with an abbreviated form like the following:
val r = l map {case(first, second) => first + second}
I cannot find any reference to this syntax in the documentation I have. Is that normal? Am I missing something trivial?
See Section 8.5 of the language reference, "Pattern Matching Anonymous Functions".
An anonymous function can be defined by a sequence of cases
{case p1 =>b1 ... case pn => bn }
which appear as an expression without a prior match. The expected type of such an expression must in part be defined. It must be either scala.Functionk[S1, ..., Sk, R] for some k > 0, or scala.PartialFunction[S1, R], where the argument type(s) S1, ..., Sk must be fully determined, but the result type R may be undetermined.
The expected type deternines whether this is translated to a FunctionN or PartialFunction.
scala> {case x => x}
<console>:6: error: missing parameter type for expanded function ((x0$1) => x0$1 match {
case (x # _) => x
})
{case x => x}
^
scala> {case x => x}: (Int => Int)
res1: (Int) => Int = <function1>
scala> {case x => x}: PartialFunction[Int, Int]
res2: PartialFunction[Int,Int] = <function1>
{case(first, second) => first + second} is treated as a PartialFunction literal. See examples in "Partial Functions" section here: http://programming-scala.labs.oreilly.com/ch08.html or section 15.7 of Programming in Scala.
Method map accepts a function. In your first example you create a function, assign it to a variable, and pass it to the map method. In the second example you pass your created function directly, omitting assigning it to a variable. You are doing just the same thing.