;; Author: Nicolas Petton <nicolas@petton.fr>
;; Keywords: stream, laziness, sequences
-;; Version: 2.0.2
+;; Version: 2.1.0
;; Package-Requires: ((emacs "25"))
;; Package: stream
(char-after (point)))))
(stream buffer (1+ pos)))))
+(declare-function iter-next "generator")
+
+(defun stream-from-iterator (iterator)
+ "Return a stream generating new elements through ITERATOR.
+ITERATOR is an iterator object in terms of the \"generator\"
+package."
+ (stream-make
+ (condition-case nil
+ (cons (iter-next iterator) (stream-from-iterator iterator))
+ (iter-end-of-sequence nil))))
+
(defun stream-regexp (buffer regexp)
(stream-make
(let (match)
(with-current-buffer buffer
(setq match (re-search-forward regexp nil t)))
(when match
- (cons (match-data) (stream-regexp buffer regexp))
- nil))))
+ (cons (match-data) (stream-regexp buffer regexp))))))
(defun stream-range (&optional start end step)
"Return a stream of the integers from START to END, stepping by STEP.
"Return a stream of all but the first element of STREAM."
(or (cdr (thunk-force (cadr stream)))
(stream-empty)))
+
+(defun stream-append (&rest streams)
+ "Concatenate the STREAMS.
+Requesting elements from the resulting stream will request the
+elements in the STREAMS in order."
+ (if (null streams)
+ (stream-empty)
+ (stream-make
+ (let ((first (pop streams)))
+ (while (and (stream-empty-p first) streams)
+ (setq first (pop streams)))
+ (if (stream-empty-p first)
+ nil
+ (cons (stream-first first)
+ (if streams (apply #'stream-append (stream-rest first) streams)
+ (stream-rest first))))))))
+
+(defmacro stream-pop (stream)
+ "Return the first element of STREAM and set the value of STREAM to its rest."
+ (unless (symbolp stream)
+ (error "STREAM must be a symbol"))
+ `(prog1
+ (stream-first ,stream)
+ (setq ,stream (stream-rest ,stream))))
\f
;;; cl-generic support for streams
;;; Implementation of seq.el generic functions
-(cl-defmethod seq-p ((_stream stream))
+(cl-defmethod seqp ((_stream stream))
t)
(cl-defmethod seq-elt ((stream stream) n)
The elements of the produced stream are the results of the
applications of FUNCTION on each element of STREAM in succession."
(stream-make
- ;; Avoid using `stream-empty-p', as it will consume the first element of the
- ;; stream before iterating over the stream.
- (let ((first (stream-first stream)))
- (when first
- (cons (funcall function first)
- (seq-map function (stream-rest stream)))))))
+ (when (not (stream-empty-p stream))
+ (cons (funcall function (stream-first stream))
+ (seq-map function (stream-rest stream))))))
(cl-defmethod seq-do (function (stream stream))
"Evaluate FUNCTION for each element of STREAM eagerly, and return nil.