I suspect that I fundamentally misunderstand Scheme's evaluation rules. What is it about the way that let and letrec are coded and evaluated that makes letrec able to accept mutually recursive definitions whereas let cannot? Appeals to their basic lambda forms may be helpful.
The following is even? without let or letrec:
(define even?
( (lambda (e o) <------. ------------.
(lambda (n) (e n e o)) -----* |
) |
(lambda (n e o) <------. <---+
(if (= n 0) #t (o (- n 1) e o))) -----* |
(lambda (n e o) <------. <---*
(if (= n 0) #f (e (- n 1) e o))))) -----*
This defines the name even? to refer to the result of evaluating the application of the object returned by evaluating the (lambda (e o) (lambda (n) (e n e o)) ) expression to two objects produced by evaluating the other two lambda expressions, the ones in the arguments positions.
Each of the argument lambda expressions is well formed, in particular there are no references to undefined names. Each only refers to its arguments.
The following is the same even?, written with let for convenience:
(define even?-let-
(let ((e (lambda (n e o) <------. <---.
(if (= n 0) #t (o (- n 1) e o)))) -----* |
(o (lambda (n e o) <------. <---+
(if (= n 0) #f (e (- n 1) e o)))) -----* |
) |
(lambda (n) (e n e o)) )) ----------------------------*
But what if we won't pass those e and o values around as arguments?
(define even?-let-wrong- ^ ^
(let ((e (lambda (n) <-----------------|--|-------.
(if (= n 0) #t (o (- n 1))))) --* | |
(o (lambda (n) | |
(if (= n 0) #f (e (- n 1))))) --* |
) |
(lambda (n) (e n)) )) ---------------------------*
What are the two names o and e inside the two lambda's if expressions refer to now?
They refer to nothing defined in this piece of code. They are "out of scope".
Why? It can be seen in the equivalent lambda-based expression, similar to what we've started with, above:
(define even?-wrong- ^ ^
( (lambda (e o) <----. ----|---|---------.
(lambda (n) (e n)) --* | | |
) | | |
(lambda (n) | | <------+
(if (= n 0) #t (o (- n 1)))) ---* | |
(lambda (n) | <------*
(if (= n 0) #f (e (- n 1)))))) -----*
This defines the name even?-wrong- to refer to the result of evaluating the application of the object returned by evaluating the (lambda (e o) (lambda (n) (e n)) ) expression to two objects produced by evaluating the other two lambda expressions, the ones in the arguments positions.
But each of them contains a free variable, a name which refers to nothing defined in its scope. One contains an undefined o, and the other contains an undefined e.
Why? Because in the application (<A> <B> <C>), each of the three expressions <A>, <B>, and <C> is evaluated in the same scope -- that in which the application itself appears; the enclosing scope. And then the resulting values are applied to each other (in other words, the function call is made).
A "scope" is simply a textual area in a code.
Yet we need the o in the first argument lambda to refer to the second argument lambda, not anything else (or even worse, nothing at all). Same with the e in the second argument lambda, which we need to point at the first argument lambda.
let evaluates its variables' init expressions in the enclosing scope of the whole let expression first, and then it creates a fresh environment frame with its variables' names bound to the values which result from those evaluations. The same thing happens with the equivalent three-lambdas expression evaluation.
letrec, on the other hand, first creates the fresh environment frame with its variables' names bound to as yet-undefined-values (such that referring to those values is guaranteed to result in an error) and then it evaluates its init expressions in this new self-referential frame, and then it puts the resulting values into the bindings for their corresponding names.
Which makes the names inside the lambda expressions refer to the names inside the whole letrec expression's scope. In contrast to the let's referring to the outer scope:
^ ^
| |
(let ((e | |
(... o ...)) |
(o |
(............ e .........)))
.....)
does not work;
.----------------.
| |
(letrec ((e <--|--------. |
(..... o ...)) | |
(o <-----------|-------*
(.............. e .........)))
.....)
works fine.
Here's an example to further clarify things:
1. consider ((lambda (a b) ....here a is 1.... (set! a 3) ....here a is 3....) 1 2)
now consider ((lambda (a b) .....) (lambda (x) (+ a x)) 2).
the two as are different -- the argument lambda is ill-defined.
now consider ((lambda (a b) ...(set! a (lambda (x) (+ a x))) ...) 1 2).
the two as are now the same.
so now it works.
let can't create mutually-recursive functions in any obvious way because you can always turn let into lambda:
(let ((x 1))
...)
-->
((λ (x)
...)
1)
and similarly for more than one binding:
(let ((x 1)
(y 2))
...)
-->
((λ (x y)
...)
1 2)
Here and below, --> means 'can be translated into' or even 'could be macroexpanded into'.
OK, so now consider the case where the x and y are functions:
(let ((x (λ (...) ...))
(y (λ (...) ...)))
...)
-->
((λ (x y)
...)
(λ (...) ...)
(λ (...) ...))
And now it's becoming fairly clear why this can't work for recursive functions:
(let ((x (λ (...) ... (y ...) ...))
(y (λ (...) ... (x ...) ...)))
...)
-->
((λ (x y)
...)
(λ (...) (y ...) ...)
(λ (...) (x ...) ...))
Well, let's make this more concrete to see what goes wrong: let's consider a single recursive function: if there's a problem with that then there certainly will be problems with sets of mutually recursive functions.
(let ((factorial (λ (n)
(if (= n 1) 1
(* n (factorial (- n 1)))))))
(factorial 10))
-->
((λ (factorial)
(factorial 10))
(λ (n)
(if (= n 1) 1
(* n (factorial (- n 1))))))
OK, what happens when you try to evaluate the form? We can use the environment model as described in SICP . In particular consider evaluating this form in an environment, e, in which there is no binding for factorial. Here's the form:
((λ (factorial)
(factorial 10))
(λ (n)
(if (= n 1) 1
(* n (factorial (- n 1))))))
Well, this is just a function application with a single argument, so to evaluate this you simply evaluate, in some order, the function form and its argument.
Start with the function form:
(λ (factorial)
(factorial 10))
This just evaluates to a function which, when called, will:
create an environment e' which extends e with a binding of factorial to the argument of the function;
call whatever is bound to factorial with the argument 10 and return the result.
So now we have to evaluate the argument, again in the environment e:
(λ (n)
(if (= n 1) 1
(* n (factorial (- n 1)))))
This evaluates to a function of one argument which, when called, will:
establish an environment e'' which extends e with a binding of n to the argument of the function;
if the argument isn't 1, will try to call some function bound to a variable called factorial, looking up this binding in e''.
Hold on: what function? There is no binding of factorial in e, and e'' extends e (in particular, e'' does not extend e'), but by adding a binding of n, not factorial. Thus there is no binding of factorial in e''. So this function is an error: you will either get an error when it's evaluated or you'll get an error when it's called, depending on how smart the implementation is.
Instead, you need to do something like this to make this work:
(let ((factorial (λ (n) (error "bad doom"))))
(set! factorial
(λ (n)
(if (= n 1) 1
(* n (factorial (- n 1))))))
(factorial 10))
-->
((λ (factorial)
(set! factorial
(λ (n)
(if (= n 1) 1
(* n (factorial (- n 1))))))
(factorial 10))
(λ (n) (error "bad doom")))
This will now work. Again, it's a function application, but this time all the action happens in the function:
(λ (factorial)
(set! factorial
(λ (n)
(if (= n 1) 1
(* n (factorial (- n 1))))))
(factorial 10))
So, evaluating this in e results in a function which, when called will:
create an environment e', extending e, in which there is a binding of factorial to whatever its argument is;
mutate the binding of factorial in e', assigning a different value to it;
call the value of factorial in e', with argument 10, returning the result.
So the interesting step is (2): the new value of factorial is the value of this form, evaluated in e':
(λ (n)
(if (= n 1) 1
(* n (factorial (- n 1)))
Well, this again is a function which, when called, will:
create an environent, e'', which extends e' (NOTE!) with a binding for n;
if the value of the binding of n is not 1, call whatever is bound to factorial in the e'' environment.
And now this will work, because there is a binding of factorial in e'', because, now, e'' extends e' and there is a binding of factorial in e'. And, further, by the time the function is called, e' will have been mutated so that the binding is the correct one: it's the function itself.
And this is in fact more-or-less how letrec is defined. In a form like
(letrec ((a <f1>)
(b <f2>))
...)
First the variables, a and b are bound to some undefined values (it is an error ever to refer to these values). Then <f1> and <f2> are evaluated in some order, in the resulting environment (this evaluation should not refer to the values that a and b have at that point), and the results of these evaluations are assigned to a and b respectively, mutating their bindings and finally the body is evaluated in the resulting environment.
See for instance R6RS (other reports are similar but harder to refer to as most of them are PDF):
The <variable>s are bound to fresh locations, the <init>s are evaluated in the resulting environment (in some unspecified order), each <variable> is assigned to the result of the corresponding <init>, the <body> is evaluated in the resulting environment, and the values of the last expression in <body> are returned. Each binding of a <variable> has the entire letrec expression as its region, making it possible to define mutually recursive procedures.
This is obviously something similar to what define must do, and in fact I think it's clear that, for internal define at least, you can always turn define into letrec:
(define (outer a)
(define (inner b)
...)
...)
-->
(define (outer a)
(letrec ((inner (λ (b) ...)))
...))
And perhaps this is the same as
(letrec ((outer
(λ (a)
(letrec ((inner
(λ (b)
...)))
...)))))
But I am not sure.
Of course, letrec buys you no computational power (neither does define): you can define recursive functions without it, it's just less convenient:
(let ((facter
(λ (c n)
(if (= n 1)
1
(* n (c c (- n 1)))))))
(let ((factorial
(λ (n)
(facter facter n))))
(factorial 10)))
or, for the pure of heart:
((λ (facter)
((λ (factorial)
(factorial 10))
(λ (n)
(facter facter n))))
(λ (c n)
(if (= n 1)
1
(* n (c c (- n 1))))))
This is pretty close to the U combinator, or I always think it is.
Finally, it's reasonably easy to write a quick-and-dirty letrec as a macro. Here's one called labels (see the comments to this answer):
(define-syntax labels
(syntax-rules ()
[(_ ((var init) ...) form ...)
(let ((var (λ x (error "bad doom"))) ...)
(set! var init) ...
form ...)]))
This will work for conforming uses, but it can't make referring to the initial bindings of the variables is an error: calling them is, but they can leak out. Racket, for instance, does some magic which makes this be an error.
Let's start with my version of everyone's favorite mutually recursive example, even-or-odd.
(define (even-or-odd x)
(letrec ((internal-even? (lambda (n)
(if (= n 0) 'even
(internal-odd? (- n 1)))))
(internal-odd? (lambda (n)
(if (= n 0) 'odd
(internal-even? (- n 1))))))
(internal-even? x)))
If you wrote that with let instead of letrec, you'd get an error that internal-even? in unbound. The descriptive reason for why that is is that the expressions that define the initial values in a let are evaluated in a lexical environment before the variables are bound whereas letrec creates an environment with those variables first, just to make this work.
Now we'll have a look at how to implement let and letrec with lambda so you can see why this might be.
The implementation of let is fairly straightforward. The general form is something like this:
(let ((x value)) body) --> ((lambda (x) body) value)
And so even-or-odd written with a let would become:
(define (even-or-odd-let x)
((lambda (internal-even? internal-odd?)
(internal-even? x))
(lambda (n)
(if (= n 0) 'even
(internal-odd? (- n 1))))
(lambda (n)
(if (= n 0) 'odd
(internal-even? (- n 1))))))
You can see that the bodies of internal-even? and internal-odd? are defined outside the scope of where those names are bound. It gets an error.
To deal with this problem when you want recursion to work, letrec does something like this:
(letrec (x value) body) --> ((lambda (x) (set! x value) body) #f)
[Note: There's probably a much better way of implementing letrec but that's what I'm coming up with off the top of my head. It'll give you the idea, anyway.]
And now even-or-odd? becomes:
(define (even-or-odd-letrec x)
((lambda (internal-even? internal-odd?)
(set! internal-even? (lambda (n)
(if (= n 0) 'even
(internal-odd? (- n 1)))))
(set! internal-odd? (lambda (n)
(if (= n 0) 'odd
(internal-even? (- n 1)))))
(internal-even? x))
#f #f))
Now internal-even? and internal-odd? are being used in a context where they've been bound and it all works.
Exercise 1.16: Design a procedure that evolves an iterative exponentiation process that uses successive squaring and uses a logarithmic number of steps, as does fast-expt. (Hint: Using the observation that (b(^n/2))^2 = (b(^2))^n/2 , keep, along with the exponent n and the base b, an additional state variable a, and define the state transformation in such a way that the product ab^n is unchanged from state to state. At the beginning of the process a is taken to be 1, and the answer is given by the value of a at the end of the process. In general, the technique of defining an invariant quantity that remains unchanged from state to state is a powerful way to think about the design of iterative algorithms.)
So I've tried really hard and came up with this solution:
(define (exp b n)
(exp-iter b n 1))
(define (square p) (* p p))
(define (even? k)
(= (remainder k 2) 0))
(define (exp-iter b counter product)
(define (smash counter)
(if (even? counter) (square (exp-iter b (/ 2 counter) product)) (* b (exp-iter b (- counter 1) product))))
(if (= counter 0) product (smash counter)))
(exp 4 3) ;test
This runs perfectly but I'm not sure if this is what the author asked me to do. Are there any problems with this? Is my solution really iterative?
Your solution is not iterative. An iterative process is one that doesn't call anything after the recursive call, and that's not the case in these two lines:
(square (exp-iter b (/ 2 counter) product))
(* b (exp-iter b (- counter 1) product))
After invoking exp-iter, in the first line you're passing the result to square, and in the second line you're multiplying the result by b. Compare it with this, a tail recursive solution:
(define (exp-iter b counter product)
(cond ((= counter 0)
product)
((even? counter)
(exp-iter (square b) (/ counter 2) product))
(else
(exp-iter b (- counter 1) (* b product)))))
Notice that after invoking exp-iter there's nothing left to do and the procedure simply returns its value. A smart compiler will detect this, and transform the recursive call into a loop that will use a constant amount of stack memory (instead of increasing with every recursive call.)
Write a tail recursive function called popadd that models a population with P people at time t = 0 and adds d people per year.
(define (popadd t P)
(if (= t 0)
P
(+(popadd( - t 1) P)d))
)
but, of course, I get the error that d hasn't been defined yet, which is true. I tried adding it as an input, but as a return I get the number inserted for D.
You can simply pass along another parameter to the recursion:
(define (popadd t P d)
(if (= t 0)
P
(+ d (popadd (- t 1) P d))))
Or you can define the value, to avoid passing it around - assuming it doesn't need to change:
(define d 100)
(define (popadd t P)
(if (= t 0)
P
(+ d (popadd (- t 1) P))))
Notice that you could do the same with P, if it's ok. It really depends on what's the expected contract for the procedure.
Note that neither your code nor the code in the other answer is tail-recursive: in a recursive call like (+ (f ...)), f is not in tail position. To make the code tail-recursive you need the result of the recursive call be the result of the overall call (so in the above example, + is in tail position). To do this you need an auxiliary function. Here is a way of doing it which relies only on local define:
(define (popadd t P d)
(define (popadd-loop tau pop)
(if (zero? tau)
pop
(popadd-loop (- tau 1) (+ pop d))))
(popadd-loop t P))
Here is essentially the same thing using named-let, which is nicer:
(define (popadd t P d)
(let popadd-loop ([tau t] [pop P])
(if (zero? tau)
pop
(popadd-loop (- tau 1) (+ pop d)))))
Finally note that this problem has a closed-form solution:
(define (popadd t P d)
(+ P (* t d)))
I really wish that people trying to teach programming knew enough maths to not set problems which have trivial closed-form answers, as doing so encourages people to write inefficient (in the complexity-class sense) code. Obviously this is not your fault: it's your teacher's.
I basically need to do a iterative version of the following function which i've already made:
(define (expo base e)
(cond ((or (= base 1) (= e 0)) 1)
(else (* base (expo base (- e 1))))))
im not sure how to so i need help(in racket/scheme))
The general pattern with converting such recursive functions to iteration is to use an accumulator
(define (expo base e)
(define (go base e accum)
(if (or (= base 1) (= e 0))
accum
(go base (- e 1) (* accum base)))) ; Now this is tail recursion
???)
Where ??? calls go with the appropriate initial value of accum. Notice how before the recusive call was inside another call (namely *) but now it's the last thing called. This allows for the program to run in constant space.
All you have to do is pass the result around in an accumulator. For that you need an extra parameter, there are several ways to do it, for example using an inner helper procedure:
(define (expo base e)
; helper procedure
(define (iter e acc)
; now the base case returns the accumulator
(cond ((or (= base 1) (= e 0)) acc)
; see how the result is accumulated in the parameter
(else (iter (- e 1) (* base acc)))))
; at the beginning, initialize the parameter in the right values
(iter e 1))
Alternatively, we can use a named let for the same effect:
(define (expo base e)
(let iter ((e e) (acc 1))
(cond ((or (= base 1) (= e 0)) acc)
(else (iter (- e 1) (* base acc))))))
It's good to differentiate between recursive procedures and processes. Both of the above implementations are recursive procedures: syntactically, it's easy to see that they call themselves. But the processes they generate are iterative: they're written in a tail recursive style, so after each recursive call ends there's nothing left to do, and the compiler can optimize away the recursive call and, for all practical purposes, transform it into an iterative loop.
To better understand how iteration works in Scheme read more about this subject in the fantastic SICP book, in the section Procedures and the Processes They Generate
As others have noted, a tail recursive algorithm is an iterative algorithm. However, perhaps you need an explicit iterative algorithm?
(define (expo base exp)
(do ((acc 1 (* acc base))
(exp exp (- exp 1)))
((= 0 exp) acc))))
One could add a condition for (= base 1) - but, as written, this is a simple as it gets. Assumes exp is an integer.
I was trying to implement Fermat's primality test in Scheme.
I wrote a procedure fermat2(initially called fermat1) which returns true
when a^p-1 congruent 1(mod p) (please read it correctly guys!!)
a
every prime p number should satisfy the procedure (And hence Fermat's little theorem .. )
for any a
But when I tried to count the number of times this procedure yields true for a fixed number of trials ... ( using countt procedure, described in code) I got shocking results ans
So I changed the procedure slightly (I don't see any logical change .. may be I'm blind) and named it fermat1(replacing older fermat1 , now old fermat1 ->fermat2) and it worked .. the prime numbers passed the test all the times ...
why on earth the procedure fermat2 called less number of times ... what is actually wrong??
if it is wrong why don't I get error ... instead that computation is skipped!!(I think so!)
all you have to do , to understand what I'm trying to tell is
(countt fermat2 19 100)
(countt fermat1 19 100)
and see for yourself.
Code:
;;Guys this is really weird
;;I might not be able to explain this
;;just try out
;;(countt fermat2 19 100)
;;(countt fermat1 19 100)
;;compare both values ...
;;did you get any error using countt with fermat2,if yes please specify why u got error
;;if it was because of reminder procedure .. please tell your scheme version
;;created on 6 mar 2011 by fedvasu
;;using mit-scheme 9.0 (compiled from source/microcode)
;; i cant use a quote it mis idents (unfriendly stack overflow!)
;;fermat-test based on fermat(s) little theorem a^p-1 congruent to 1 (mod p) p is prime
;;see MIT-SICP,or Algorithms by Vazirani or anyother number theory book
;;this is the correct logic of fermat-test (the way it handles 0)
(define (fermat1 n)
(define (tryout a x)
;; (display "I've been called\n")
(= (remainder (fast-exp a (- x 1)) x) 1))
;;this exercises the algorithm
;;1+ to avoid 0
(define temp (random n))
(if (= temp 0)
(tryout (1+ temp) n)
(tryout temp n)))
;;old fermat-test
;;which is wrong
;;it doesnt produce any error!!
;;the inner procedure is called only selective times.. i dont know when exactly
;;uncomment the display line to see how many times tryout is called (using countt)
;;i didnt put any condition when it should be called
;;rather it should be every time fermat2 is called
;;how is it so??(is it to avoid error?)
(define (fermat2 n)
(define (tryout a x)
;; (display "I've been called\n")
(= (remainder (fast-exp a (- x 1)) x) 1))
;;this exercises the algorithm
;;1+ to avoid 0
(tryout (1+ (random n)) n))
;;this is the dependency procedure for fermat1 and fermat2
;;this procedure calculates base^exp (exp=nexp bcoz exp is a keyword,a primitive)
;;And it is correct :)
(define (fast-exp base nexp)
;;this is iterative procedure where a*b^n = base^exp is constant always
;;A bit tricky though
(define (logexp a b n)
(cond ((= n 0) a);;only at the last stage a*b^n is not same as base^exp
((even? n) (logexp a (square b) (/ n 2)))
(else (logexp (* a b) b (- n 1)))))
(logexp 1 base nexp))
;;utility procedure which takes a procedure and its argument and an extra
;; argument times which tells number of times to call
;;returns the number of times result of applying proc on input num yielded true
;;counting the number times it yielded true
;;procedure yields true for fixed input,
;;by calling it fixed times)
;;uncommenting display line will help
(define (countt proc num times)
(define (pcount p n t c)
(cond ((= t 0)c)
((p n );; (display "I'm passed by fermat1\n")
(pcount p n (- t 1) (+ c 1)));;increasing the count
(else c)))
(pcount proc num times 0))
I had real pain .. figuring out what it actually does .. please follow the code and tell why this dicrepieancies?
Even (countt fermat2 19 100) called twice returns different results.
Let's fix your fermat2 since it's shorter. Definition is: "If n is a prime number and a is any positive integer less than n, then a raised to the nth power is congruent to a modulo n.". That means f(a, n) = a^n mod n == a mod n. Your code tells f(a, n) = a^(n-1) mod n == 1 which is different. If we rewrite this according to definition:
(define (fermat2 n)
(define (tryout a x)
(= (remainder (fast-exp a x) x)
(remainder a x)))
(tryout (1+ (random n)) n))
This is not correct yet. (1+ (random n)) returns numbers from 1 to n inclusive, while we need [1..n):
(define (fermat2 n)
(define (tryout a x)
(= (remainder (fast-exp a x) x)
(remainder a x)))
(tryout (+ 1 (random (- n 1))) n))
This is correct version but we can improve it's readability. Since you're using tryout only in scope of fermat2 there is no need in parameter x to pass n - latter is already bound in scope of tryout, so final version is
(define (fermat n)
(define (tryout a)
(= (remainder (fast-exp a n) n)
(remainder a n)))
(tryout (+ 1 (random (- n 1)))))
Update:
I said that formula used in fermat2 is incorrect. This is wrong because if a*k = b*k (mod n) then a = b (mod n). Error as Vasu pointed was in generating random number for test.