Some Additional Scheme Topics: Improper Lists, Functions with a Variable Number of Arguments; Quasiquoting

Improper Lists

You have no doubt been wondering all quarter what this statement means at the top of

(schemers . org):
an improper list
of Scheme resources
(Well, maybe you haven't.) Anyway, we have always written lists in which the cdr of a cons cell is either the empty list or another cons cell; and this is the norm. It turns out this isn't required. A list in which the cdr of a cons cell is something else is an improper list, and is written using a dot.

For example,

(2 . 3)
denotes this list:
                |       |       |  
                |   o   |   o   |   
                    |       |       
                    |       |       
                    2       3       


(2 3 . 4)
                 _______________        ________________ 
                |       |       |      |        |       |
                |   o   |   ----|----->|    o   |   o   |
                |___|___|_______|      |____|___|___|___|
                    |                       | 	    | 	 
                    |                       |	    | 
                    2                       3       4  

Functions with a Variable Number of Arguments

We've used functions with a variable number of arguments (for example +), but have only written them with a fixed number of arguments.

Example definitions with a variable number of arguments:

(define (squid a b . c)
   (display a) (newline)
   (display b) (newline)
   (display c) (newline))
squid requires at least 2 arguments. Any remaining arguments (perhaps 0) are put into a list, which is bound to c.

This function can take 0 or more arguments:

(define (average . lst)
   (if (null? lst) 
      (error "can't take the average of an empty list")
      (/ (apply + lst) (length lst))))


"Backquote" or "quasiquote" expressions are useful when you want to construct a list for which you know most, but not all, of the desired structure in advance. For example, suppose that you want to return a list of band members that includes a mysterious 5th Beatle. With what we know so far you could do this:

(define (bands m)
   (list '(peter paul mary)
         (list 'john 'paul 'george 'ringo m)
         '(simon garfunkle)))
Since we know all of the structure except for the 5th Beatle, instead we could use quasiquoting:
(define (quasibands m)
   `((peter paul mary)
     (john paul george ringo ,m)
     (simon garfunkle)))
Here everything in the quasiquoted list is quoted, except when it is preceded by a comma (which unquotes it).

You can also splice in a list in the middle of another using an @ sign.

(define x '(clam squid))
`(octopus ,@x mollusc oyster) => (octopus clam squid mollusc oyster)
compare with:
`(octopus ,x mollusc oyster) => (octopus (clam squid) mollusc oyster)

Advanced Topic - Nested Quotes

(define x 3)
'''x  => ''x
(eval '''x)  => 'x
(eval (eval '''x))  => x
(eval (eval (eval '''x)))  => 3

Nested Quasiquoting

From the R5RS Scheme Report:
Quasiquote forms may be nested. Substitutions are made only for unquoted components appearing at the same nesting level as the outermost backquote. The nesting level increases by one inside each successive quasiquotation, and decreases by one inside each unquotation.
This is probably not something you would actually do in a program, but language designers need to account for it -- and it's better to have a uniform treatment of the construct (as Scheme does) than something ad hoc.