def bang(x: Int): Int =
if (x == 0) throw new Exception("bang!")
else bang(x - 1)
scala> bang(5)
java.lang.Exception: bang!
at .bang(<console>:5)
at .<init>(<console>:6)
Scala only optimizes directly recursive calls back to the same function making the call. If the recursion is indirect, no optimization is possible:
def isEven(x: Int): Boolean =
if (x == 0) true else isOdd(x - 1)
def isOdd(x: Int): Boolean =
if (x == 0) false else isEven(x - 1)
You also won't get a tail-call optimization if the final call goes to a function value.
val funValue = nestedFun _
def nestedFun(x: Int) {
if (x != 0) { println(x); funValue(x - 1) }
}
Read more: Tail recursiondef curriedSum(x: Int)(y: Int) = x + y
There is a way to get an actual reference to curriedSum’s “second”
function. You can use the placeholder notation to use curriedSum in a partially applied function expression, like this:
scala> val onePlus = curriedSum(1)_
onePlus: (Int) => Int = <function1>
The underscore in curriedSum(1)_ is a placeholder for the second parameter list. The result is a reference to a function that, when invoked, adds one
to its sole Int argument and returns the result:
scala> onePlus(2)
res7: Int = 3
Read more: Currying
class CompilesFine {
private int f = 0;
public int f() {
return 1;
}
}
But the corresponding Scala class would not compile:
class WontCompile {
private var f = 0
def f = 1
}
The reason Scala places fields and methods into the same namespace is precisely so you can override a parameterless method with a val.
@vetalbabenko36 True! thanks :) it creates Warning:(4, 32) could not emit switch for @switch annotated match def tokenMe(ch: Char) = (ch: @switch) match { ^
May 18, 1:04:03 AM Scala
This example will be successfully compiled. It doesn't optimize to tableswtich , but it is compiled.
May 3, 8:37:51 AM Scala