My use-case is more complicated but basically below is the simplified example of what I am trying to achieve (my original code is for akka-stream):
offset := 0
//pump data
def pump(): Unit = {
elem := poller.getNumberFromOffset(offset)
elem match {
case null => doSomething()
case Completed => doSomethingElse()
case _ =>
offset += 1
//check if the element is matched with a pre-supplied selector/filter function
if(filterFunc(elem)) {
doSomething2()
} else {
//if the element doesn't match; increase offset and try again; can sleep for a while here
pump()
}
}
}
The problem is that pump() function might result in stack-overflow (because pump function is called over-and-over again for a specific condition).
I can write the function into a non-recursive version like the following:
offset := 0
//pump data
def pump(): Unit = {
elem := poller.getNumberFromOffset(offset)
while(elem != null && elem != Completed && !filterFunc(elem)) {
offset += 1
elem = poller.getNumberFromOffset(offset)
}
elem match {
case null => doSomething()
case Completed => doSomethingElse()
case _ =>
offset += 1
doSomething2()
}
}
However my use-case is much more complicated; so I would really like to use the recursion function if it's possible instead of converting the existing code to while/for loop.
My question is "should I do so" and is there any difference if I just simply put @tailrec annotation on the first example so that scala complier will treat pump as tail-recursion function (@tailrec def pump(): Unit = {}). In my case, the pump() function should be called separatedly / after fixed interval; so stack-frame is really not necessary here.
Thanks.
@tailrecannotation on the first example" – No. The@tailrecannotation makes no difference. Tail-recursive methods are always optimized. (More precisely: methods that satisfy the conditions laid out in the spec.) The only thing the@tailrecannotation does is generate a compiler error if the method is not tail-recursive. It does not change whether or not the method gets optimized. - Jörg W Mittagnull. Instead, I would wrap your possiblenullvalue in Option#apply. Example:Option[String] { null }===None- Kevin Meredith