Philip Kaludercic wrote: >> +(cl-defstruct (stream (:constructor stream--make-stream) >> + (:predicate streamp) >> + :named) >> + >> + "A lazily evaluated sequence, compatible with the `seq' library's functions." >> + >> + (evaluated--internal >> + nil >> + :type boolean >> + :documentation "Whether the head and tail of the stream are accessible. >> + >> +This value is set to t via the function `stream--force' after it >> +calls the updater function.") >> + >> + (first--internal >> + nil >> + :type (or t null) > > Isn't this type just t? Not a proof, but this doesn't signal: Yes. I have changed it to just `t`. >> +(defun stream--force (stream) >> + "Evaluate and return the STREAM. >> + >> +If the output of the updater function is nil, then STREAM is >> +marked as empty. Otherwise, the output of the updater function >> +is used to set the head and the tail of the stream." >> + ;; Check explicitly so that we can avoid checking >> + ;; in accessors by setting safety to 0 via `cl-declaim'. >> + (unless (streamp stream) >> + (signal 'wrong-type-argument (list 'stream stream))) > > If you are already using cl-lib, you could also make use of `cl-check-type'. Done. >> + (if (stream-evaluated--internal stream) >> + stream >> + (pcase (funcall (stream-updater--internal stream)) >> + (`(,head . ,tail) >> + (setf (stream-first--internal stream) head >> + (stream-rest--internal stream) tail)) >> + ((pred null) >> + (setf (stream-empty--internal stream) t)) >> + (bad-output >> + (error "Bad output from stream updater: %s" >> + bad-output))) >> + (setf (stream-evaluated--internal stream) t) >> + stream)) >> >> (defmacro stream-make (&rest body) >> "Return a stream built from BODY. >> -BODY must return nil or a cons cell whose cdr is itself a >> -stream." >> - (declare (debug t)) >> - `(cons ',stream--fresh-identifier (lambda () ,@body))) >> >> -(defun stream--force (stream) > > Did you change the order of the definitions? Yes. I brought the fundamental features to the top of the file. In the existing version, things are defined after they are used. I know that is not an error, but it had me jumping around more to see how it worked. >> + >> +(defconst stream-empty >> + (stream--make-stream :evaluated--internal t >> + :first--internal nil >> + :rest--internal nil >> + :empty--internal t >> + :updater--internal nil) >> + "The empty stream.") >> + >> +(defun stream-empty () >> + "Return the empty stream." >> + stream-empty) > > This definition also appears unchanged? Please try to keep the diff as > small as possible. OK. I have broken it into several files, which I've attached. How does it look now?