Home > Blockchain >  Scala3 inline if reuse result of function
Scala3 inline if reuse result of function

Time:05-27

val num = 3
val x = if (func(num) > 3) func(num) else 4

How can i avoid calling func(num) twice here? My project is fully functional so calling func(num) twice is guaranteed to yield the same result. Does the compiler optimize this automatically? I am aware of this:

val num = 3
val x = List(num).map(f(_)).map(a => if (a > 3) a else 4).head

EDIT: I'm looking for a way to improve this

val temp = tl.indexWhere(<bool>)
val insertIndex = if(temp == -1) tl.size else temp 

CodePudding user response:

The Scala compiler will generally not know if a function is pure, so it cannot perform that optimization automatically.

val temp = tl.indexWhere(???)
val insertIndex = if(temp == -1) tl.size else temp

Is very likely the clearest and (by explicitly preventing double evaluation) most performant expression of this logic. Assuming that temp is a local variable, the Scala compiler can see that it's not used later in your function/method and reuse the local variable slot.

CodePudding user response:

Just in case you want to make it abundantly clear that the local variable is only used for this particular block of code, you could utilize … a block of code:

val insertIndex = { val temp = tl.indexWhere(<bool>); if (temp == -1) tl.size else temp }

or

val insertIndex = {
  val temp = tl.indexWhere(<bool>)
  if (temp == -1) tl.size else temp
}

As mentioned in another answer, Scala cannot, generally, know that tl.indexWhere is pure, since Purity Analysis is equivalent to solving the Halting Problem.

CodePudding user response:

Not sure if this is an improvement but you can use pattern matching with guard:

val num = 3
val x = num match {
  case v if v > 3 => v
  case _ => 4
}

Or in second case simply:

val insertIndex = tl.indexWhere(...) match {
  case -1 => tl.size
  case v => v
}
  • Related