views:

215

answers:

5

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.

Thanks!

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
+1  A: 

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

Peter Tillemans
I think that makes sense. But then why use lambda instead of define?
Cam
You don't always need a name for a function, thus you don't always need define.
nos
Right - got that from sepp2k's answer. Why would you want to not name a function though? (might be best to respond under sepp2k's answer so as to not duplicate this conversation). Thanks!
Cam
@incrediman, `define` is a special form and cannot be part of an expression because it can mess up the local environment since it adds or replaces variable names. That is not acceptable. The names must already exist prior evaluation.
Nick D
+3  A: 

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. 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))
sepp2k
Thanks. Can you provide some details regarding why you mgiht choose either one? You said "if you don't want to give a name to a function ...". But why wouldn't you?
Cam
In scheme and the other functional programs you use functions so much that you do not want to pollute your namespace by defining them even if you use them only once.Additionally very simple functions cannot bear the overhead of defining them separately and it would be very tiresome to have to look for their definitions in another place than where you need them.It will become evident after some use. It is difficult to explain without actually experiencing it.
Peter Tillemans
Why give it a name when you need it only in one single occasion? Instead of thinking of some a name that won't clutter your namespace, you can just pass an anonymous function.
LukeN
@incresiman: 1. You need to think of a name first. If you use a lot of little functions like this, this can become tiresome. 2. The more functions you define the harder it will become to think of an unused function name. 3. It will also become harder to remember which function does what, if you define a lot of little functions. 4. As you can see in my example the version with lambda is also a bit shorter than the one with define.
sepp2k
+13  A: 

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.

eljenso
Awesome - totally makes sense, thanks!
Cam
Hey, you can even construct natural numbers and arythmetic operations with nothing more than lambdas.
Tadeusz A. Kadłubowski
+1  A: 

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

rabidmachine9
+1  A: 

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.

Vijay Mathew