20-CS-4003-001 Organization of Programming Languages Fall 2017
Miscellaneous Ideas

Lambda calculus, Type theory, Formal semantics, Program analysis

    Prev     Next     All lectures        Code

More on cons and lists

;; -> (2 . 1)
(cons 2 1)

;; -> ((2) . 1)
(cons '(2) 1)

;; -> (((3) . 2) . 1)
(cons (cons '(3) 2) 1)

;; -> ((((4) . 3) . 2) . 1)
(cons (cons (cons '(4) 3) 2) 1)

;; (build1 5) -> (5 4 3 2 1)
(define build1 
  (lambda (n)
    (if (zero? n)
        '()
        (cons n (build1 (- n 1))))))

;; (build2 5) ->
;;   (((((1) . 2) . 3) . 4) . 5)
(define build2
  (lambda (n)
    (if (= n 1)
        '(1)
        (cons (build2 (- n 1)) n))))

;; (build3 5 '()) -> (1 2 3 4 5)
(define build3
  (lambda (n m)
    (if (zero? n)
        m
        (build3 (- n 1) (cons n m)))))

;; (build4 5) -> (1 2 3 4 5)
(define build4
  (lambda (n)
    (letrec 
      ((build 
         (lambda (n acc)
           (if (zero? n)
               acc
               (build (- n 1) (cons n acc))))))
      (build n '()))))
 -  A list is implemented in scheme as a linked list. As usual for linked lists, the objects are carried using simple cells which contain a pointer to an object and a pointer to the next cell in the list. The list (cons 1 '()) looks like this:
      +-----+-----+
      |  o  |  o--|---> NULL
      +--|--+-----+
         |
         +---> 1
and is represented to the user like this: (1). It is possible to do this: (cons 2 1) which looks like this:
      +-----+-----+
      |  o  |  o--|---> 1
      +--|--+-----+
         |
         +---> 2
and is represented to the user like this: (2 . 1). Doing this: (cons 3 (cons 2 (cons 1 '()))) looks like this:
      +-----+-----+    +-----+-----+    +-----+-----+
      |  o  |  o--|--->|  o  |  o--|--->|  o  |  o--|---> NULL
      +--|--+-----+    +--|--+-----+    +--|--+-----+
         |                |                |
         +---> 3         +---> 2         +---> 1
and is represented to the user as (3 2 1). But (cons '(2) 1), as shown on the left, results in this:
      +-----+-----+    
      |  o  |  o--|---> 1
      +--|--+-----+ 
         |   
         |    +-----+-----+
         +--->|  o  |  o--|---> NULL
              +--|--+-----+
                 |
                 +---> 2
so it is represented to the user as ((2) . 1). The expression (cons (cons (cons '(4) 3) 2) 1) looks like this:
      +-----+-----+    
      |  o  |  o--|---> 1
      +--|--+-----+ 
         |   
         |    +-----+-----+
         +--->|  o  |  o--|---> 2
              +--|--+-----+
                 |   
                 |    +-----+-----+
                 +--->|  o  |  o--|---> 3
                      +--|--+-----+
                         |   
                         |    +-----+-----+
                         +--->|  o  |  o--|---> NULL
                              +--|--+-----+
                                 |
                                 +---> 4
and is represented to the user as ((((4) . 3) . 2) .1).

The function build1 to the left produces a list of decreasing integers as shown. The function build2 attempts to produce a list in increasing order by swapping the arguments of cons. The numbers are in the right order but the result is a nesting of lists as above instead of a single list. A solution is build3 which is awkward because it requires two arguments. But this function can be placed in a letrec which is wrapped inside a function of one argument as shown in build4.