a a’s v v’s a a’s 2.5 das dsa
scala> def loop() = loop //infinite loop OR def loop: Boolean = loop
Call by value [only evaluate once] - Call by Name [arg not evaluated if not used]
scala> def test(x:Int, y: Int) = x
scala> test(3+4, 8)
def func(x:Int, y: => Int) = x + y //y is call by name because of =>
func(1+2, loop) 1+2 3 func(loop, 1+2) //infinite
If is a statement not an expression
scala> def abs(x: Int) = if (x > 0) x else -xdef is call by name, function body will not be evaluated until called. but val is call by value and the function is evaluated right there.
def x = loop //OK
val x = loop //INFINITE LOOP
implement && function:
def and(x: Boolean, y: => Boolean) = if (x) y else false //=> let's us have short circuiting and in case x is false we won't go to evaluate y.
and(false, loop) // if y is not call by name we will stick to infinite loop otherwise it evaluates to false.
is an expression itself. sequence of expressions, the last expression is the value of the blockSemicolons are optional. when writing expressions in multiple lines scala assumes they are differnet expressions but we only want to have them in multiple lines. To avoid use parenthesis, OR write operator as character on previous line
nesting functions you can inherit variables instead of sending them as explicit parameters.
In a tail recursive function, all calculations happen first and the recursive call is the last thing that happens.functions that take other functions as parameters or that return functions as results are called higher order functions
Imagine a tail recursive function. It runs. It completes all its computation. As its very last action, it is ready to make its recursive call. What, at this point, is the use of the stack frame? None at all. We don’t need our local variables anymore because we’re done with all computations. We don’t need to know which function we’re in because we’re just going to re-enter the very same function. Scala, in the case of tail recursion, can eliminate the creation of a new stack frame and just re-use the current stack frame. The stack never gets any deeper, no matter how many times the recursive call is made. That’s the voodoo that makes tail recursion special in scala.
Incidentally, some languages achieve a similar end by converting tail recursion into iteration rather than by manipulating the stack.
This won’t work with head recursion. Do you see why? Imagine a head recursive function. First it does some work, then it makes its recursive call, then it does a little more work. We can’t just re-use the current stack frame when we make that recursive call. We’re going to NEED that stack frame info after the recursive call completes. It has our local variables, including the result (if any) returned by the recursive call.
This is not tail recursive:
function as an argument
sum(f: Int => Int, x: Int, y: Int) : Int = if (x<=y) f(x) + sum(x + 1, y) else 0 //sigma f(i) i from x to y
def sumcube(a: Int, b: Int) = sum(x => x * x * x, a, b) //the type can be omitted if it can be inferred from context
(x:Int, y:Int) => x+y