开发者

using lambda instead of let in scheme

In SICP 1.2.1 there is a function that m开发者_运维知识库akes a rational number, as follow:

(define (make-rat n d)
  (let ((g (gcd n d)))
    (cons (/ n g) (/ d g))))

I'm just curious how you can implement the same thing using lambda instead of let, without calling GCD twice. I couldn't figure it out myself.


Looking at SICP section 1.3.2,

(let ((<var1> <exp1>)
      (<var2> <exp2>)
      ...
      (<varn> <expn>))
   <body>)

is equivalent to

((lambda (<var1> ...<varn>)
    <body>)
 <exp1>
 ...
 <expn>)

So your procedure,

(define (make-rat n d)
  (let ((g (gcd n d)))
    (cons (/ n g) (/ d g))))

should be equivalent to

(define (make-rat n d)
  ((lambda (g)
    (cons (/ n g) (/ d g)))
  (gcd n d)))


These two things are same:

((lambda (p1 p2...) body) v1 v2...)

and

(let ((p1 v1) (p2 v2)...) body)


(define-syntax let-as-lambda
  (syntax-rules ()
        ((_ (x value) body)
            (let ((x value))
              body))))

(printf "~s~n" (let-as-lambda (x 1) (+ x 1)))


Let us examine two simple cases so that we can understand how we can rewrite any function that uses let with lambda:

  1. In our first case we have one let. This function is very simple, it returns a given input by adding 10 to it:

    (define (test x)
      (let ((b 10))
        (+ x b)))
    

Now let us turn this into an expression using lambda:

    (define (test-lambda x)
      ((lambda (b)
         (+ x b))
       10))

As you can see, test-lambda returns a lambda evaluation that is evaluated with the value 10. Testing this we can say:

    (test-lambda 10)

which will return 20.

  1. Now for more than one let, we nest lambda-expressions within lambda-expressions.

Our let case we have two let statements:

    (define (lets x)
      (let ((a 10)
            (b 20))
        (+ x a b)))

We can write this with lambda like so:

    (define (lets-lambda x)
      ((lambda (a)
         ((lambda (b)
            (+ x a b))
          20))
       10))

So now we are evaluating each of the lambda expressions giving them a value, and the innermost lambda expression takes care of what we want to compute using the variable names that each lambda expression has been assigned.

Hope this was clear and might help others see more clearly!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜