;;;; Copyright 2002, Jonathan Bachrach.  See file TERMS.

(use goo/boot)
(use goo/fun)
(use goo/class)
(use goo/macros)
(use goo/math)
(use goo/cols/col)
(use goo/cols/seq)

;;;;!! Interface
(exported
 (dc <step> (<seq>))
 (dg first-then (first|<fun> then|<fun>))
 (dc <each> (<seq>))
 (dg each (f|<fun>))
)

;;;;!! Implementation

;;;; STEP

(dp step-first (<step> => <fun>))
(dp step-then (<step> => <fun>))

;;;; Collection iteration protocol
(dm first-then (first|<fun> then|<fun> => <step>)
  (new <step> step-first first step-then then))

(dc <step-enum> (<enum>))
  (dp  %dat (<step-enum> => <step>))
  (dp! %first? (<step-enum> => <log>) #t)
(dm enum (x|<step> => <step-enum>) 
  (new <step-enum> %dat x))
(dm fin? (e|<step-enum> => <log>) #f)
(dm nxt (e|<step-enum> => <step-enum>)
  (renew e %first? #f ;; %dat (%dat e)
         ))
(dm now (e|<step-enum> => <any>)
  (if (%first? e) ((step-first (%dat e))) ((step-then (%dat e)))))

;;;; EACH 

(dp each-fun (<each> => <fun>))

(dc <each-enum> (<enum>))
(dp %dat (<each-enum> => <each>))
(dm enum (x|<each> => <each-enum>) 
  (new <each-enum> %dat x))
(dm fin? (e|<each-enum> => <log>) #f)
(dm nxt (e|<each-enum> => <each-enum>) e)
(dm now (e|<each-enum> => <any>)
  ((each-fun (%dat e))))
