Scala: declaring val within for loop, if condition - scala

I'm a scala beginner and trying to understand how val works in Scala. I read that vals cannot be modified. When I do the following:
for( line <- Source.fromFile(args(0)).getLines() ) {
val currentLine = line
println(currentLine)
}
currentLine is updated in each iteration, while I expect it to be initialized with the first line and hold it till the end, or at least give a re-initialization error of some sort. Why is this so? Is the val created and destroyed in each iteration? My second question: I would like to use x outside if in the following code.
if( some condition is satisfied) val x = 2 else val x = 3
As of now, I'm getting an "Illegal start of simple expression" error. Is there a way to use x outside if?

Yes, the val is created and destroyed on each iteration.
val x = if(condition) 2 else 3 would do what you want.
Edit: You could rewrite 2. to if(conditon) {val x = 2} else {val x = 3} (to make it compile) but that would do nothing, since the if does not return anything and the variable can not be used outside the if

For Loop
You can break it down into a map operation.
for( line <- Source.fromFile(args(0)).getLines() ) {
val currentLine = line
println(currentLine)
}
So this code transforms to
Source.fromFile(args(0)).getLines().map( line => block )
block could be any expression. Where in your case block is:
{
val currentLine = line
println(currentLine)
}
Here currentLine is local to block and is created for each of the values of line given to map operation.
If-Else
Again following is also wrong:
if( some condition is satisfied) val x = 2 else val x = 3
Essentially if-else in Scala returns a value. So it should be:
if( condition ) expression1 else expression1
In your case you it can be:
if( condition ) { val x = 2 } else { val x = 3 }
However an assignment returns Unit ( or void if you want an analogy with Java / C++ ). So You can simply take the value of if-else like so:
val x = if( condition ) { 2 } else { 3 }
// OR
val x = if( condition ) 2 else 3

No answer mentioned it so in addition to what was said :
The val is made available for garbage collection on each iteration (and thus is not accessible from the next loop iteration). This is due to what is called scope of variables which is limited to the block in scala (same as Java).
As stated by #Kigyo val x = if(condition) 2 else 3 would do what you want, because you do only one assignation. If you put the assignation to val into the blocks, then the scope of this val is the block and thus not usable like you want to.

1st question: yes, in every iteration a new val is created
2nd question: you could rewrite it is
val x = if (some condition is satisfied)
2
else
3

Related

Declaration never used - but it is?

I am writing in Scala and within this if statement I have a for loop and I initialized i=0 and used i in the for loop. It is telling me that declaration is not used, but I am using it in the for loop. top is always equal to 5 also.
else {
var i = 0
for (i <- 0 until (top))
For loops work a little different in Scala than other languages. In Scala, a for comprehension is syntax sugar over foreach, filter, map/flatMap higher order functions.
When you write
for (i <- 0 until top)
The compiler re-writes this to
(0 until top).foreach {
i => ...
}
Here, the foreach body is an anonymous function where i is the function parameter that has the same type as the iterable. So you can just remove the declaration for i in your code snippet.
Like posted before, the for in Scala is a very different animal than in e.g. Java. Using it as an iterator is only one of its many potential usages.
For your code: The first and the second i are not the same. In fact, the variable in the for expression is ephemeral and doesn't leave the for's scope, but actually shadows the outer one.
var i = 0 // you don't need this
for (i <- 0 until (top)) // loops from 0 to whatever top is regardless what's in the outer i
This will print 0 1 2 3 4:
val top = 5
for (i <- 0 until (top)) {
println(i)
}
One really cool aspect of for comes from the yield keyword (example from the first link):
val names = List("adam", "david", "frank")
val ucNames = for (name <- names) yield name.capitalize
Also it is used to kind of map over multiple collections/monads etc. at once like in Haskell, a task rather tedious otherwise:
val names = List("adam", "david")
val numbers = List(1, 2)
val lst = for {
name <- names
number <- numbers
} yield s"$name: $number"
lst will now hold the cartesian product of the two lists as a List[String]: List("adam: 1", "adam: 2", "david: 1", "david: 2")

How to access previous element when using yield in for loop chisel3

This is mix Chisel / Scala question.
Background, I need to sum up a lot of numbers (the number of input signals in configurable). Due to timing constrains I had to split it to groups of 4 and pipe(register it), then it is fed into next stage (which will be 4 times smaller, until I reach on)
this is my code:
// log4 Aux function //
def log4(n : Int): Int = math.ceil(math.log10(n.toDouble) / math.log10(4.0)).toInt
// stage //
def Adder4PipeStage(len: Int,in: Vec[SInt]) : Vec[SInt] = {
require(in.length % 4 == 0) // will not work if not a muliplication of 4
val pipe = RegInit(VecInit(Seq.fill(len/4)(0.S(in(0).getWidth.W))))
pipe.zipWithIndex.foreach {case(p,j) => p := in.slice(j*4,(j+1)*4).reduce(_ +& _)}
pipe
}
// the pipeline
val adderPiped = for(j <- 1 to log4(len)) yield Adder4PipeStage(len/j,if(j==1) io.in else <what here ?>)
how to I access the previous stage, I am also open to hear about other ways to implement the above
There are several things you could do here:
You could just use a var for the "previous" value:
var prev: Vec[SInt] = io.in
val adderPiped = for(j <- 1 to log4(len)) yield {
prev = Adder4PipeStage(len/j, prev)
prev
}
It is a little weird using a var with a for yield (since the former is fundamentally mutable while the latter tends to be used with immutable-style code).
You could alternatively use a fold building up a List
// Build up backwards and reverse (typical in functional programming)
val adderPiped = (1 to log4(len)).foldLeft(io.in :: Nil) {
case (pipes, j) => Adder4PipeStage(len/j, pipes.head) :: pipes
}.reverse
.tail // Tail drops "io.in" which was 1st element in the result List
If you don't like the backwards construction of the previous fold,
You could use a fold with a Vector (better for appending than a List):
val adderPiped = (1 to log4(len)).foldLeft(Vector(io.in)) {
case (pipes, j) => pipes :+ Adder4PipeStage(len/j, pipes.last)
}.tail // Tail drops "io.in" which was 1st element in the result Vector
Finally, if you don't like these immutable ways of doing it, you could always just embrace mutability and write something similar to what one would in Java or Python:
For loop and mutable collection
val pipes = new mutable.ArrayBuffer[Vec[SInt]]
for (j <- 1 to log4(len)) {
pipes += Adder4PipeStage(len/j, if (j == 1) io.in else pipes.last)
}

scalacheck: define a generator for an infinite stream with some dependence on previous elements

I'm trying to define a Gen[Stream[A]] for an infinite (lazily evaluated) stream of As where each element A can depend on previous elements.
As a minimal case, we can take Gen[Stream[Int]] where the next element is either +1 or +2 of the previous element. For reference here is a haskell implementation:
increasingInts :: Gen [Int]
increasingInts = arbitrary >>= go
where
go seed = do
inc <- choose (1,2)
let next = seed + inc
rest <- go next
return (next : rest)
I have tried Gen.sequence on a Stream[Gen[A]] but got a stackoverflow. I also tried defining the Gen from scratch, but the constructor gen for Gen is private and works with private methods/types.
This attempt also gives a stackoverflow.
def go(seed: Int): Gen[Stream[Int]] =
for {
inc <- Gen.choose(1, 2)
next = seed + inc
rest <- Gen.lzy(go(next))
} yield next #:: rest
val increasingInts: Gen[Stream[Int]] = go(0)
increasingInts(Gen.Parameters.default, Seed.random()).get foreach println
So I'm stuck. Any ideas?
What you want can be achieved with this:
val increasingInts = {
val increments = Gen.choose(1, 2)
val initialSeed = 0
for {
stream <- Gen.infiniteStream(increments)
} yield stream.scanLeft(initialSeed)(_ + _)
}
.scanLeft is like a .foldLeft but retains the intermediate values, thus giving you another Stream.
I've written about scanLeft here: https://www.scalawilliam.com/most-important-streaming-abstraction/

call-by-name and call-by-value with lazy val

I would like to know the difference between a variable passed by value, but lazy, and pass a variable by name in Scala.
I wrote this example to try to show but I do not, how should I do?
def callByValue(x : Unit) = {
x
x
}
def callByName(x : => Unit) = {
x
x
}
lazy val j = {println("initializing lazy"); 0}
var i = {println("initializing"); 0}
callByName(i = i + 1)
print(i + "\n") // "5"
callByValue(j)
print(j + "\n") // "1"
By "5" you mean, like, 2, right? And "1" means 0?
Is this one of those Google interview questions?
This shows the closure evaluated twice by the function:
scala> callByName {
| println("calling")
| i += 1
| }
calling
calling
and then
scala> println(i)
4
That's after it was 2.
HTH.
See if this helps.
val is executed at time of definition
lazy val is executed once
but at first time of reference
:=> pass by name is executed
everytime at time of reference but not at time of definition (think
of it like a function, a function is executed at time of
call/reference, not at time when we define a function),
def callByValue(x : Unit) = {
x
x
}
def callByName(x : => Unit) = {
x
x
}
val i = {println("i"); 0}//print should happen now at time of declaration. i is 0.
lazy val j = {println("j"); 0} //no print because {...} will get executed when j is referenced, not at time of definition.
val k = {println("k"); 0} //same as case of i, print should happen now. K should be 0
//no special case. A val being passed like a regular function
println("k test. K is val")
callByValue (k) //no prints as K block is already evaluated.
//passing a val to a function by name. The behavior will be same as K because i is already evaluated at time of definition. basically we are passing 0
println("i test. i is val but passed by Name.");
callByName(i);//I is passed by name. Thus the block will be executed everytime it is referenced
println("j test. It is passed lazy. It will be executed only once when referenced for 1st time")
callByValue(j) //prints j once, assigns value 0 to j inside callByValue function. Note that because j is lazy, it the block {print j;0} is evaluated once when j was referenced for first time. It is not executed everytime j was referenced.
println("test l")
callByName({println("l");0});//l is passed by name. Thus the block will be executed everytime it is referenced
println("test l again")
callByValue({println("l");0});//l is passed by value. Thus the block will be executed once
Output
i <- when i was defined. val i = {println("i"); 0}
k <- when k was defined. {println("k"); 0}
k test. K is val <- no further prints of 'k' as the {println("k"); 0} has already been evaluated
i test. i is val but passed by Name. <- no furhter prints of 'i' as {println("i"); 0} is already evaluated
j test. It is passed lazy. It will be executed only once when referenced for 1st time
j <- note j is printed now instead of time of definition
test l
l <- we passed {print(l);0}. It will get executed everytime l is referenced. Thus two prints corresponding to {x;x} code of call by name
l
test l again
l <- only one print when {print(l);0} was passed by value

How do I break out of a loop in Scala?

How do I break out a loop?
var largest=0
for(i<-999 to 1 by -1) {
for (j<-i to 1 by -1) {
val product=i*j
if (largest>product)
// I want to break out here
else
if(product.toString.equals(product.toString.reverse))
largest=largest max product
}
}
How do I turn nested for loops into tail recursion?
From Scala Talk at FOSDEM 2009 http://www.slideshare.net/Odersky/fosdem-2009-1013261
on the 22nd page:
Break and continue
Scala does not have them. Why?
They are a bit imperative; better use many smaller functions
Issue how to interact with closures.
They are not needed!
What is the explanation?
You have three (or so) options to break out of loops.
Suppose you want to sum numbers until the total is greater than 1000. You try
var sum = 0
for (i <- 0 to 1000) sum += i
except you want to stop when (sum > 1000).
What to do? There are several options.
(1a) Use some construct that includes a conditional that you test.
var sum = 0
(0 to 1000).iterator.takeWhile(_ => sum < 1000).foreach(i => sum+=i)
(warning--this depends on details of how the takeWhile test and the foreach are interleaved during evaluation, and probably shouldn't be used in practice!).
(1b) Use tail recursion instead of a for loop, taking advantage of how easy it is to write a new method in Scala:
var sum = 0
def addTo(i: Int, max: Int) {
sum += i; if (sum < max) addTo(i+1,max)
}
addTo(0,1000)
(1c) Fall back to using a while loop
var sum = 0
var i = 0
while (i <= 1000 && sum <= 1000) { sum += 1; i += 1 }
(2) Throw an exception.
object AllDone extends Exception { }
var sum = 0
try {
for (i <- 0 to 1000) { sum += i; if (sum>=1000) throw AllDone }
} catch {
case AllDone =>
}
(2a) In Scala 2.8+ this is already pre-packaged in scala.util.control.Breaks using syntax that looks a lot like your familiar old break from C/Java:
import scala.util.control.Breaks._
var sum = 0
breakable { for (i <- 0 to 1000) {
sum += i
if (sum >= 1000) break
} }
(3) Put the code into a method and use return.
var sum = 0
def findSum { for (i <- 0 to 1000) { sum += i; if (sum>=1000) return } }
findSum
This is intentionally made not-too-easy for at least three reasons I can think of. First, in large code blocks, it's easy to overlook "continue" and "break" statements, or to think you're breaking out of more or less than you really are, or to need to break two loops which you can't do easily anyway--so the standard usage, while handy, has its problems, and thus you should try to structure your code a different way. Second, Scala has all sorts of nestings that you probably don't even notice, so if you could break out of things, you'd probably be surprised by where the code flow ended up (especially with closures). Third, most of Scala's "loops" aren't actually normal loops--they're method calls that have their own loop, or they are recursion which may or may not actually be a loop--and although they act looplike, it's hard to come up with a consistent way to know what "break" and the like should do. So, to be consistent, the wiser thing to do is not to have a "break" at all.
Note: There are functional equivalents of all of these where you return the value of sum rather than mutate it in place. These are more idiomatic Scala. However, the logic remains the same. (return becomes return x, etc.).
This has changed in Scala 2.8 which has a mechanism for using breaks. You can now do the following:
import scala.util.control.Breaks._
var largest = 0
// pass a function to the breakable method
breakable {
for (i<-999 to 1 by -1; j <- i to 1 by -1) {
val product = i * j
if (largest > product) {
break // BREAK!!
}
else if (product.toString.equals(product.toString.reverse)) {
largest = largest max product
}
}
}
It is never a good idea to break out of a for-loop. If you are using a for-loop it means that you know how many times you want to iterate. Use a while-loop with 2 conditions.
for example
var done = false
while (i <= length && !done) {
if (sum > 1000) {
done = true
}
}
To add Rex Kerr answer another way:
(1c) You can also use a guard in your loop:
var sum = 0
for (i <- 0 to 1000 ; if sum<1000) sum += i
Simply We can do in scala is
scala> import util.control.Breaks._
scala> object TestBreak {
def main(args : Array[String]) {
breakable {
for (i <- 1 to 10) {
println(i)
if (i == 5)
break;
} } } }
output :
scala> TestBreak.main(Array())
1
2
3
4
5
Since there is no break in Scala yet, you could try to solve this problem with using a return-statement. Therefore you need to put your inner loop into a function, otherwise the return would skip the whole loop.
Scala 2.8 however includes a way to break
http://www.scala-lang.org/api/rc/scala/util/control/Breaks.html
An approach that generates the values over a range as we iterate, up to a breaking condition, instead of generating first a whole range and then iterating over it, using Iterator, (inspired in #RexKerr use of Stream)
var sum = 0
for ( i <- Iterator.from(1).takeWhile( _ => sum < 1000) ) sum += i
// import following package
import scala.util.control._
// create a Breaks object as follows
val loop = new Breaks;
// Keep the loop inside breakable as follows
loop.breakable{
// Loop will go here
for(...){
....
// Break will go here
loop.break;
}
}
use Break module
http://www.tutorialspoint.com/scala/scala_break_statement.htm
Just use a while loop:
var (i, sum) = (0, 0)
while (sum < 1000) {
sum += i
i += 1
}
Here is a tail recursive version. Compared to the for-comprehensions it is a bit cryptic, admittedly, but I'd say its functional :)
def run(start:Int) = {
#tailrec
def tr(i:Int, largest:Int):Int = tr1(i, i, largest) match {
case x if i > 1 => tr(i-1, x)
case _ => largest
}
#tailrec
def tr1(i:Int,j:Int, largest:Int):Int = i*j match {
case x if x < largest || j < 2 => largest
case x if x.toString.equals(x.toString.reverse) => tr1(i, j-1, x)
case _ => tr1(i, j-1, largest)
}
tr(start, 0)
}
As you can see, the tr function is the counterpart of the outer for-comprehensions, and tr1 of the inner one. You're welcome if you know a way to optimize my version.
Close to your solution would be this:
var largest = 0
for (i <- 999 to 1 by -1;
j <- i to 1 by -1;
product = i * j;
if (largest <= product && product.toString.reverse.equals (product.toString.reverse.reverse)))
largest = product
println (largest)
The j-iteration is made without a new scope, and the product-generation as well as the condition are done in the for-statement (not a good expression - I don't find a better one). The condition is reversed which is pretty fast for that problem size - maybe you gain something with a break for larger loops.
String.reverse implicitly converts to RichString, which is why I do 2 extra reverses. :) A more mathematical approach might be more elegant.
I am new to Scala, but how about this to avoid throwing exceptions and repeating methods:
object awhile {
def apply(condition: () => Boolean, action: () => breakwhen): Unit = {
while (condition()) {
action() match {
case breakwhen(true) => return ;
case _ => { };
}
}
}
case class breakwhen(break:Boolean);
use it like this:
var i = 0
awhile(() => i < 20, () => {
i = i + 1
breakwhen(i == 5)
});
println(i)
if you don’t want to break:
awhile(() => i < 20, () => {
i = i + 1
breakwhen(false)
});
The third-party breakable package is one possible alternative
https://github.com/erikerlandson/breakable
Example code:
scala> import com.manyangled.breakable._
import com.manyangled.breakable._
scala> val bkb2 = for {
| (x, xLab) <- Stream.from(0).breakable // create breakable sequence with a method
| (y, yLab) <- breakable(Stream.from(0)) // create with a function
| if (x % 2 == 1) continue(xLab) // continue to next in outer "x" loop
| if (y % 2 == 0) continue(yLab) // continue to next in inner "y" loop
| if (x > 10) break(xLab) // break the outer "x" loop
| if (y > x) break(yLab) // break the inner "y" loop
| } yield (x, y)
bkb2: com.manyangled.breakable.Breakable[(Int, Int)] = com.manyangled.breakable.Breakable#34dc53d2
scala> bkb2.toVector
res0: Vector[(Int, Int)] = Vector((2,1), (4,1), (4,3), (6,1), (6,3), (6,5), (8,1), (8,3), (8,5), (8,7), (10,1), (10,3), (10,5), (10,7), (10,9))
import scala.util.control._
object demo_brk_963
{
def main(args: Array[String])
{
var a = 0;
var b = 0;
val numList1 = List(1,2,3,4,5,6,7,8,9,10);
val numList2 = List(11,12,13);
val outer = new Breaks; //object for break
val inner = new Breaks; //object for break
outer.breakable // Outer Block
{
for( a <- numList1)
{
println( "Value of a: " + a);
inner.breakable // Inner Block
{
for( b <- numList2)
{
println( "Value of b: " + b);
if( b == 12 )
{
println( "break-INNER;");
inner.break;
}
}
} // inner breakable
if( a == 6 )
{
println( "break-OUTER;");
outer.break;
}
}
} // outer breakable.
}
}
Basic method to break the loop, using Breaks class.
By declaring the loop as breakable.
Ironically the Scala break in scala.util.control.Breaks is an exception:
def break(): Nothing = { throw breakException }
The best advice is: DO NOT use break, continue and goto! IMO they are the same, bad practice and an evil source of all kind of problems (and hot discussions) and finally "considered be harmful". Code block structured, also in this example breaks are superfluous.
Our Edsger W. Dijkstra† wrote:
The quality of programmers is a decreasing function of the density of go to statements in the programs they produce.
I got a situation like the code below
for(id<-0 to 99) {
try {
var symbol = ctx.read("$.stocks[" + id + "].symbol").toString
var name = ctx.read("$.stocks[" + id + "].name").toString
stocklist(symbol) = name
}catch {
case ex: com.jayway.jsonpath.PathNotFoundException=>{break}
}
}
I am using a java lib and the mechanism is that ctx.read throw a Exception when it can find nothing.
I was trapped in the situation that :I have to break the loop when a Exception was thrown, but scala.util.control.Breaks.break using Exception to break the loop ,and it was in the catch block thus it was caught.
I got ugly way to solve this: do the loop for the first time and get the count of the real length.
and use it for the second loop.
take out break from Scala is not that good,when you are using some java libs.
Clever use of find method for collection will do the trick for you.
var largest = 0
lazy val ij =
for (i <- 999 to 1 by -1; j <- i to 1 by -1) yield (i, j)
val largest_ij = ij.find { case(i,j) =>
val product = i * j
if (product.toString == product.toString.reverse)
largest = largest max product
largest > product
}
println(largest_ij.get)
println(largest)
Below is code to break a loop in a simple way
import scala.util.control.Breaks.break
object RecurringCharacter {
def main(args: Array[String]) {
val str = "nileshshinde";
for (i <- 0 to str.length() - 1) {
for (j <- i + 1 to str.length() - 1) {
if (str(i) == str(j)) {
println("First Repeted Character " + str(i))
break() //break method will exit the loop with an Exception "Exception in thread "main" scala.util.control.BreakControl"
}
}
}
}
}
I don't know how much Scala style has changed in the past 9 years, but I found it interesting that most of the existing answers use vars, or hard to read recursion. The key to exiting early is to use a lazy collection to generate your possible candidates, then check for the condition separately. To generate the products:
val products = for {
i <- (999 to 1 by -1).view
j <- (i to 1 by -1).view
} yield (i*j)
Then to find the first palindrome from that view without generating every combination:
val palindromes = products filter {p => p.toString == p.toString.reverse}
palindromes.head
To find the largest palindrome (although the laziness doesn't buy you much because you have to check the entire list anyway):
palindromes.max
Your original code is actually checking for the first palindrome that is larger than a subsequent product, which is the same as checking for the first palindrome except in a weird boundary condition which I don't think you intended. The products are not strictly monotonically decreasing. For example, 998*998 is greater than 999*997, but appears much later in the loops.
Anyway, the advantage of the separated lazy generation and condition check is you write it pretty much like it is using the entire list, but it only generates as much as you need. You sort of get the best of both worlds.