6 The Art of Lisp Programming

Example 6-1. A small Lisp program.

(define middle-c 60)

(define albans-row '(0 3 7 11 2 5 9 1 4 6 8 10))

(define (transpose-row row offset)
  (loop for pc in row collect (+ pc offset)))

Interaction 6-1. Using the program

cm> (transpose-row albans-row middle-c)
(60 63 67 71 62 65 69 61 64 66 68 70)
cm> (transpose-row '(0 2 5) 90)
(90 92 95)
cm> (transpose-row albans-row (random 80))
(17 20 24 28 19 22 26 18 21 23 25 27)
cm>

Interaction 6-2. Examples of numerical predicates.

cm> (number? 1)
#t
cm> (number? '(1))
#f
cm> (even? 0)
#t
cm> (odd? -2)
#f
cm>

Interaction 6-3. Examples of arithmetic relations.

cm> (= 1 1.0)
#t
cm> (< 1 1)
#f
cm> (> 3 2 1)
#t
cm> (>= -1 0 1 1 100)
#f
cm> (<= -1 0 100 .3)
#f
cm>

Interaction 6-4. Example arithmetic operators.

cm> (+ 1 2 3 4)
10
cm> (* 10 10)
100
cm> (- 1)
-1
cm> (- 1 .5)
0.5
cm> (/ 1)
1
cm> (/ 1 .25)
4.0
cm> (/ 30 5 -2)
-3
cm> (+)
0
cm> (*)
1
cm>

Interaction 6-5. The list predicates.

cm> (list? '())
#t
cm> (list? 1)
#f
cm> (list? '(1))
#t
cm> (null? '())
#t
cm> (null? '(1))
#f
cm>

Interaction 6-6. List constructors.

cm> (list)
()
cm> (list 1 2 3)
(1 2 3)
cm> (list* 1 '(2 3))
(1 2 3)
cm>

Interaction 6-7. List accessors.

cm> (define my-notes '(a b c d e))

cm> (first my-notes)
a
cm> (rest my-notes)
(b c d e)
cm> (list-ref my-notes 0)
a
cm> (list-ref my-notes (random 5))
d
cm>

Interaction 6-8. List setting

cm> (list-set! my-notes 0 'f)

cm> my-notes
(f b c d e)
cm>

Interaction 6-9. List setting

cm> (define my-notes '(a b c d e))

cm> (length my-notes)
5
cm> (reverse my-notes)
(e d c b a)
cm> (append my-notes (reverse my-notes) my-notes)
(a b c d e e d c b a a b c d e)
cm> (member 'g my-notes)
#f
cm> (member 'e my-notes)
#t
cm> (position 'b my-notes)
1
cm> (position 'g my-notes)
#f
cm>

Interaction 6-10. Example of boolean operators.

cm> (and #t #t #t)
#t
cm> (and #f #t)
#f
cm> (and (= 1 1) (< 10 11))
#t
cm> (or #f #f #t #f)
#t
cm> (or #f #f)
#f
cm> (not #f)
#t
cm> (not (not #f))
#f
cm> (if #t 1 2)
1
cm> (if #f 1 2)
2
cm> (if (> pi 4) 'yes)
#f
cm> (if (< 1 3) 'winner 'loser)
winner
cm>

Interaction 6-11. Sequential evaluation.

cm> (begin 1 2 3 'go)
go
cm> (if (< (random 3) 2)
      (begin (print 'winner) 
             'payday)
      (begin (print 'loser)
             'go-to-jail))
loser
go-to-jail
cm>

Interaction 6-12. Defining variables.

cm> (define two-pi (* pi 2))

cm> two-pi
6.283185307179586
cm> (define lotsa-pi (* pi pi pi))

cm> lotsa-pi
31.006276680299816
cm> (define favorite-pie 'apple-crunch)

cm> favorite-pie
apple-crunch
cm>

Interaction 6-13. Redefining and assigning variables.

cm> (define favorite-row '(0 7 8 3 4 11 10 5 6 1 2 9))

cm> favorite-row
(0 7 8 3 4 11 10 5 6 1 2 9)
cm> (define albans-row (reverse favorite-row))

cm> albans-row
(9 2 1 6 5 10 11 4 3 8 7 0)
cm> (set! favorite-row albans-row)

cm> favorite-row
(9 2 1 6 5 10 11 4 3 8 7 0)
cm>

Example 6-2. Convert beats per minute to time in seconds.

(define (bpm->seconds bpm)
  (/ 60.0 bpm))

Interaction 6-14. Converting beats per minute to time in seconds.

cm> (bpm->seconds 60)
1.0
cm> (bpm->seconds 120)
0.5
cm> (bpm->seconds 90)
0.6666666666666666
cm> (bpm->seconds 40)
1.5
cm>

Example 6-3. Three example let statements.

(let ()
  3)

(let ((a 10)
      (b 20))
  (* a b))

(let ((a (random 10)))
  (* a a))

Interaction 6-15. A let definition with three expressions.

cm> (let ((a 10)
          (b (random 10)))
      (print a)
      (print b)
      (list a b (+ a b)))
10
2
(10 2 12)
cm>

Interaction 6-16. A let* definition with a dependent variable definition.

cm> (let* ((key (random 116))
           (oct (+ key 12))) 
      (list key oct))
(33 45)
cm>

Example 6-4. Encapsulation by function definition.

(define (random-octave)
  (let ((key (random 116)))
    (list key (+ key 12))))

Interaction 6-17. Calculating random octaves with a function call.

cm> (random-octave)
(21 33)
cm> (random-octave)
(88 100)
cm> (random-octave)
(17 29)
cm>

Chapter Source Code

The source code to all of the examples and interactions in this chapter can be found in the file core.cm located in the same directory as the HTML file for this chapter. The source file can be edited in a text editor or evaluated inside the Common Music application.