(
(define ConsStream  (lambda (PrimoEl FunGen) (cons PrimoEl FunGen)))
(define Head        (lambda (Stream)         (car Stream)))
(define Tail        (lambda (Stream)         ((cdr Stream))))

(define EmptyS      (lambda (Stream)         (null Stream)))

(define EmptyStream  nil)



(define IntStream (lambda (n) 
                     (ConsStream n (lambda() (IntStream (+ 1 n))))))
(define IntStreamLimit (lambda (n max)
                          (cond ((eq n max) EmptyStream)
                                 (   t      (ConsStream n (lambda() (IntStreamLimit (+ 1 n) max)))))
                          ))
(define StreamInList (lambda (S)
                          (cond ((EmptyS S) EmptyStream)
                                (    t      (cons (Head S) (StreamInList (Tail S))))
                          )))
(define StampaStream (lambda (S) (write (Head S))))

(define Filtro (lambda (S Pred) 
                  (cond (  (EmptyS S)    EmptyStream)
                        ((Pred (Head S)) (ConsStream (headS) (lambda () Filtro (Tail S) Pred)))
                        (    t           (Filtro (Tail S) Pred))
                  )))

(define Accum (lambda (S ElNeutro Oper) 
                  (cond ((EmptyS S) ElNeutro)
                        (    t      (Oper (Head S) (Accum (Tail S) ElNeutro Oper)))
                  )))

(define Limita (lambda (S Conta MaxConta)
                  (cond ((eq Conta MaxConta) EmptyStream)
                        (      t             (ConsStream (Head S) (lambda (Tail S) (+ Conta 1) MaxConta)))
                  )))

(define Trasforma (lambda (S Fun)
                     (cond ((EmptyS S) EmptyStream)
                           (    t      (ConsStream (Fun (Head S)) (lambda () (Trasforma (Tail S) Fun))))
                     )))





(define Sift (lambda (S)
                (cond ((EmptyS) S)
                      (    t    (ConsStream (Head S) (lambda () (Sift (Filtro (Tail S) (lambda (x) (/=0 (rem x (Head S)))))))))
                )))

(StreamInList (Limita (Sift (IntStream 2)) 1 10))
(StampaStream (Limita (Sift (IntStream 2)) 1 10))

)
