开发者

What's the point of lambda in scheme?

开发者 https://www.devze.com 2023-01-01 09:42 出处:网络
I am learning scheme. I know how to use both lambda and let expressions. However I\'m struggling to figure out what the point is of using lambda. Can\'t you do everything with let that you can with l

I am learning scheme. I know how to use both lambda and let expressions.

However I'm struggling to figure out what the point is of using lambda. Can't you do everything with let that you can with lambda?

It would be especially helpful to see an example of a situation where a lambda expression is a better choice than let.

One other thing - are there also situations where let is more useful than lambda? If so such an example would be nice as well.

Edit: I'm also interested in contrasting define and lambda, as开发者_运维知识库 they seem to perform similar tasks.


Update:

Thanks for the help everyone. I did some more looking into lambda/let/define after reading your answers, and now understand it a lot better.

I came accross an excellent example of cool lambda useage - returning anonymous functions from procedures. For example, the procedure operateTwice below returns an anonymous function that is based on parameters passed in to the procedure:

(define operateTwice
  (lambda (op1 op2)
    (lambda (x y)
      (op2 (op1 x y) y))))

((operateTwice * +) 2 3) ;equivalent to: (+ (* 2 3) 3), or in standard notation 2*3+3

Output:

9


A let is a lambda.

E.g.

(let ((x 1))
  body)

can be translated into

((lambda (x) body) 1)

Furthermore, in Scheme all control and environment structures can be represented by lambda expressions and applications of lambdas.

So, lambda is strictly more powerful than let and forms the basis of many of the interesting constructs found in Scheme.

Concerning define and lambda, a top-level define adds a binding to the top-level environment.

When you write

(define (f x)
  body)

you are really saying

(define f (lambda (x) body))

Nested defines are translated into letrec, which can be rewritten using lambdas as well.

So, again, a lot of Scheme constructs can be translated into something using lambda, and therefore it is really worthwile that you understand lambda well.


You use lambda if you want to create a function to use it as an argument to another function (like for example map), but you don't actually want to name the function.

For example, if you want to add 42 to every number in a list, you can do:

(define (add42 x) (+ x 42))
(map add42 (list 1 2 3 4))

But if you don't want to give a name to a function that you only use this once, you could just do:

(map (lambda (x) (+ x 42)) (list 1 2 3 4))


Let is actually just shorthand for a Lambda expression. The following two expressions are equivalent:

(let ((alpha 7)) (* 5 alpha))

((lambda (alpha) (* 5 alpha)) 7)

Lambda follows the philosophy of the language that everything should look like a mathematical function. But in practice Let makes it easier to figure out what is happening if there are too many variables. Imagine 10 variables which have their values defined after the Lambda block, and you trying to match each of those with the variable name, with Let the values of variables are placed right next to their names, convenient for the programmer but conforming less to the Functional Programming philosophy.

Lambda can be used to return a function from a higher order function however let cannot do that. Eg:

(define (plus-list x)
  (cond ((number? x)
         (lambda (y) (+ (sum-n x) y)))
        ((list? x)
         (lambda (y) (+ (sum-list x) y)))
        (else (lambda (x) x))
        ))

> ((plus-list 3) 4)
10
> ((plus-list '(1 3 5)) 5)
14
> ((plus-list 'a) 5)
5

Lambda can also be used to pass a function to a function:

>(map (lambda (x) (+ 1 x)) '(-1 2 -3))
(0 3 -2)


lambda creates new anonymous functions, which of course are evaluated each time you use them.

let creates temporary names for values and are set once for use in the scope defined by the let form.

They are really very different beasts.

some examples :

(lambda (x) (* 5 x))

(let ([x 2]) (* 5 x)) 10 (let ([f (lambda (x) (* 5 x))]) (f 2)) 10

first form creates a function to multiply by 5

second form assign 2 to x and multiplies it by 5 resulting in 10

third we use the function of 1 (which mutiplies by 5) and call it with 2 as a parameter resulting also in 10


In Scheme a procedure (or function) is a first class object like a list, a number or a string. To create a list literal you use the primitive called list:

> (define marks (list 33 40 56))
> marks
> (33 40 56)

Just like this, to create a procedure, you use the lambda primitive (or special form):

> (define add-marks (lambda (m) (apply + m)))
> (add-marks marks)
> 129

As procedures are the primary form of abstraction, Scheme provides a shortcut for define to make it easy to bind new procedures:

> (define (add-marks m) (apply + m))

Other than this, procedures are just like all other first class objects. They can be passed as arguments to other procedures and a procedure can evaluate to produce (or return) another procedure.


You can think it like that... you create a function that uses another function but you want to make things more modular so what you do is you call the second function as an argument of the first one, and that leaves you the possibility to change the second whenever you feel like you need another functionality... hope that makes sense

0

精彩评论

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