I am trying to understand lambda use in racket and I am still unclear. I get that they are unnamed (anonymous) functions but why is that good? I need to access my functions from other functions so how would I call them??? Please explain the small program below and why using lambda is better? Thank you.
; why is this better than below???
(define test
(lambda (x)
(lambda (y)
(+ x y))))
(define add27
(test 27))
; what's wrong with this???
(define (addTest x)
(+ x 27))
> (add27 2)
29
> (addTest 2)
29
Procedure Expressions: lambda and case-lambda in The Racket Reference provides more on function expressions. The case-lambda form creates a function that can have completely different behaviors depending on the number of arguments that are supplied. A case-lambda expression has the form
A lambda function is a small anonymous function. A lambda function can take any number of arguments, but can only have one expression. Syntax. lambda arguments : expression. The expression is executed and the result is returned: Example. Add 10 to argument a, and return the result:
The resulting function accepts any number of arguments, and the arguments are put into a list bound to rest-id. Functions with a rest-id often use apply to call another function that accepts any number of arguments. The apply Function describes apply. The lambda form also supports required arguments combined with a rest-id:
That is, a lambda expression can have a single rest-id that is not surrounded by parentheses. The resulting function accepts any number of arguments, and the arguments are put into a list bound to rest-id.
In Racket (and other functional programming languages) lambda
s are very useful, when you want to pass an in-line, one-shot function as a parameter without defining it first. For example, suppose that we want to square a list of numbers. We can go the long way and define a square
function first, and then use map
:
(define (square x)
(* x x))
(map square '(1 2 3 4 5))
=> '(1 4 9 16 25)
… Or we can simply pass a lambda
, like this:
(map (lambda (x) (* x x))
'(1 2 3 4 5))
=> '(1 4 9 16 25)
As you can see, there exist cases where we don't need to refer to a function's name. Of course, if the procedure represented by the lambda
is going to be reused in several parts, or if it's recursive then it makes sense to give it a name (so it's no longer anonymous):
(define square
(lambda (x) (* x x)))
The above is equivalent to the first definition of square
at the beginning. In fact, the first definition is just syntactic sugar to define a function, but in the end all functions are lambdas!
Now let's see your example. Here we are using a lambda
in a slightly different fashion, and also exemplifies why they're useful - we're not only defining a function, but returning a function as well:
(define test
(lambda (x)
(lambda (y)
(+ x y))))
Perhaps it'll be a bit clearer if we write it like this (it's equivalent, for the reasons mentioned above):
(define (test x)
(lambda (y)
(+ x y)))
Or even shorter - in Racket we can also use this syntax for the same purpose:
(define ((test x) y)
(+ x y))
It's not that this is a better (or worse) way to define a function - it's a different thing! we're defining a procedure called test
, that receives as parameter x
and returns as a result a new anonymous function, that in turn will receive as parameter y
. Now, in these lines:
(define add27
(test 27))
… we're calling test
with an x
value of 27
, which returns the anonymous function, and we name that function add27
. Remember the lambda
that received as parameter y
? now that lambda
has been named add27
- and this is an example of currying. Think of it: test
is a function that is used for generating functions that add a fixed value x
to a given parameter y
, that explains why this works:
(add27 2)
=> 29
On the other hand, this function will always add 27
to its parameter with no way to change it:
(define (addTest x)
(+ x 27))
(addTest 2)
=> 29
You see the difference? test
allows us to generate new functions that add an arbitrary value, whereas addTest
always adds a fixed value, 27
. What if you wanted to add say, 100
? using test
this is simple:
(define add100 (test 100))
But addTest
can't be changed, we would need to write a new function:
(define (addTest100 x)
(+ x 100))
I hope this clarifies things, feel free to ask in the comments any additional questions about my answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With