I am reading Newton's method in SICP, where he introduce the block structure which have the function nested, say
(define (sqrt x)
(define (good enough ? guess x)
(<(abs(-(square guess) x)) 0.001))
(define (improve guess x)
(average guess (/ x guess)))
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter(improve guess x)x)))
(sqrt-iter 1.0 x))
I am quite confused because in my understanding of nested, "good enough ?" and "improve guess" should be nested
in the body of "sqrt-iter", and "sqrt iter" should be put in the body of "sqrt x"
(define (sqrt x)
(sqrt-iter 1.0 x
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter(improve guess x)x)
(define (good enough ? guess x)
(<(abs(-(square guess) x)) 0.001))
(define (improve guess x)
(average guess (/ x guess)))
))
))
why it is not like that.I am using LISP
Notice that sqrt-iter is already defined inside the body of sqrt. But the way you wrote it doesn't make sense, you're trying to call sqrt-iter but you're defining it inside the call as a third parameter. This isn't right:
(sqrt-iter 1.0 x (define (sqrt-iter ...)))
You must define it before calling it, and you can't define it as if it were a parameter, as part of the procedure call. This is the correct way:
(define (sqrt-iter guess x) ...) ; first define
(sqrt-iter 1.0 x) ; after defining, you can call it
Your other suggestion makes more sense, it'd be possible to define good-enough? and improve inside sqrt-iter, but maybe it's clearer in the way they wrote it in the book. This is valid, but has the disadvantage that good-enough? and improve will be redefined each time sqrt-iter is called:
(define (sqrt x)
(define (sqrt-iter guess x)
(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.001))
(define (improve guess x)
(average guess (/ x guess)))
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x)x)))
(sqrt-iter 1.0 x))
You should read more carefully the section of the book that explains how procedures are defined and used in Scheme, you seem to be confusing concepts, mixing parameters, procedure definitions and procedure invocations.
Related
I would like to see how the value of a square root is iteratively improved. For example on the following:
#lang sicp
(define (square x) (* x x))
(define (average x y) (/ (+ x y) 2))
(define (improve guess x) (average guess (/ x guess)))
(define (good-enough? guess x) (< (abs (- (square guess) x)) 0.001 ))
(define (sqrt-iter guess x) (if (good-enough? guess x) guess (sqrt-iter (improve guess x) x)))
(define (sqrt x) (sqrt-iter 1.0 x))
(sqrt 2)
It gets values such as the following:
1 1
2 1.5
3 1.4166666666666665
4 1.4142156862745097
As an example of what I want to show, in Javascript I would do something like:
const sqrt_iter = (guess, x) => {
console.log(count++, guess);
return good_enough(guess, x) ? guess : sqrt_iter(improve(guess, x), x);
}
const sqrt = x => sqrt_iter(1.0, x);
How could I print or trace these intermediate values in DrRacket/SICP? I tried doing (trace sqrt) but it said not found.
I am sure Racket has some fancy trace facility. But there's a famous quote (due I think to John Foderaro):
Lisp [for which read Racket] is the programmable programming language.
What this means is: if there's no tracing facility, or you are too lazy to make one, you can just write one.
Here is a rudimentary one I wrote in five minutes:
#lang racket
(provide define/traced)
(define trace-depths (make-parameter 0))
(define (spaces n)
(make-string n #\ ))
(define-syntax define/traced
(syntax-rules ()
[(_ (name arg ...) form ...)
(define/traced name (λ (arg ...) form ...))]
[(_ (name . args) form ...)
(define/traced name (λ args form ...))]
[(_ name function)
(define name
(λ args
(let* ([depth (trace-depths)]
[prefix (spaces depth)])
(parameterize ([trace-depths (+ depth 1)])
(printf "~A~S ...~%" prefix `(,'name ,#args))
(call-with-values
(thunk (apply function args))
(λ results
(printf "~A-> ~S~%" prefix results)
(apply values results)))))))]))
Stash this in a file called define-traced.rkt and then require it, and tell it to trace the procedures you care about:
#lang racket
(require "define-traced.rkt")
(define (square x) (* x x))
(define (average x y) (/ (+ x y) 2))
(define/traced (improve guess x) (average guess (/ x guess)))
(define (good-enough? guess x) (< (abs (- (square guess) x)) 0.001 ))
(define/traced (sqrt-iter guess x) (if (good-enough? guess x) guess (sqrt-iter (improve guess x) x)))
(define (sqrt x) (sqrt-iter 1.0 x))
(sqrt 2)
Which will duly print this:
(sqrt-iter 1.0 2) ...
(improve 1.0 2) ...
-> (1.5)
(sqrt-iter 1.5 2) ...
(improve 1.5 2) ...
-> (1.4166666666666665)
(sqrt-iter 1.4166666666666665 2) ...
(improve 1.4166666666666665 2) ...
-> (1.4142156862745097)
(sqrt-iter 1.4142156862745097 2) ...
-> (1.4142156862745097)
-> (1.4142156862745097)
-> (1.4142156862745097)
-> (1.4142156862745097)
1.4142156862745097
Note that when I said it was a rudimentary facility I meant it: in particular it will probably turn tail calls into non-tail calls, and there are many other things wrong with it. But it took less long to write than it would take to read the manual on some hairy facility. If I was going to use this thing just once (and this is probably the only time I will ever use it: it only made it into a file so I could require it in another file) it's worth it. This is one of the glories of Lisp-family languages.
Try begin with printf (and also add one variable as counter):
#lang racket
(define (square x)
(* x x))
(define (average x y)
(/ (+ x y) 2))
(define (improve guess x)
(average guess (/ x guess)))
(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.001 ))
(define (sqrt-iter guess x count)
(begin
(printf "~a ~a \n" count guess)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x)
x
(+ 1 count)))))
(define (sqrt x) (sqrt-iter 1.0 x 1))
(sqrt 2)
1 1.0
2 1.5
3 1.4166666666666665
4 1.4142156862745097
1.4142156862745097
Note that I used #lang racket- it seems that sicp don't have print or printf, but you can try write or display to achieve similar result.
#ignis provides the proper technique for this. However, before you dive into the deep ocean of define-syntax, maybe you want the quick-and-dirty approach -
#lang sicp
(define (sqrt-iter guess x)
(for-each display (list "sqrt-iter" " " guess " " x "\n"))
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))
(sqrt 2)
sqrt-iter 1.0 2
sqrt-iter 1.5 2
sqrt-iter 1.4166666666666665 2
sqrt-iter 1.4142156862745097 2
1.4142156862745097
When I write code in Dr Racket, I got error message
unsaved-editor:8:2: define: expected only one expression for the
function body, but found 3 extra parts in: (define (improve guess x)
(average guess (/ x guess)))
But this code can run in Racket or repl.it.
I want to know why error is happening in Dr Racket and is my code really wrong?
My code is this:
(define (average x y) (/ (+ x y) 2))
(define (square x) (* x x))
(define (sqrt1 x)
(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.001))
(define (improve guess x)
(average guess (/ x guess)))
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))
(sqrt-iter 1.0 x))
(sqrt1 9)
Your code is OK for Scheme/Racket. However Student Language is a subset of Scheme, highly limited so it's easier for beginners. It's also used in How To Design Programs book. You can read more about Student Languages (actually there is five of them) on https://docs.racket-lang.org/htdp-langs/index.html.
In case of define there are important limitations:
You can have only one expression in the function body.
In function body you can only use expressions, not definitions (so no define inside define).
To make your code valid for Student Language, depending on Level (Beginner, Intermediate etc), you can:
use letrec* or local instead of define for all local definitions
or
define good-enough, improve and sqrt-iter as top level functions.
(define (complex-num x y)
(cons x y))
(define (real x)
(car x))
(define (imag x)
(cdr x))
Is it right? Or maybe you can suggest a better way to do it.
Yes, that's a correct way to represent complex numbers in Scheme. It's also possible to alias the procedures, because you're calling them directly:
(define complex-num cons)
(define real car)
(define imag cdr)
... But it's a matter of taste, and anyway your solution is easier to understand.
(define (sqrt x)
(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.001))
(define (improve guess x)
(average guess (/ x guess)))
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))
(sqrt-iter 1.0 x))
I can't seem to wrap my head around around internal block structure. If the syntax for define is: (define procedure arg arg body). How are you able to define all the other local-scope variables inside the top-level define?
Is there a syntax exception for defines?
The syntax for define is not (define procedure arg .. body). It is either (define (name . args) defines ... body1 bodyn ...) which is a shortcut for (define name (lambda args defines ... body1 bodyn ...)). Note that x ... means zero or more so (lambda (a b) (+ a b)) is fine but (lambda (a b) (define (test) (+ a b))) isn't.
Internal define is handled by the lambda syntax. Basically it gets rewritten to a letrec. So
(define (sqrt x)
(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.001))
(define (improve guess x)
(average guess (/ x guess)))
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))
(sqrt-iter 1.0 x))
Becomes:
(define sqrt
(lambda (x)
(letrec ((good-enough? (lambda (guess x)
(< (abs (- (square guess) x)) 0.001)))
(improve (lambda (guess x)
(average guess (/ x guess))))
(sqrt-iter (lambda (guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))))
(sqrt-iter 1.0 x))))
Obviously the reason for using local define is to keep it flatter and more readable than letrec. Keeping the same name even though they are totally different beasts that are handled by different parts of the implementation is a simplification for scheme programmers but harder to grasp and understand if you try to figure out how scheme implementations work.
I try to do a program that calculates the square of a number in Scheme but it gives me as an error that I gave the abs procedure two arguments instead of one. This is my first program in Scheme and have no clue how to do it. I tried to change the position of the brackets but it doesn't work.
(define (square X)
(try 1 X))
(define (try guess X)
(if (good-enaugh? guess X)
guess
((try improve guess X) X)))
(define (good-enaugh? guess X)
(< (abs(- (* guess guess) X)) 0.0001))
(define (improve guess X)
(/(+ (/ X guess) guess) 2))
You are almost there. The problem is that the second branch of your conditional in try has a pair of parentheses too much.
(define (try guess X)
(if (good-enaugh? guess X)
guess
((try improve guess X) X)))
Should become:
(define (try guess X)
(if (good-enaugh? guess X)
guess
(try (improve guess X) X)))
You make a call to the function try. The first parameter is the result of (improve guess X) and the second argument is the number X. Notice that I also changed the parenthesis around the call to improve. The way you wrote it was calling the function try with as first argument the function improve, second argument guess and third argument X.
Full source
For good measure the complete source is listed below.
(define (square X)
(try 1 X))
(define (try guess X)
(if (good-enaugh? guess X)
guess
(try (improve guess X) X)))
(define (good-enaugh? guess X)
(< (abs(- (* guess guess) X)) 0.0001))
(define (improve guess X)
(/(+ (/ X guess) guess) 2))
> (square 13)
3,....
Link to repl.it