# CS3L OaW Lecture 9 : Lambda

## Review

• every maps, or does something to every word in the sentence/word, returning a sentence
• First argument is a one-argument transforming function
• keep selects certain elements of a word or sentence and discards the others
• First argument is a one-argument predicate function
• accumulate transforms the entire word or sentence into a single result in a right-associative fashion
• First argument is a two-argument combining (usually associative) function
• repeated takes a function and a number and returns a new procedure.
• The returned procedure is one that invokes the original procedure repeatedlynumbertimes.
• We saw the ability to write our own HOFs by chaining together other HOFs, or by writing them using recursion

• Survey this week (Tue/Wed)
• Midterm on Wed 2009-03-18 @ 6-9pm in 306 Soda:
• Open book, open notes, covering everything up to and including HOFs and Lambda

## Lambda

### Motivation

• Let's write a function called add-letters
• Someone is called a "person of letters" if there are letters after the person's name. E.g., "Dan Garcia, Ph.D." or "Diane Chambers, M.D." or "Marchelle King, D.D.S"
• Write a procedure (without using explicit recursion) that takes a sentence of last names and a new suffix and adds the suffix to the end of all the last name.
```: (add-letters 'phd '(garcia yelick cosby))
(garcia-phd yelick-phd cosby-phd)```
• Good luck (if you don't know lambda)
• Ok, I'm listening. What IS this lambda thing?

### Introduction

• Lambdas are special forms which provide a way of creating functions other than using define, except you don't need to assign a name to them!
• Usage: (lambda (formal-parameters) body)
• The first element is the symbol lambda
• The second is a parameter list,
• The remaining elements are the body of the function (just as in define)!
• Lambdas create nameless functions
• We've been using lambda all along, it was just being handled automatically by the computer.

### Example : square (aka "The truth about define")

• That is, when we type:
```(define (square x)
(* x x))```
• ...the Scheme interpreter automatically translates it to
```(define square
(lambda (x) (* x x)))```
• This means that the variable square is bound to a procedure which takes an argument x, and multiplies it by itself.
• lambda just means a procedure.
• It turns out, then, that a procedure name is really just a variable whose value happens to be a procedure.
• We knew this already! What happens when we type:
```: square
==>```
• We don't have to give every function a name. I could call a function by saying either
```(        square         3 ) ;; ==>  9
( (lambda (x) (* x x))  3 ) ;; ==>  9```
• The first parenthesis tells us we're calling a function, and the second parenthesis is the one that denotes the beginning of the function.
• The function is anonymous, all we know is it takes an argument called x, and it multiplies that argument by itself.

### Using lambda with multiple (or no) arguments

• Functions returned by lambdas can take multiple (or no) arguments, just as functions can.
• Example: A function that takes no arguments and returns cal:
```: (lambda () 'cal)
#[procedure #x18F0794]```
• Oops, need to call it!
```: ((lambda () 'cal))
cal```
• Example: A function that takes two arguments and adds them:
```: ((lambda (a b) (+ a b)) 4 5)
9```

• You may notice that the way let stores a value in a temporary variable is similar to the way lambda does it.
• It turns out let is really an abbreviation for lambda.
• Example: notice the similarity between the lambda above and this let:
```: (let ((a 4)
(b 5))
(+ a b))
9```
• Now does it click why the variables being assigned in the let happen in "parallel" and can't depend on one another?

### Name Conflicts : AVOID THEM!

• What happens when you have inner parameters (created by let, lambda, etc) with the same name as the outer parameters (or as a global variable)?
• In truth, the inner parameters win, the outer values are shadowed, and not seen inside.
• Example:
```(define (foo x)
(let ((x 3))
(lambda (x)
(+ x 5)))) ;; Which x do we mean?```

### Returning a procedure

• You can make a procedure that returns a procedure yourself!
• Read the following code carefully to make sure you understand it. It's subtle, but important.
```: (define (make-bookender bookend)
(lambda (w) (word bookend w bookend)))
make-bookender

: ((make-bookender 'o) 'hi)
ohio

: ((make-bookender 'to) 'n)
tonto```
• Now we can define a specific bookender function to be the result of the call to make-bookender!
```: (define to_to (make-bookender 'to))
to_to```
• And now to_to is just like any other procedure!!
```: (to_to 'ron)
toronto```
• Howabout writing a procedure compose that takes two unary (one argument) functions f and g and returns a function that takes an argument arg and returns the result of (f (g arg))?
```: (define (compose f g)
==>```
• Can you use compose to define second ?
```: (define second
==>```

## Lambda and Higher-Order Functions

### Overview

• More useful than the above is using lambda with higher-order functions.
• That is, instead of saying
```: (define (square x) (* x x))
square

: (every square '(1 2 3 4))
(1 4 9 16)```
• I could write it more succinctly like this:
```: (every (lambda (x) (* x x)) '(1 2 3 4))
(1 4 9 16)```
• I eliminated the step of having to separately define square, by just writing literally the function I want to do to every word in the sentence.
• I just cut out the middle man because the only time I'm going to need that function is just for this one call to every, and I'm not going to need to refer to it again.
• The only time I need to name a function is when I'm going to need to use it more than once, for the same reason that I only create any variable if it refers to a value I need more than once.
• Recall the definition
`(define square (lambda (x) (* x x))).`
• It means that any time I see the word square, I could replace it with
`(lambda (x) (* x x))`
• That's just what I did in the call to every above. I replaced the word square with its value, which is that procedure

• Let's do a more extended example to illustrate lambda's importance.
• Add 1 to every word in a sentence, and return a sentence of the results
• Here's the long way
```;; add-1-to-sent
;;
;; Example: (add-1-to-sent '(1 2 3)) ==> (2 3 4)

(+ num 1))```
• ...and here's the short way...
```(define (add-1-to-sent S)
==>```
• I don't need to go to the bother of defining a separate function called add-1 to add 1 to a number, I can just use lambda.
• You might, however, say that using lambda explicitly may be shorter, but it's still unnecessary. Consider the following example:

• What about if someone asked you to write a function to add an input, n, to a sentence of words:
```;; add-n-to-sent
;;
;; Example: (add-n-to-sent 5 '(1 2 3)) ==> (6 7 8)

(every ??? S))

;; What goes in the ??? -- let's try to find out.```
• My first try in which I try the old-fashioned way of using a helper function
```(define (add-n-to-sent n S)

(+ num n))   ; WRONG, why? ==>```
• So I try to fix it like this:
```(define (add-n n num)  ; I added a new parameter called n
(+ n num))           ; ALSO WRONG, BUT FOR A DIFFERENT REASON
; Why? ==>```
• In fact, I cannot write a separate function add-n if I want to use every.
• There's no way that it can add n to the number, because it doesn't know the value of n.
• The solution is to ditch the helper function altogether and use lambda instead.
```(define (add-n-to-sent n S)
==>```
• This works because the lambda only takes one argument, but it can still refer to n within its body because n is a parameter of the current function.

• Given a sentence, return the same sentence with all the odd numbers incremented by 1
```;; Example:
;;
;; (add-1-to-odds '(1 out of 3 likes u 2 and u b 40))
;; ==> (2 out of 4 likes u 2 and u b 40)

==>
==>
==>
==>```
• Is lambda just convenient or is it necessary? ==>

### Example : all-letter-twister?

• Given a letter and a sentence, return non-#f if every word in the sentence is a begins with a given letter (i.e., is a tongue twister in that latter), otherwise #f
```;; Example:
;;
;; (all-letter-twister? 'r '(rubber bumper baby buggy)) ==> #f
;; (all-letter-twister? 's '(six sheiks sixth sheeps sick)) ==> #t

: (define (all-letter-twister? letter S)
==>
==>
==>
==>```
• Is lambda just convenient or is it necessary? ==>

## Summary

• Lambda expressions are a way of creating nameless functions.
• They are most often used to create specialized functions to use with higher-order functions.
• You sometimes NEED lambdas when the function you are passing in as an argument to the HOF needs more information than just each list element provides.
• They are the easiest way to return a function

## In Lab this week you'll see...

• Election processing miniproject continued
• More HOF and Lambdas lab activities
• A chance to take an old Midterm exam

## In Life this week you'll see...

• Wall Street : the beginning of a mini-rally? Can the Dow stay above 7K?