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
Let is actually just shorthand for a Lambda expression. The following two expressions are equivalent:
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:
Lambda can also be used to pass a function to a function:
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
:Just like this, to create a procedure, you use the
lambda
primitive (or special form):As procedures are the primary form of abstraction, Scheme provides a shortcut for
define
to make it easy to bind new procedures: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.
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 :
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
You use
lambda
if you want to create a function to use it as an argument to another function (like for examplemap
), 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:
But if you don't want to give a name to a function that you only use this once, you could just do:
A
let
is alambda
.E.g.
can be translated into
Furthermore, in Scheme all control and environment structures can be represented by lambda expressions and applications of lambdas.
So,
lambda
is strictly more powerful thanlet
and forms the basis of many of the interesting constructs found in Scheme.Concerning
define
andlambda
, a top-leveldefine
adds a binding to the top-level environment.When you write
you are really saying
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 understandlambda
well.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