What am I doing wrong with Scheme? - scheme

When I enter the following:
(define (root a b c)
(/ (+ (-b) (sqrt (- (exp b 2) (* 4 a c)))) (* 2 a)))
and then enter:
(root 3 6 2)
I get a message indicating that the procedure had two arguments but only requires exactly one. What am I doing wrong?

The exp function doesn't do exponents really, it does something else mathy. (I don't know.)
What you want is usually called pow for "power" but probably isn't defined in your environment, so I suggest you just define your own square method:
(define (square x) (* x x))
And then:
(define (root a b c)
(/ (+ (- b) (sqrt (- (square b) (* 4 a c)))) (* 2 a)))
Edit: Oh, you'll also have to change a couple spacing issues, like (* 4 a c) instead of (*4 a c), and (- b) instead of (-b). You always have to separate the operator from the operands with spaces.

The procedure exp raises the number e to the power of its argument, if you need to raise an argument to the power of another argument, use expt. Even better, given that you only need to square b, a simple multiplication will do. Like this:
(define (root a b c)
(/ (+ (- b) (sqrt (- (* b b) (* 4 a c))))
(* 2 a)))

The function the error refers to is exp which takes only one argument. The exp function calculates the exponential function, not an exponent. You want expt, which raises a root x to the exponent y:
(expt b 2)
You can also just multiply the number times itself.
I usually keep R5RS or The Scheme Programming Language on hand since these basic functions can be hard to keep straight.

Related

Scheme: Proabably a typo in SICP. 1.3.2. Am I right?

In SICP, (1.3.2. page: 62), there is a solution for finding pi-sum using lambda. The solution is:
(define (pi-sum a b)
(sum (lambda (x) (/ 1.0 (* x (+ x 2))))
a
(lambda (x) (+ x 4))
b))
However, I feel there should be a bracket enclosing ((lambda (x) (+ x 4) b). The program as such produces an error saying sum is expecting a number but getting a procedure.
Modifying the above code is giving no error.
(define (pi-sum a b)
(sum ((lambda (x) (/ 1.0 (* x (+ x 2))))
a)
((lambda (x) (+ x 4))
b)))
Please correct me if my understanding is wrong. I assume the book cannot be wrong.
The pi-sum procedure in the book is making use of the higher-order procedure sum, defined earlier in 1.3.1. The sum procedure takes a and b as arguments which describe the bounds of the summation, and it takes term and next as arguments which describe how to create a term from a, and how to get the next a from the current a. Both term and next need to be procedures. Here is the definition of sum from the book:
(define (sum term a next b)
(if (> a b)
0
(+ (term a)
(sum term (next a) next b))))
If you add parentheses in the definition of pi-sum, you should get an exception because sum requires four arguments, but now only two are passed. I am not sure why you are getting an error like "sum is expecting a number but getting a procedure", but I suspect that you have a different definition for sum than the one intended by the book.

dont understood lambda expression on scheme

i try to realize what this expiration, and don't get it.
( lambda (a b) (lambda (x y) (if b (+ x y a) (-x y a)))
i think,
a is a number, and b is #t or #f,
on the if statement we ask if b is true, if yes return first expression(sum 3 numbers), else the second(Subtract 3 numbers)
what i need to write on Racket to run this?
i try
(define question( lambda (a b) (lambda (x y) (if b (+ x y a) (-x y a)))))
and than
(question 5 #f)
and nothing not going well in this language.
This is not a complete answer as I don't want to do your homework for you.
First of all formatting and indenting your code is going to help you in any programming language. You almost certainly have access to an editor which will do this. Below I've done this.
So, OK, what does a form like (λ (...) ...) denote? Well, its a function which takes some arguments (the first ellipsis) and returns the value of the last form in its body (the second ellipsis), or the only form in its body in a purely functional language.
So, what does:
(λ (a b)
(λ (x y)
...))
Denote? It's a function of two arguments, and it returns something: what is the thing it returns? Well, it's a form which looks like (λ (...) ...): you know what those forms mean already.
And finally we can fill out the last ellipsis (after correcting an error: (-x ...) is not the same as (- x ...)):
(λ (a b)
(λ (x y)
(if b
(+ x y a)
(- x y a))))
So now, how would you call this, and how would you make it do something interesting (like actually adding or subtracting some things)?
(lambda (a b) (lambda (x y) (if b (+ x y a) (- x y a))))
is a function that takes two arguments (that's what (lambda (a b) ...) says).
You can use the substitution method to discover what it produces.
Apply it to 5 and #f:
((lambda (a b) (lambda (x y) (if b (+ x y a) (- x y a)))) 5 #f)
[Replace a with 5 and b with #f in the body]:
(lambda (x y) (if #f (+ x y 5) (- x y 5)))
And this is a function that takes two numbers and produces a new number.
(Note that the #f and the 5 became fixed by the application of the outer lambda.)
It's easier to use the function if we name it (interactions from DrRacket):
> (define question (lambda (a b) (lambda (x y) (if b (+ x y a) (- x y a)))))
> (question 5 #f)
#<procedure>
which is as expected, based on the reasoning above.
Let's name this function as well:
> (define answer (question 5 #f))
and use it:
> (answer 3 4)
-6
or we could use it unnamed:
> ((question 5 #f) 3 4)
-6
or you could do it all inline, but that's a horrible unreadable mess:
> (((lambda (a b) (lambda (x y) (if b (+ x y a) (- x y a)))) 5 #f) 3 4)
-6

Make procedure in Scheme by lambda

I am learning Scheme by 'Structure and Interpretation of Computer Programs'
In Chapter 1.3.2 Constructing Procedures Using lambda.
I understood lambda like this.
The value to match the lambda is written outside the parenthesis of the lambda.
((lambda (x) (+ x 4) 4) ; (x) is matched to 4, result is 8
But in SICP, another example code is different.
The code is :
(define (sum x y) (+ x y))
(define (pi-sum a b)
(sum (lambda (x) (/ 1.0 (* x (+ x 3))))
a
(lambda (x) (+ x 4))
b
))
(pi-sum 3 6)
I think if (lambda (x) (/ 1.0 (* x (+ x 3)))) want match to a, lambda and a must bound by parenthesis.
But in example code, don't use parenthesis.
When I run this code, error is occurs.
error is this :
***'sum: expects only 2 arguments, but found 4'***
When I use more parenthesis like this :
(define (sum x y) (+ x y))
(define (pi-sum a b)
(sum ((lambda (x) (/ 1.0 (* x (+ x 3))))
a)
((lambda (x) (+ x 4))
b)
))
(pi-sum 2 6) ; result is 10.1
Code is run.
I'm confused because of SICP's example code.
Am I right on the principle of lambda?
If I am right, why SICP write like that?
It says to use the sum from 1.3.1. On page 77 (actually starting on 77 and ending on 78) it looks like this:
(define (sum term a next b)
(if (> a b)
0
(+ (term a)
(sum term (next a) next b))))
As you can see it looks a lot different from your sum that just adds two number together. You also had a typo in pi-sum:
(define (pi-sum a b)
(sum (lambda (x) (/ 1.0 (* x (+ x 2)))) ; multiplied by 2, not 3!
a
(lambda (x) (+ x 4))
b))
(* 8 (pi-sum 1 1000))
; ==> 3.139592655589783
So the point here is that you can pass lambdas instead of named procedures. Since (define (name . args) body ...) is just syntax sugar for (define name (lambda args body ...)) passing (lambda args body ...) instead of defining it and pass a name is just an equal refactoring.
Parentheses around a variable (+) or a lambda ((lambda args body ...)) calls whatever procedure the operator expression evaluates. It is not what you want since you pass procedures to be used by sum as an abstraction. sum can do multiplications or any number of things based on what you pass. in sum term is the procedure (lambda (x) (/ 1.0 (* x (+ x 2)))) and you see it calls it as apart of its code.

Scheme result of a function

I have met the following code in Scheme:
(define x!
(lambda(x)
(if (= x 1) 1 (* x (x! (- x 1))))))
(define fact x!)
(define x! (lambda (x) x))
(fact 5)
Everything is clear for me until re-defining x! and seeing the result of the function (20).
How can it be explained?.. Why is it 20 and not 5!= 120.
Thanks in advance
Here's what's happening:
When you (define fact x!), you aren't permanently linking fact to x!. You're making fact equal to whatever x! is at the time of fact's definition.
So (define fact x!) is actually equivalent to:
(define fact
(lambda(x)
(if (= x 1) 1 (* x (x! (- x 1))))))
Next, you redefine x!:
(define x! (lambda (x) x))
But that does not change fact - it only changes x!. Next, you do this:
(fact 5)
Here's what the interpreter 'does' next (it may actually do it slightly differently - but only trivially so, and this should at least help you understand the behaviour of your program):
Replacing fact with its definition gives:
(lambda(x)
(if (= x 1) 1 (* x (x! (- x 1)))))
Replacing x! with its new definition gives:
((lambda(x)
(if (= x 1)
1
(* x
(- ((lambda (x)
x)
x)
1))))
5)
...Simplifying gives:
((lambda(x)
(if (= x 1)
1
(* x (- x 1))))
5)
...
(if (= 5 1)
1
(* 5 (- 5 1)))
...
(if #f
1
(* 5 (- 5 1)))
...Resolving the conditional and simplifying the substraction gives:
(* 5 4)
...Which yields 20.
The way Scheme behaves when you have a redefinition of an identifier is to use set! for it. In your case, if you replace the redefinition with
(set! x! (lambda (x) x))
then the result will become clearer.
(Note that this is not something that all schemes do...)
first you define x! to be the way to compute factorial (i.e. (x! 5) = 120).
Then you define fact to be what x! is, which is the same function (i.e. fact = lambda(x) (if (= x 1)...
Then you change what x! is the identity. However, fact is still that same function, you didn't change it, but that function references x! internally, so it ends up calling fact (which is the first thing you defined) which calls the identity function.
so (fact 5) is the same as:
(if (= 5 1) 1 (* 5 (x! (- 5 1))))))
which is the same as:
(if false 1 (* 5 (x! 4)))
which is the same as:
(if false 1 (* 5 4))
which is the same as:
(* 5 4)
which is 20
Ok, what happens here is the following:
When you do (x! (- x 1)) inside the original definition of x!, you're calling the function named x!. So if you change what the name x! means, that will affect this call to x!.
When you do (define fact x!) fact doesn't refer to the name x!, but to the current contents of x!, i.e. the function you just defined.
Now you change the meaning of the name x! and then call (fact 5). This will first invoke the original definition of x! (because that's what fact refers to), however when it gets to the call (x! (- 5 1)), it invokes the new definition of x!, which returns 4, so you get 5*4 = 20.
One side note: You need to use an environment model to figure it out.Because the answer of questions like that differs in lexical scoping versus dynamic scoping.

SICP exercise 1.16, where is my bug, because it looks right to me

I've just started working through this book for fun; I wish it were homework, but I could never afford to attend MIT, and there are tons of people smarter than me anyway. :p
fast-exp is supposed to find b^n, i.e. 4^2 = 16, 3^3 = 27
(define (fast-exp b n)
(define (fast-exp-iter n-prime a)
(cond ((= n-prime 1) a)
((= (remainder n-prime 2) 1) (fast-exp-iter (- n-prime 1) (* a b)))
(else (fast-exp-iter (/ n-prime 2) (* a b b)))))
(fast-exp-iter n 1))
fast-exp 4 2; Expected 16, Actual 2
You forgot to call fast-exp. Instead, you evaluated three separate atoms. To actually evaluate the fast-exp of 4 to the 2, you'd have to write
(fast-exp 4 2)
The solution you have written here is also incorrect. e.g. Check out (fast-exp 2 6). Expected: 64, actual: 32.
Your solution is calculating wrong answers. (See http://ideone.com/quT6A) In fact, how you in principle can write a tail-recursive fast exponentiation passing only two numbers as arguments? I don't think it's even possible, because in the middle of computation you don't know what multiplier to use if you encounter odd exponent.
But I can give an example of working solution that is exactly what is expected by SICP authors (iterative process using "invariant quantity" (a * b^n), where a is initially 1)
(define (pow x y)
(define (powi acc x y)
(cond
((= y 0) acc)
((odd? y) (powi (* acc x) x (- y 1)))
(else (powi acc (* x x) (/ y 2)))))
(powi 1 x y))

Resources