Created
May 28, 2025 14:26
-
-
Save thierryvolpiatto/fc95d8e4d079376a0abf2bae381242e6 to your computer and use it in GitHub Desktop.
Iterator with oclosure
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; ocl-iterator.el --- define iterator with oclosure -*- lexical-binding: t -*- | |
;;; Code: | |
(oclosure-define ocl-iterator | |
"Return an iterator from SEQ." | |
(seq :type 'list :mutable t) | |
(cycle :type 'boolean) | |
(changing-direction :type 'boolean :mutable t) | |
(element :mutable t) | |
(direction :type 'symbol :mutable t)) | |
(defun ocl-iterator (seq &optional cycle) | |
"Return an iterator from SEQ. | |
When CYCLE is non nil make the iterator infinite. | |
The iterator is mutable, its direction can be changed at anytime with | |
the function `ocl-iterator-reverse', when doing so the sequence | |
handled by the iterator is reversed from the last element yielded. | |
Elements of the iterator can be accessed via the ocl-iterator--* fns. | |
All the oclosure slots are mutable but the only one that can be | |
changed safely is \\='changing-direction', expect weird behavior if | |
you try to modify other elements externally." | |
(oclosure-lambda (ocl-iterator (seq seq) | |
(cycle cycle) | |
(tmp-seq seq) | |
(element (car seq)) | |
(direction 'right) | |
(changing-direction nil)) | |
() | |
(let ((elm (car tmp-seq)) | |
revlist queue index) | |
(if changing-direction | |
(setq revlist (reverse seq) | |
queue (memql element revlist) | |
direction (pcase direction | |
('left 'right) | |
('right 'left)) | |
index (- (length seq) (length queue)) | |
seq (append queue (take index revlist)) | |
tmp-seq (cddr seq) | |
elm (cadr seq) | |
changing-direction nil) | |
(setq tmp-seq (if cycle | |
(or (cdr tmp-seq) seq) | |
(cdr tmp-seq)))) | |
(setq element elm)))) | |
(defun ocl-iterator-reverse (iterator) | |
(setf (ocl-iterator--changing-direction iterator) t)) | |
(defun ocl-iterator-next (iterator) | |
(and iterator (funcall iterator))) | |
;; (setq A (ocl-iterator '(a b c d e f g) 'cycle)) | |
;; (ocl-iterator-next A) | |
;; (ocl-iterator-reverse A) | |
;; (ocl-iterator-next A) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment