[plt-scheme] to define, or to let
Lo, on Saturday, March 20, Richard Cleis did write:
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
> It seems that the bigger issue is that 'let forces the new variables
> into their own context. I like that.
>
> But how far should a schemer go? For example, do schemers typically
> use 'letrec for a whole list if there is at least one dependency, or do
> they cascade 'let & 'letrec even though the program might be a bit
> messier?
I think this varies from person to person. (See also let* in the help
desk; at one point there were some additional generalizations, but I
don't know if they're still around.)
>
> (let ((strict-one 1)
> (strict-etc 2))
> (letrec ((fishy-one 1)
> (fishy-etc (+ 1 fishy-one)))
> #f))
Just FYI, I don't think this will necessarily do what you expect.
Letrec is, as people have said up-thread, primarily used for mutually
recursive definitions. Consider the following:
(letrec ((a E1)
(b E2))
E3)
where E1, E2, and E3 are arbitrary expressions.
R5RS states that evaluating E1 cannot require the value of b, and that
evaluating E2 cannot require the value of a. If such dependencies
exist, the results are undefined. (It's entirely possible that MzScheme
does define the results in this case; I don't remember, and I'm in the
middle of rebuilding DrScheme so I can't check the helpdesk.)
So, in your example, it's entirely possible that fishy-etc is not bound
to 2.
There is, of course, a common gotcha here for beginners; the following
*does* do what you want:
(letrec ([even? (lambda (n) (if (zero? n) #t (odd? (sub1 n))))]
[odd? (lambda (n) (if (zero? n) #f (even? (sub1 n))))])
(even? 3))
=> #f
Even though the body of EVEN? refers to ODD?, evaluating that lambda
form doesn't require the value of ODD? -- the dependency is defered
until you apply EVEN? (or ODD?) to an argument.
Richard