simple recursive function error - java.lang.StackOverFlow error - output exceeds cut off limit - scala

I am practicing scala's simple recursive function. This is from a book
def calculatePower(x:Int, y:Int): Long = {
if (x>=1)
x*calculatePower(x,y-1)
else 1
}
calculatePower(2,2)

You are checking x but you are decrementing y. That means your base-case will never be reached.

Your method stack overflows because it doesn't terminate and the stack frames accumulates until there is no more room.
if (x>=1) x*calculatePower(x,y-1) You test if x is greater or equal to 1 but in the recursive call you only decrement y!

Related

How tail recursion works internally in scala?

I am not able to understand tail recursion.
How accumulator variable store intermediate values of recursive calls?
What is the flow of execution. who executes first and why return value fact(n,1)?
def trec(n: Int): BigInt = {
#tailrec
def fact(x: Int, accumulator: BigInt): BigInt = {
if (x <= 1) accumulator else fact(x - 1, x * accumulator)
}
fact(n,1)
}
println(trec(5))
The recursion is support by how code execution works. Whenever you make a call to a method this call is pushed into a stack and all other methods called inside this one is pushed on top of the first, only when the method execution finishes the method call is popped from the stack and its return value is available for the outer method that called it to use it.
This way the recursion works because the results of the previous calls are stored in the stack and each call of the method uses the previous value that has already calculated.
The case of tail recursion specifically is that because the recursive call is the last thing done inside the method you don't need to push one call above the other in the stack (that may cause stack overflow exception) because the previous call has already finished. And because of that when you use #tailrec in scala it converts it to a loop under the hood that is more efficient.
So now I am going to try to answer your questions:
each call to the method has in its accumulator parameter the accumulated value of the factorial so far. The sequence is something like
fact(5, 1) -> fact(4, 5 * 1) -> fact(3, 4 * 5 * 1) -> fact(2, 3 * 4 * 5 * 1) -> fact(1, 2 * 3 * 4 * 5)
So in the last one call the accum parameter has already the result
The flow is first you call the trec method with the value you want to calculate and then this methods call its internal fact method passing also the value that you want to calculate and the accumulator that in this case is the neutral element in multiplication, 1. And then the flow is the one that I have written in step 1 following the recursion

Couldn't understand this SWIFT Fucntion [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
Hope you are doing well. Would anyone please explain this code to me? I am still not getting how we got 120 here. When the parameters were passed to the function, where was it saved? How did it determine max and min before calculating?
Would be really appreciated if anyone could explain it for me please..
You're getting 120 because you're asking the tuple for the sum value twice. The tuple passed back is (min: Int, max: Int, sum: Int). In this case, sum is also index number 2 (min is index zero, max is index one). So in this case statistics.sum == statistics.2
If you want to access min or max you can access them using statistics.min or statistics.max respectively. You can also use statistics.0 or statistics.1 if you prefer (I recommend using the labels though).
Final thought: I would change your initial assignment of max and min inside the function to read as follows:
guard var max = scores.first, var min = scores.first else {
return (0, 0, 0)
}
This will protect against the user accidentally passing an empty array.
You could have also set min and max to 0 ,not to scores[0].
This func is very simple, I think you should read somewhere How functions are working.
For loop is used to go through every element, in your case every element in array scores. In every iteration, variable sum is increased by current element in array. So:
At the beginning of the function : sum = 0
1. iteration: sum = 0 + 5
2. iteration: sum = 5 + 3
3. iteration: sum = 8 + 100
4. iteration: sum = 108 + 3
5. iteration: sum = 111 + 9
For loop ends. Sum = 120.
Score in Scores means like every single element in score. So name Score can be whatever you want to name it. You could have also name it element , x, a or whatever you like.
The function returns a tuple of type (min: Int, max: Int, sum: Int).
max and min are not determined before being calculated. When they're first assigned at the top of the function, they just contain the first element of the passed in scores array. But by the time the loop below finishes, they indeed have the correct minimum and maximum values. Those values are then returned in a tuple matching the return type.

Scala recursion depth differences and StackOverflowError below allowed depth

The following program was written to check how deep recursion in Scala can go deep on my machine. I assume that it mostly depends on stack's size assigned to this program. However, after calculating the maximal depth of recursion (catching exception when it appears) and trying to simulate a recursion of this depth I got odd outputs.
object RecursionTest {
def sumArrayRec(elems: Array[Int]) = {
def goFrom(i: Int, size: Int, elms: Array[Int]): Int = {
if (i < size) elms(i) + goFrom(i + 1, size, elms)
else 0
}
goFrom(0, elems.length, elems)
}
def main(args: Array[String]) {
val recDepth = recurseTest(0, 0, Array(1))
println("sumArrayRec = " + sumArrayRec((0 until recDepth).toArray))
}
def recurseTest(i: Int, j: Int, arr: Array[Int]): Int = {
try {
recurseTest(i + 1, j + 1, arr)
} catch { case e: java.lang.StackOverflowError =>
println("Recursion depth on this system is " + i + ".")
i
}
}
}
The results vary among executions of the program.
One of them is a desirable output:
/usr/lib/jvm/java-8-oracle/bin/java
Recursion depth on this system is 7166.
sumArrayRec = 25672195
Process finished with exit code 0
Nevertheless, the second possible output which I get indicates an error:
/usr/lib/jvm/java-8-oracle/bin/java
Recursion depth on this system is 8129.
Exception in thread "main" java.lang.StackOverflowError
at RecursionTest$.goFrom$1(lab44.scala:6)
at RecursionTest$.goFrom$1(lab44.scala:6)
at RecursionTest$.goFrom$1(lab44.scala:6)
(...)
at RecursionTest$.goFrom$1(lab44.scala:6)
at RecursionTest$.goFrom$1(lab44.scala:6)
Process finished with exit code 1
I didn't observe any dependence or relationship of them, I just once got the first, and other time the second
All of that lead me to the following questions:
Why do I get an error and what causes it?
Is this the stack overflow error and if yes...
Why the size of stack changes in the same time when the program is running? Is it even possible?
When I changed println("sumArrayRec = " + sumArrayRec((0 until recDepth).toArray)) into
println("sumArrayRec = " + sumArrayRec((0 until recDepth - 5000).toArray)), so much less, the behaviour remains the same.
You get a stack overflow because you cause a stack overflow
Yes
The max stack doesn't change, the JVM sets this. Your two methods recurseTest and sumArrayRec push different amounts to the stack. recurseTest is basically adding 2 ints the stack with each call while sumArrayRec is adding 3 ints since you have a call to elms(i), probably more with addition/ifelse (more instructions). It's tough to tell since the JVM is handling all of this and it's purpose is to obscure this from what you need to know. Also, who knows what optimizations the JVM is doing behind the scenes which can drastically effect the stack sizes created from each method call. On multiple runs you'll get different depths for stack due to system timing etc, maybe the jvm will optimize in the short time the program has run, maybe it won't, it's non-deterministic in this scenario. If you ran some warmup code before hand that might make your tests more deterministic so any optimizations will or will not take place.
You should look into using something like JMH for your tests, it will help with the determinism.
Side note: you can also manually change your stack size with -Xss2M, common for SBT usage.

Martin Odersky : Working hard to keep it simple

I was watching the talk given by Martin Odersky as recommended by himself in the coursera scala course and I am quite curious about one aspect of it
var x = 0
async { x = x + 1 }
async { x = x * 2 }
So I get that it can give 2 if if the first statement gets executed first and then the second one:
x = 0;
x = x + 1;
x = x * 2; // this will be x = 2
I get how it can give 1 :
x = 0;
x = x * 2;
x = x + 1 // this will be x = 1
However how can it result 0? Is it possible that the statement don't execute at all?
Sorry for such an easy question but I'm really stuck at it
You need to think about interleaved execution. Remember that the CPU needs to read the value of x before it can work on it. So imagine the following:
Thread 1 reads x (reading 0)
Thread 2 reads x (reading 0)
Thread 1 writes x + 1 (writing 1)
Thread 2 writes x * 2 (writing 0)
I know this has already been answered, but maybe this is still useful:
Think of it as a sequence of atomic operations. The processor is doing one atomic operation at a time.
Here we have the following:
Read x
Write x
Add 1
Multiply 2
The following two sequences are guaranteed to happen in this order "within themselves":
Read x, Add 1, Write x
Read x, Multiply 2, Write x
However, if you are executing them in parallel, the time of execution of each atomic operation relative to any other atomic operation in the other sequence is random i.e. these two sequences interleave.
One of the possible order of execution will produce 0 which is given in the answer by Paul Butcher
Here is an illustration I found on the internet:
Each blue/purple block is one atomic operation, you can see how you can have different results based on the order of the blocks
To solve this problem you can use the keyword "synchronized"
My understanding is that if you mark two blocks of code (e.g. two methods) with synchronized within the same object then each block will own the lock of that object while being executed, so that the other block cannot be executed while the first hasn't finished yet. However, if you have two synchronised blocks in two different objects then they can execute in parallel.

For loop in scala without sequence?

So, while working my way through "Scala for the Impatient" I found myself wondering: Can you use a Scala for loop without a sequence?
For example, there is an exercise in the book that asks you to build a counter object that cannot be incremented past Integer.MAX_VALUE. In order to test my solution, I wrote the following code:
var c = new Counter
for( i <- 0 to Integer.MAX_VALUE ) c.increment()
This throws an error: sequences cannot contain more than Int.MaxValue elements.
It seems to me that means that Scala is first allocating and populating a sequence object, with the values 0 through Integer.MaxValue, and then doing a foreach loop on that sequence object.
I realize that I could do this instead:
var c = new Counter
while(c.value < Integer.MAX_VALUE ) c.increment()
But is there any way to do a traditional C-style for loop with the for statement?
In fact, 0 to N does not actually populate anything with integers from 0 to N. It instead creates an instance of scala.collection.immutable.Range, which applies its methods to all the integers generated on the fly.
The error you ran into is only because you have to be able to fit the number of elements (whether they actually exist or not) into the positive part of an Int in order to maintain the contract for the length method. 1 to Int.MaxValue works fine, as does 0 until Int.MaxValue. And the latter is what your while loop is doing anyway (to includes the right endpoint, until omits it).
Anyway, since the Scala for is a very different (much more generic) creature than the C for, the short answer is no, you can't do exactly the same thing. But you can probably do what you want with for (though maybe not as fast as you want, since there is some performance penalty).
Wow, some nice technical answers for a simple question (which is good!) But in case anyone is just looking for a simple answer:
//start from 0, stop at 9 inclusive
for (i <- 0 until 10){
println("Hi " + i)
}
//or start from 0, stop at 9 inclusive
for (i <- 0 to 9){
println("Hi " + i)
}
As Rex pointed out, "to" includes the right endpoint, "until" omits it.
Yes and no, it depends what you are asking for. If you're asking whether you can iterate over a sequence of integers without having to build that sequence first, then yes you can, for instance using streams:
def fromTo(from : Int, to : Int) : Stream[Int] =
if(from > to) {
Stream.empty
} else {
// println("one more.") // uncomment to see when it is called
Stream.cons(from, fromTo(from + 1, to))
}
Then:
for(i <- fromTo(0, 5)) println(i)
Writing your own iterator by defining hasNext and next is another option.
If you're asking whether you can use the 'for' syntax to write a "native" loop, i.e. a loop that works by incrementing some native integer rather than iterating over values produced by an instance of an object, then the answer is, as far as I know, no. As you may know, 'for' comprehensions are syntactic sugar for a combination of calls to flatMap, filter, map and/or foreach (all defined in the FilterMonadic trait), depending on the nesting of generators and their types. You can try to compile some loop and print its compiler intermediate representation with
scalac -Xprint:refchecks
to see how they are expanded.
There's a bunch of these out there, but I can't be bothered googling them at the moment. The following is pretty canonical:
#scala.annotation.tailrec
def loop(from: Int, until: Int)(f: Int => Unit): Unit = {
if (from < until) {
f(from)
loop(from + 1, until)(f)
}
}
loop(0, 10) { i =>
println("Hi " + i)
}