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

Lambda calculus, Type theory, Formal semantics, Program analysis

    Prev     Next     All lectures           Code

Lambda - delay and force

(define inf-list
  (lambda (n) 
    (cons n (inf-list (+ n 1)))))
 -  An attempt to create an infinite list. Running this gets a stack overflow.
   prompt> (inf-list 1)
   ;Aborting!: maximum recursion depth exceeded
(define inf-list$
  (lambda (n)
    (cons n (lambda () (inf-list$ (+ n 1))))))
 -  The call to inf-list$ in the third line is placed inside a lambda. When inf-list$ is invoked, the recursive call to inf-list$ in the third line is delayed due to the lambda. The result looks like this:
   prompt> (inf-list$ 1)
   ;Value 13: (1 . #[compound-procedure 14])
The first token of the infinite list, shown in red, is output along with a procedure that will compute the rest of the list. To get the second token of the list, shown in red, do this:
   prompt> ((cdr (inf-list$ 1)))
   ;Value 17: (2 . #[compound-procedure 18])
To get the third token do this:
   prompt> ((cdr ((cdr (inf-list$ 1)))))
   ;Value 19: (3 . #[compound-procedure 20])
and so on.
(define take$
  (lambda (n S$)
    (if (or (null? S$) (= n 0))
        (cons (car S$) 
              (take$ (- n 1) ((cdr S$)))))))
 -  Using this information the procedure take$ is implemented to pull a desired number of tokens from an infinite list, or stream as will be said from now on. The symbol S$ is used to identify the input stream to take tokens from. The $ denotes the fact that a stream is expected. The parameter n is the number of desired tokens to pull from S$. Run it like this:
   prompt> (take$ 10 (inf-list$ 1))
   ;Value 21: (1 2 3 4 5 6 7 8 9 10)
(define take
  (lambda (n S)
    (if (or (null? S) (= n 0))
        (if (and (not (null? (cdr S)))
                 (procedure? (cdr S)))
            (cons (car S)
                  (take (- n 1) ((cdr S))))
            (cons (car S) 
                  (take (- n 1) (cdr S)))))))
 -  The procedure take pulls tokens from either a stream or a list depending on whether the cdr of S is a procdure.
   prompt> (take 4 (inf-list$ 1))
   ;Value 21: (1 2 3 4)
   prompt> (take 4 '(1 2 3 4 5 6 7))
   ;Value 22: (1 2 3 4)