Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is "letrec" implemented without using "set!"?

How can letrec be implemented without using set!?

It seems to me that set! is an imperative programming construct, and that by using it, one loses the benefits of functional programming.

like image 871
user1059449 Avatar asked Dec 11 '11 23:12

user1059449


People also ask

How does letrec work?

Unlike let , letrec makes new bindings visible before they're initialized. Storage is allocated, and the meanings of names are changed to refer to the new local variable bindings, and then the initial values of those variables are computed and the variables are initialized.

What is Letrec?

letrec supports the creation of recursive local procedures, including mutually recursive sets of procedures. let* supports the sequenced binding of variables, where each initial value expression can use the previous bindings.


2 Answers

I know usually we ask content to be copied but there is no short answer to your question. http://www.cs.indiana.edu/~dyb/pubs/fixing-letrec.pdf

like image 65
chx Avatar answered Sep 23 '22 02:09

chx


No. Just because a functional feature is implemented with imperative code behind the scenes, that doesn't make the feature be imperative. Our computing machines are all imperative; so at some point all functional code must be implemented by translation into imperative code!

The key thing to understand here is this: functional programming pertains to interface, not to implementation. A piece of code is functional if that code itself is unable to observe any side effects—even if side effects are in fact happening behind the scenes. I.e., if you check the value of the same binding of the same variable multiple times, you will get the same value—even if that value, behind the scenes, was put there by a use of set!.

In the case of letrec, there is a little catch here: the result is undefined if the evaluation of any of the bindings in the letrec causes another one to be derefenced. So, the result of this code is undefined:

(letrec ((foo bar)
         (bar 7))
  (cons foo bar))

The value of foo in the body of the letrec is undefined. The result of the following, on the other hand, is defined:

(letrec ((foo (lambda () bar))
         (bar 7))
  (cons (foo) bar))

This is because evaluating the lambda captures the reference to bar, but the actual value is not looked up until the closure is executed in the body.

like image 44
Luis Casillas Avatar answered Sep 24 '22 02:09

Luis Casillas