Search code examples
scalafunctional-programming

Is it efficient to use Arrays in Recursion, when programming functionally in scala?


If taking a functional approach, is this the most efficient way to do this?

@tailrec
def readLine(in: SomeTypeOfBuffer, a: Array[Byte]): Array[Byte] = {
    val char = in.readByte()
    char match{
        case '\n'  => a 
        case other => readLine(in, a :+ other) 
    }

}

Since each recursive call makes a new array, another call to memory has to be made to allocate space for another array, and the previous array freed from memory.

Is this just the price of functional programming?

(I'm relatively new to scala and functional, so plz don't crucify me if I've got something horrendously wrong)


Solution

  • As @DeFuncT said, it is better to use an (immutable) List since it will not copy data when building. I will just show you how to do that.

    I am also going to apply the advice from @QuickSilver.

    def readLine(in: SomeTypeOfBuffer): List[Byte] = {
      val NewLine: Byte = '\n'.toByte
    
      @annotation.tailrec
      def loop(acc: List[Byte]): List[Byte]
        in.readByte() match {
          case NewLine => acc.reverse
          case char    => loop(other :: acc)
        }
    
      loop(acc = List.empty)
    }
    

    PS: In common Scala, you never see Array. Maybe the new ArraySeq or Vector.
    Plain arrays are usually only used for performance reasons, and usually contained in the scope of a single method.