Search code examples
arraysscalasyntaxfunctional-programmingimmutability

Why does nothing happen every time I try to change the value of any data structure in Scala?


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
  }

Solution

  • 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?