Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda in Racket Explained

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
like image 684
1Raptor007 Avatar asked Sep 06 '14 01:09

1Raptor007


People also ask

What is the difference between lambda and case lambda in racket?

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

What is a lambda function in C++?

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:

What is the difference between lambda form and rest-ID?

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:

How many arguments can a lambda expression have?

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.


1 Answers

In Racket (and other functional programming languages) lambdas 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.

like image 84
Óscar López Avatar answered Oct 20 '22 08:10

Óscar López