;;; encap.ss
;;;   A set of routines for dealing with "encapsulated" lists.  These
;;;   are lists that can be treated as if they were lazy.
;;; Author
;;;   Samuel A. Rebelsky
;;; Version
;;;   1.0 of April 1998
;;; Requires
;;;   utils.ss
;;; Copyright (c) Samuel A. Rebelsky.  All rights reserved.

;;; Demand an encapsulated value, making sure that it's encapsulated.
(define (demand encapsulated)
  (if (procedure? encapsulated)
      (encapsulated)
      encapsulated))

;;; Demand the car of an encapsulated list.  
(define demandcar
  (compose demand car))

;;; Demand the cdr of an encapsulated list.
(define demandcdr
  (compose demand cdr))

;;; Generate an encapsulated list of the integers starting with n.
(define (intsfrom n)
  (cons (lambda () n)
        (lambda () (intsfrom (+ n 1)))))

;;; Extract the first n elements of an encapsulated list.
(define (firstn n lst)
  (if (= n 0) nil
      (cons (demandcar lst)
            (firstn (- n 1) (demandcdr lst)))))

;;; Generate an encapsulated list of Fibonacci numbers.
(define (fibs)
  (fibs-helper 1 1))
;;; Generate an encapsulated list of Fibonacci numbers, given the first
;;; two numbers in the list.
(define (fibs-helper alpha beta)
  (cons (lambda () alpha)
        (lambda () (fibs-helper beta (+ alpha beta)))))
