1
$\begingroup$

What would be the problem of running the following scala codes assuming we are working with dynamic scoping and a global stack to store environments as some variants of Lisp do?

def fact(n:Int,f:() => Int):Int = 
 if(n == 0) f()
 else fact(n-1,() => n*f())
fact(7,() => 1)



def incrementer(x:Int)  = y => y+x
incrementer(2)(3)
$\endgroup$
  • $\begingroup$ Have you tried to run them on paper? Just pass lambdas as they are, without closing their free variables in any way. From a cursory look, the first should get stuck in an infinite loop, while the second accesses an undefined variable x $\endgroup$ – chi Dec 18 '16 at 18:06
2
$\begingroup$

With fact, the primary problem is with f. If n is 0, then it works fine. However, for any other value of n, fact is called with an f of () => n * f(). So when the base case (n = 0) is finally encountered, f is () => n * f(). When f is invoked, f is still () => n * f(). So the call to f results in unbounded recursion with itself.

With incrementer, x will be not be defined when y => x + y is called in your example. This is because y => x + y does not close over x (because of dynamic, as opposed to lexical, binding), there is no call on the stack that binds x to a value when the closure is invoked, and there is no global / top-level binding for x.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.