How to step through this evaluation? - scheme

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

Related

Nested function in programing

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.

Scheme R5RS contract violation

The code below is the answer given by the professor for a question in my intro to scheme course but it comes out with an error. Cannot see why.
#!r5rs
(define (make-complex a b) (cons a b))
(define (real x) (car x))
(define (imag x) (cdr x))
(define (complex-sqrt x)
(define (sgn v)
(cond ((< v 0) -1)
((= v 0) 0)
(else 1)))
(let ((root (sqrt (+ (* (real x) (real x))
(* (imag x) (imag x))))))
(make-complex (sqrt (/ (+ (real x) root) 2))
(* (sgn (imag x))
(sqrt (/ (- root (real x)) 2))))))
(complex-sqrt 7)
;; ERROR mcar: contract violation
;; expected: mpair?
;; given: 7
I took a screenshot of the error with trace illustartion while running it in DrRacket.
Here's your code transcribed. Please consider posting the actual code rather than a screenshot in future.
(define (make-complex a b) (cons a b))
(define (real x) (car x))
(define (imag x) (cdr x))
(define (complex-sqrt x)
(define (sgn v)
(cond ((< v 0) -1)
((= v 0) 0)
(else 1)))
(let ((root (sqrt (+ (* (real x) (real x))
(* (imag x) (imag x))))))
(make-complex (sqrt (/ (+ (real x) root) 2))
(* (sgn (imag x))
(sqrt (/ (- root (real x)) 2))))))
Was the (complex-sqrt 7) part provided by your professor too? We're trying to get the square root of a complex number, so we should pass in a complex number:
(complex-sqrt (make-complex 5 2))
'(2.27872385417085 . 0.43884211690225433)
Which according to https://www.wolframalpha.com/input/?i=sqrt(2i%2B5) is correct!
The implementation of complex-sqrt is an unsafe one. What that means is that it assumes you pass it a complex number, in this case something created with make-complex.
To fix this you need to check if the argument is complex:
;; Not 100%. Should use `struct` to not
;; mix with random pairs that happens to have numeric parts
(define (complex? x)
(and (pair? x)
(number? (car x))
(number? (cdr x))))
;; The original code is renamed to unsafe-complex-sqrt
(define (complex-sqrt x)
(if (complex? x)
(unsafe-complex-sqrt x)
(raise-argument-error 'complex-sqrt "complex?" x)))
Now you can test it:
(complex-sqrt (make-complex 7 0))
; ==> (2.6457513110645907 . 0)
(complex-sqrt 7)
; ERROR complex-sqrt: contract violation
; expected: complex?
; given: 7
Perfect. Now it says you have mot passed the required complex number to a function that requires a complex number to work.
So what happend in the original code?
In unsafe-complex-sqrt it uses car and cdr which are safe operations that signal contract violation if the argument x supplied isn't #t for (pair? x).
Racket uses mcons in its #!r5rs implementation and thus the errors refer to every pair/list function in R5RS prefixed with an m since the error doesn't pay attention to renaming.

Internal Definitions in Block Structure

(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.

Distributive Law Simplification

I'm trying to write a procedure that makes use of the distributive property of an algebraic expression to simplify it:
(dist '(+ x y (exp x) (* x 5) y (* y 6)))
=> (+ (* x (+ 1 5))
(* y (+ 1 1 6))
(exp x))
(dist '(+ (* x y) x y))
=> (+ (* x (+ y 1))
y)
; or
=> (+ (* y (+ x 1))
x)
As the second example shows, there can be more than one possible outcome, I don't need to enumerate them all, just a valid one. I'm wondering if someone could provide me with at least a qualitative description of how they would start attacking this problem? Thanks :)
Oleg Kiselyov's pmatch macro makes distributing a factor across terms pretty easy:
(define dist
(λ (expr)
(pmatch expr
[(* ,factor (+ . ,addends))
`(+ ,#(map (λ (addend)
(list factor addend))
addends))]
[else
expr])))
(dist '(* 5 (+ x y))) => (+ (5 x) (5 y))
The main trick is to match a pattern and extract elements from the expression from the corresponding slots in the pattern. This requires a cond and let with tricky expressions to cdr to the right place in the list and car out the right element. pmatch writes that cond and let for you.
Factoring out common terms is harder because you have to look at all the subexpressions to find the common factors and then pull them out:
(define factor-out-common-factors
(λ (expr)
(pmatch expr
[(+ . ,terms) (guard (for-all (λ (t) (eq? '* (car t)))
terms))
(let ([commons (common-factors terms)])
`(* ,#commons (+ ,#(remove-all commons (map cdr terms)))))]
[else
expr])))
(define common-factors
(λ (exprs)
(let ([exprs (map cdr exprs)]) ; remove * at start of each expr
(fold-right (λ (factor acc)
(if (for-all (λ (e) (member factor e))
exprs)
(cons factor acc)
acc))
'()
(uniq (apply append exprs))))))
(define uniq
(λ (ls)
(fold-right (λ (x acc)
(if (member x acc)
acc
(cons x acc)))
'()
ls)))
(factor-out-common-factors '(+ (* 2 x) (* 2 y)))
=> (* 2 (+ (x) (y)))
The output could be cleaned up some more, this doesn't cover factoring out a 1, and remove-all is missing, but I'll leave all that to you.
A very general approach:
(dist expr var-list)
=> expr factored using terms in var-list
dist would have to know about "distributable" functions like +,-,*,/,etc and how each of them behave. If, say, it only knew about the first four, then :
(dist expr var-list
(if (empty? var-list) expr
(let* ([new-expr (factor expr (first var-list))])
(return "(* var " (dist new-expr (rest var-list)))))
That "return "(* var " " is not correct syntax, but you probably already knew that. I'm not a racket or lisp expert by any means, but basically this comes down to string processing? In any case, factor needs to be fleshed out so that it removes a single var from * functions and all of the var from + functions (replacing them with 1). It also needs to be smart enough to only do it when there are at least two replacements (otherwise we haven't actually done anything).

Gaussian functions and currying in Scheme

I am currently trying to learn Scheme to run FDTD simulations and I am having trouble building a Gaussian function in 2 dimensions.
In a forum I found this possibility for 1D:
(define ( (gaussx sigma) x)
(exp (- (/ (vector3-dot x x) (* 2 sigma sigma)))))
which if I understood currying correctly is equivalent to:
(define (gauss sigma)
(lambda(x)
(exp (- (/ (vector3-dot x x) (* 2 sigma sigma))))))
Now I would like the function to be gaussian along both x and y directions but I don't understand why this doesn't work:
(define (gauss sigma)
(lambda(x)
(lambda(y)
(exp (- (/ (+ (vector3-dot y y) (vector3-dot x x)) (* 2 sigma sigma))))
When I call
(gauss 1)
I get the following message:
ERROR: Wrong type (expecting real number): # <procedure> #f (y)
Does someone see what I am doing wrong? I also tried other solutions but I don't seem to get the logics here...
Thanks a lot for your help!
Best regards
Mei
I don't think there's need for a double currying here, try this:
(define (gauss sigma)
(lambda (x y)
(exp (- (/ (+ (vector3-dot y y) (vector3-dot x x)) (* 2 sigma sigma))))))
Call it like this:
(define gauss-1 (gauss 1))
(gauss-1 some-x some-y)
But if you definitely need the double currying, this should work:
(define (gauss sigma)
(lambda (x)
(lambda (y)
(exp (- (/ (+ (vector3-dot y y) (vector3-dot x x)) (* 2 sigma sigma)))))))
Using it like this:
(define gauss-1 (gauss 1))
((gauss-1 some-x) some-y)

Resources