In Racket (and other functional programming languages), lambda very useful if you want to pass an inline function with one shot as a parameter, without first defining it. For example, suppose we want to put together a list of numbers. We can go a long way and first define the function square , and then use map :
(define (square x) (* xx)) (map square '(1 2 3 4 5)) => '(1 4 9 16 25)
... Or we can just pass lambda , for example:
(map (lambda (x) (* xx)) '(1 2 3 4 5)) => '(1 4 9 16 25)
As you can see, there are cases when we do not need to refer to the function name. Of course, if the procedure provided by lambda is reused in several parts or if it is recursive, then it makes sense to give it a name (so that it is no longer anonymous):
(define square (lambda (x) (* xx)))
The above is equivalent to the first definition of square at the beginning. Actually, the first definition is just syntactic sugar to define a function, but in the end all functions are lambdas!
Now let's look at your example. Here we use lambda slightly different way, and also illustrate why they are useful - we not only define the function, but also return the function:
(define test (lambda (x) (lambda (y) (+ xy))))
Perhaps it will be a little clearer if we write it like this (this is equivalent for the reasons mentioned above):
(define (test x) (lambda (y) (+ xy)))
Or even shorter - in Racket we can also use this syntax for the same purpose:
(define ((test x) y) (+ xy))
It’s not that this is the best (or worst) way to define a function - it’s another matter! we define a procedure called test , which receives x as a parameter and returns a new anonymous function as a result, which, in turn, receives y as a parameter. Now in these lines:
(define add27 (test 27))
... we call test with x value 27 , which returns an anonymous function, and we call this function add27 . Remember the lambda that was received as the y parameter? now lambda was named add27 - and this is an example of currying . Think about it: test is a function that is used to generate functions that add a fixed x value to a given y parameter, which explains why this works:
(add27 2) => 29
On the other hand, this function always adds 27 to its parameter without the ability to change it:
(define (addTest x) (+ x 27)) (addTest 2) => 29
Do you see the difference? test allows us to generate new functions that add an arbitrary value, while addTest always adds a fixed value of 27 . What if you want to add say 100 ? using test , it is simple:
(define add100 (test 100))
But addTest cannot be changed, we need to write a new function:
(define (addTest100 x) (+ x 100))
I hope this clarifies the situation, feel free to ask in the comments any additional questions about my answer.