'for' loop inside the code snippet not understood [duplicate] - scala

This question already has answers here:
Confused with the for-comprehension to flatMap/Map transformation
(5 answers)
in scala why does for yield return option instead of string
(3 answers)
Is for-yield-getOrElse paradigmatic Scala or is there a better way?
(1 answer)
Closed 3 years ago.
I have below piece of code, which is printing: Some(600) as output.
Its not understood how the addition is happening inside 'for' loop.
In below, its confusing whats happening inside the code block of 'for' loop and how the variable 'y' is being calculated. Can someone please help?
object TestObject extends App
{
def toInt(s: String): Option[Int] = {
try
{
Some(Integer.parseInt(s.trim))
}
catch
{
case e: Exception => None
}
}
val y = for
{
a <- toInt("100")
b <- toInt("200")
c <- toInt("300")
} yield a + b + c
println(y)
}

In Scala this is called a for-comprehension.
toInt wraps the value in an Option which is extracted by <- and assigned to a and so on.
If one of the Option is None the result would be None
yield always returns its last statement, in your case: a + b + c
And so the result is Some(600).
See the documentation here: https://docs.scala-lang.org/tour/for-comprehensions.html

From inside the for loop, toInt method is being called which returns an Option[Int]. Now what for loop does is to simply open the Option container and assign variable a with value of 100. On similar lines, variables b and c are assigned value of 200 and 300.
And in the end the yield statement adds the values a,b and c and puts it back in the Option container.
Please refer to https://docs.scala-lang.org/tutorials/FAQ/yield.html and https://alvinalexander.com/scala/scala-for-loop-yield-examples-yield-tutorial

Related

Why does not ; equivalent to the eol? [duplicate]

This question already has answers here:
toList on Range with suffix notation causes type mismatch
(2 answers)
Closed 6 years ago.
Here is the code that compiles as intended
def coarse_grained: Int = {
def fib: Int = List(1,2) sum ;
fib
}
and one which does not
def coarse_grained: Int = {
def fib: Int = List(1,2) sum
fib
}
The only difference is ; after the sum.
As you know, List(2,6,9).drop(1) can also be written as List(2,6,9) drop 1. In fact, it can also be written like this.
List(2,6,9) drop
1
The compiler keeps looking for the final argument, even past a newline. So if you want to do this List(1,2).sum like this List(1,2) sum, you'll need to use the semicolon ; to tell the compiler to stop looking for the final argument. It's not coming.

will 'val' produce mutable data? [duplicate]

This question already has answers here:
Why is it possible to declare variable with same name in the REPL?
(2 answers)
Closed 7 years ago.
In REPL when we type the below command
scala> val p = 1 << 1
p: Int = 2
again
scala> val p = 1 << 2
p: Int = 4
my question is , I read that val is immutable . but in this case the value is changing right . Well can someone tell me why . is this really an example of mutatating . Please help
This behaviour appears in REPL only. If you try to define val twice in Scala code you'll get compilation error. In REPL second definition of val just shadows previous value of p
yep, as nyavro said, in the REPL you can override vals. Just think that in IDE if you make a mistake typing a value you can fix, in the REPL how would you fix? you would need to close the session?

Constructing a lambda expression using an underscore

This code
(1 to 30).foreach { x =>
println(x)
println
}
does what I'd expect: it prints each of 1 to 30, interspersed with blanks. I'm pretty clear on what's going on here, I think: I'm passing an anonymous function that first prints its argument, and then prints a blank line.
What I don't understand is why this doesn't do the same:
(1 to 30).foreach {
println _
println
}
It looks equivalent to me. The underscore should represent the first and only argument to the function; and the function prints its argument, and then prints a blank line. But when I run this second version, I don't get the blank lines.
What causes this difference?
The first variant is straightforward:
In the first line, apply println on x.
In the second line, apply the no-argument println (this prints the extra newline).
With the second variant you effectively tell Scala to do this:
In the first line, define a function object from println().
Subsequently, do nothing with this newly created object.
In the second line, apply println to the argument (the element of the
sequence).
The confusion stems from the assumption that println(x) and println _ are equivalent. They are different. The funcId _ syntax defines a new function based on funcId, it is not the same as using the "underscore argument" notation when calling a function.
There is a number of things going on here.
First, of all the parameter placeholder syntax can only be used within outer parentheses of the lambda definition. It cannot be used within parentheses of the method calls that you perform within the lambda definition.
Here is an example to demonstrate this point.
val a = (1 to 10).map(_ + 1)
This will work.
val b = (1 to 10).map(math.sin(_ + 1))
This will not work.
Therefore your code does not use parameter placeholder syntax at all. It instead uses partially applied functions.
For example
(1 to 10).foreach(println _)
is functionally equal to
val a = println (_ : Int)
(1 to 10).foreach(a)
Also when a method name is used within lambda expression the underscore can be omitted. Scala will still generate the partially applied method.
Therefore
(1 to 10).foreach(println)
is equal to
(1 to 10).foreach(println _)
And therefore your code is equal to
val a = println (_ : Int)
(1 to 10).foreach{
a
a
}
And because {a a} returns a, it is equal to
val a = println (_ : Int)
(1 to 10).foreach(a)
To add to other answers, there actually exists a way to use println(_) and not to declare x parameter:
(1 to 30).foreach {
println(_: Int)
println
}
Here foreach parameter is function, which firstly invokes println(_) for range element, and then passes println(Int) result (which is (): Unit) to another function, _ => println, which ignores it's argument and prints new line.

Placeholder syntax doesn't hold my place

I have already read some other questions like What are all the uses of an underscore in Scala? and while I'm sure this question has already been asked, I can't go through all of the other 17000 Scala questions.
There is Foreach have strange behaviour and Placeholder not useful but it still seems to be a hidden feature:
scala> val is = (1 to 5) toList
is: List[Int] = List(1, 2, 3, 4, 5)
scala> is foreach { i => println("Hi.") ; Console println 2 * i }
Hi.
2
Hi.
4
Hi.
6
Hi.
8
Hi.
10
scala> is foreach { println("Hi.") ; Console println 2 * _ }
Hi.
2
4
6
8
10
Can someone explain me please the difference?
If you feel a burst of enthusiasm and try:
scala> is foreach { i => println("Hi!") ; Console println 2 * i }
java.lang.IllegalArgumentException: !") ; Console println 2 * i }: event not found
then see this answer. And yes that really happened.
Placeholder syntax works on one expression, not for the whole block, so your example is interpreted as { println("Hi."); i => Console println 2 * i }
Landei has the right answer, I think, but it's not unpacked very thoroughly. Let's start at the end:
scala> Console println 2 * _
<console>:8: error: missing parameter type for expanded function
((x$1) => Console.println(2.$times(x$1)))
Console println 2 * _
^
Okay, so we see that on its own, Console println 2 * _ is trying to create a function via explicit eta expansion, except it doesn't know the return parameter type so it can't.
Now let's try a code block that returns a function.
scala> { println("Hi"); (i: Int) => i*5 }
Hi
res1: Int => Int = <function1>
So, as with everything, you execute the entire block (including side-effecting statements like println), and return the return value which is your function.
Now, as Landei said, placeholder syntax only works for one argument in one (simple) expression, and in the second case we don't have a simple expression but a block expression (consisting of two simple expressions). So we're not using placeholder syntax, we're creating a function. And we do it in a code block:
is foreach { println("Hi.") ; Console println 2 * _ }
which, since we don't start with function arguments, is interpreted as a plain parameter, except we can in almost any context--argument lists included--replace a simple expression (x) with a block expression { stuff; x }. So we can think of it as
is foreach ({ println("Hi.") ; Console.println 2 * _ })
Now the type inferencer knows what the return type is supposed to be, so it runs that code block which prints out "Hi" and creates a function, then passes that function (just once, at the beginning!) to foreach. If the type inferencer could look across lines to figure out types, it would be equivalent to this:
val temp = { println("Hi."); Console.println 2 * _ }
is foreach (temp)

What is the underscore character used for in Scala? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What are all the uses of an underscore in Scala?
When I follow a particular tutorial, I happen to see that the following two usages gives the same result. I understand the first one, but I do not understand why the 2nd one also works. Can someone give me an explanation, and at the same time give a summary of _ usage?
def sum (a:Int, b:Int) = a + b
val sumAsFunction1 = sum(_:Int, _:Int)
// I understand this, _ used as placeholder of parameters
val sumAsFunction2 = sum _
// why this usage has the same effect as sumAsFunction1?
This is one of the few places where eta-expansion mechanism needs some help. Consider the simpler example:
def foo() = {
println("foo");
42
}
val bar1 = foo
val bar2 = foo _
There is a fundamental difference between bar1 and bar2. The former one is interpreted as call foo and assign value to bar while the latter: Change method foo into a function and assign it to bar2. As a result bar1 is just a simple Int variable while bar2 is actually a function that will call original foo() method (and print "foo").
The underscore is used for a lot of things, but in this situation, it's used to denote that you want the un-called version of the sum function.
You define sum(a: Int, b:Int) = a + b, so think of sum _ as an anonymous function that takes the two arguments and returns their sum. You can pass the function around, since it's an instance of Function2[Int,Int,Int].