Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Let in Scheme

Tags:

lisp

scheme

I want to write a program to find the roots of the quadratic equation in Scheme. I used LET for certain bindings.

(define roots-with-let
  (λ (a b c)
    (let ((4ac (* 4 a c))
          (2a (* 2 a))
          (discriminant (sqrt ( - (* b b) (4ac)))))
      (cons ( / ( + (- b) discriminant) 2a)
            ( / ( - (- b) discriminant) 2a)))))

I defined the discriminant with 4ac since I did not want (* 4 a c). Even though I have defined (4ac (* 4 a c)), it is giving me this error:

expand: unbound identifier in module in: 4ac.

My question is how is let evaluated (what order)? And if i want 4ac in my let should i write another inner let? Is there a better way to do this?

like image 760
unj2 Avatar asked Jun 03 '09 17:06

unj2


People also ask

How let and Letrec constructs work in Scheme?

In a let expression, the initial values are computed before any of the variables become bound; in a let* expression, the bindings and evaluations are performed sequentially; while in a letrec expression, all the bindings are in effect while their initial values are being computed, thus allowing mutually recursive ...

What is let * In racket?

Local Binding: let, let*, letrec, ... in The Racket Reference also documents let. A let form binds a set of identifiers, each to the result of some expression, for use in the let body: (let ([id expr] ...) body ...+)

How do I use Start Scheme?

begin is normally used when there is some side-effect. "If you omit the begin, then you simply could not write this expression". You can actually write that expression using lambda: (+ x ((lambda (x) y) (set! y (+ y 1))) z) .

What is Letrec?

letrec supports the creation of recursive local procedures, including mutually recursive sets of procedures. let* supports the sequenced binding of variables, where each initial value expression can use the previous bindings.


1 Answers

Use let* instead of let.

The difference between let and let* is the following:

let* binds variables from left to right. Earlier bindings can be used in new binding further to the right (or down).

let on the other hand can be thought of as syntactic sugar (or macro) for simple lambda abstraction:

(let ((a exp1)
      (b exp2))
   exp)

is equivalent to

((lambda (a b)
    exp)
 exp1 exp2)
like image 183
Jonas Avatar answered Nov 07 '22 06:11

Jonas