So what is a procedure? We know foldr
is a procedure but what makes it a procedure? The answer is a lambda
form.
(define x 10) ; second argument to define is 10, so x is 10
x ; ==> 10 (surprised?)
(define y (lambda () 10)) ; second argument to define is a lambda form
y ; ==> #<procedure:y> (it might vary from implementation to implementation)
(y) ; ==> 10
Both x and y are variables, but y is a procedure
. That means you cannot call x
like (x)
since that will produce an error but you can call (y)
and it will run whatever is in the body of the lambda.
Now Scheme has a simple way of writing the procedure y
. You could just write:
(define (y) 10) ; it's the same as the y above
y ; ==> #<procedure:y>
Think of it as the simplifications of the English language. We say "It's" instead of "It is" but they mean the same. This is the case for the two ways to write procedures as well. I'll give you 3 more with alternative syntax:
(define sqrt (lambda (x) (* x x)))
(define (sqrt x) (* x x))
(sqrt 10) ; ==> 100
(define list (lambda l l))
(define (list . l) l)
(list 1 2 3 4) ; ==> (1 2 3 4)
;; notice its fold1 as in number 1, not lowercase L
(define fold1
(lambda (fun acc lst)
(let loop ((acc acc) (lst lst))
(if (null? lst)
acc
(loop (fun (car lst) acc) (cdr lst))))))
(define (fold1 fun acc lst)
(let loop ((acc acc) (lst lst))
(if (null? lst)
acc
(loop (fun (car lst) acc) (cdr lst)))))
(fold1 cons '() '(1 2 3 4)) ; ==> (4 3 2 1)
Now foldr
just like fold1
accepts a procedure as it's very first argument. That means you can write:
(foldr (let ()
(define (my-add a b) (+ a b)) ; remember this is too
my-add) ; return my-add
0
'(1 2 3 4 5)) ; ==> 15
But if you just are going to give the procedure name so that you can return it by name. Since the function part of my-add
is (lambda (a b) (+ a b))
(do you see it?) why not just put that:
(foldr (lambda (a b) (+ a b)) ; PS: just + would suffice
0
'(1 2 3 4 5)) ; ==> 15
Remember. It's not the lambda
form that is sent to the foldr
procedure since it is already evaluated and is a procedure. Just like when you evaluate a symbol representing a procedure after defining it. It's pretty much the same as fold1
don't get expressions with cons
in it in the expression (fold1 + 0 (cons 1 (cons 2 (cons 3 '()))))
since by the time fold1
is applied +
is evaluated to #, 0 is evaluated to 0
(numbers self evaluate) and (cons 1 (cons 2 (cons 3 '())))
is evaluated to (1 2 3)