In chapter 7 of his ‘Common Lisp: A Gentle Introduction to Symbolic Computation’ David Touretzky introduces lambda expressions. These are anonymous ad-hoc functions that are passed directly to an applicative operator. They can result in rather concise function calls like this one:
1 2 |
(mapcar #’(lambda (n) (* n n)) ’(1 2 3 4 5)) ; (1 4 9 16 25) |
Note the #’ in front of the lambda expression which is the correct syntax for preventing this function from being evaluated. Instead, it says: this is a list that represents a function”. In this part of the series we are dealing with exercises 7.5 to 7.7 of Touretzky’s book.
Exercise 7.5 asks for lambda expression to subtract seven from a number.
Exercise 7.6 asks for a lambda expressions that returns T for every T or NIL input, and NIL for any other input.
Exercise 7.7 wants a function that returns UP for every DOWN in the input list, and vice versa.
This is the Lisp code for these exercises:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
;;; ex 7.5 (mapcar #'(lambda (n) (- n 7)) '(10 11 12 13)) ; (3 4 5 6) ;;; ex 7.6 (mapcar #'(lambda (x) (or (equal x t) (equal x nil))) '(t nil (+ 1 1) 'a)) ; (T T NIL NIL) ;;; ex 7.7 (mapcar #'(lambda (a) (if (equal a 'up) 'DOWN 'UP)) '(up down up down)) ; (DOWN UP DOWN UP) |
And this is the Clojure version of the same exercises:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
;;; ex 7.5 (map (fn [n] (- n 7)) '(10 11 12 13)) ; (3 4 5 6) ;;; ex 7.6 (map (fn [x] (or (= x true) (= x false))) '(true false (+ 1 1) 'a)) ; (true true false false) ;;; ex 7.7 (map (fn [a] (if (= a 'up) :down :up)) '(up down up down)) ; (:down :up :down :up) |
Note the differences: while Clojure’s map is equivalent to Lisp’s mapcar, the lambda function call looks a bit different in both languages: there is no quoting with #’ in Clojure and lambda has become fn. Due to Clojure’s rich syntactic sugar there is another, even more concise syntax, but we will defer this until later. Both expressions take an input list of numbers and each of them gets subtracted by 7. The results are collected in a result list.
This is also true for exercise 7.6. Lisp’s nil has become false in Clojure, but you should keep in mind that while nil and () in Lisp means the same, it’s not the same in Clojure:
1 2 |
CL-USER> (equal nil '()) ; T |
1 2 3 4 5 6 |
user> (= nil '()) ; false user> (= false nil) ; false user> (= false '()) ; false |
And while nil in Lisp both means empty list and boolean false, nil, () and false are different things in Clojure. Consequentially, Lisp’s T is a true in Clojure.
Another thing that’s worth noting is that Lisp’s many equality functions EQL, EQUAL, EQ, EQUALP, and = have become a simple = in Clojure.
See part 1 of this series. To be continued.