It usually happens when I'm using something that would change an Array or List. Like for example here: nums.drop(i). I tried to debug, but it doesn't even see the line, I would appreciate if you explain such behavior to me
def findDuplicates(nums: Array[Int]): List[Int] = {
nums.foldLeft(0)((accumValue, nextEl) => {
if (nums.tail.contains(nextEl)) {
accumValue
} else {
nums.drop(accumValue)
accumValue
}
})
nums.toList
}
The method drop
doesn't drop elements in place. It returns a new array without the elements that were dropped. And you don't use this new array in any way (you don't assign this value to some val
etc.), you just ignore the result.
Scala is expression-oriented. The value of a block (the value that the block returns) is the last expression in the block. So the value of the block
{
nums.drop(accumValue)
accumValue
}
is accumValue
.
The signature of the method is
/** The rest of the array without its `n` first elements. */
def drop(n: Int): Array[A] = ...
https://github.com/scala/scala/blob/v2.13.10/src/library/scala/collection/ArrayOps.scala#L374
It's not def drop(n: Int): Unit
.
If the debugger can't see the line it's possible that the compiler can see you are not using the result and the compiler just excludes the line.
You should get used to functional programming, where you don't mutate things in place (this would be a side effect) but take some value, transform it and return the result. You already started to use foldLeft
and accumulators, it's typical for FP.
Functional programming and non-functional programming
What is the difference between procedural programming and functional programming?