Last active
March 25, 2026 19:27
-
-
Save StarSugar/f5ea9fc0df169c4987c150e7159ff7ce to your computer and use it in GitHub Desktop.
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
| (declaim (inline mvfold mvfold!)) | |
| #-sbcl | |
| (defun mvfold (f initf &rest lsts) | |
| (declare (dynamic-extent lsts)) | |
| (declare (optimize (speed 3))) | |
| (when (or (null lsts) (some #'null lsts)) | |
| (return-from mvfold (funcall initf))) | |
| (let ((acc (multiple-value-list (funcall initf)))) | |
| (do () | |
| ((progn | |
| (setf acc | |
| (multiple-value-list | |
| (multiple-value-call | |
| f | |
| (values-list acc) | |
| (values-list (mapcar #'car lsts))))) | |
| (do ((rst lsts (cdr rst))) | |
| ((null rst)) | |
| (setf (car rst) (cdar rst))) | |
| (some #'null lsts)) | |
| (values-list acc))))) | |
| #+sbcl | |
| (defun mvfold (f initf &rest lsts) | |
| (declare (dynamic-extent lsts)) | |
| (declare (optimize (speed 3))) | |
| (when (null lsts) | |
| (return-from mvfold (funcall initf))) | |
| (labels ((iter (&rest acc) | |
| (declare (dynamic-extent acc)) | |
| (if (some #'null lsts) | |
| (values-list acc) | |
| (multiple-value-call #'iter | |
| (multiple-value-call f | |
| (values-list acc) | |
| (values-list | |
| (prog1 (mapcar #'car lsts) | |
| (do ((rst lsts (cdr rst))) | |
| ((null rst)) | |
| (setf (car rst) (cdar rst)))))))))) | |
| (multiple-value-call #'iter (funcall initf)))) | |
| #-sbcl | |
| (defun mvfold! (f initf &rest lsts) | |
| (declare (dynamic-extent lsts)) | |
| (declare (optimize (speed 3))) | |
| (when (or (null lsts) (some #'null lsts)) | |
| (return-from mvfold! (funcall initf))) | |
| (let ((acc (multiple-value-list (funcall initf)))) | |
| (do () | |
| ((progn | |
| (setf acc | |
| (multiple-value-list | |
| (multiple-value-call f | |
| (values-list acc) | |
| (values-list | |
| (let* ((lst (car lsts)) | |
| (vals lst)) | |
| (rplaca lsts (cdr lst)) | |
| (rplacd lst nil) | |
| (do ((lsts-rest (cdr lsts) (cdr lsts-rest)) | |
| (vals-last vals (cdr vals-last))) | |
| ((null lsts-rest) vals) | |
| (let ((lst (car lsts-rest))) | |
| (rplaca lsts-rest (cdr lst)) | |
| (rplacd vals-last lst) | |
| (rplacd lst nil)))))))) | |
| (some #'null lsts)) | |
| (values-list acc))))) | |
| #+sbcl | |
| (defun mvfold! (f initf &rest lsts) | |
| (declare (dynamic-extent lsts)) | |
| (declare (optimize (speed 3))) | |
| (when (null lsts) | |
| (return-from mvfold! (funcall initf))) | |
| (labels ((iter (&rest acc) | |
| (declare (dynamic-extent acc)) | |
| (if (some #'null lsts) | |
| (values-list acc) | |
| (multiple-value-call #'iter | |
| (multiple-value-call f | |
| (values-list acc) | |
| (values-list | |
| (let ((lst (car lsts)) vals) | |
| (psetf vals lst | |
| (car lsts) (cdr lst) | |
| (cdr lst) nil) | |
| (do ((lsts-rest (cdr lsts) (cdr lsts-rest)) | |
| (vals-last vals (cdr vals-last))) | |
| ((null lsts-rest) vals) | |
| (let ((lst (car lsts-rest))) | |
| (psetf (car lsts-rest) (cdr lst) | |
| (cdr vals-last) lst | |
| (cdr lst) nil)))))))))) | |
| (multiple-value-call #'iter (funcall initf)))) |
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
| (define-values (mvfold mvfold!) | |
| (begin | |
| (define (any f xs) | |
| (if (null? xs) | |
| #f | |
| (or (f (car xs)) (any f (cdr xs))))) | |
| (define (mvfold f initf . lsts) | |
| (define (acc . vals) | |
| (if (any null? lsts) | |
| (apply values vals) | |
| (call-with-values | |
| (lambda () | |
| (apply f | |
| (append | |
| vals | |
| (let ((xs (map car lsts))) | |
| (do ((rst lsts (cdr rst))) | |
| ((null? rst) xs) | |
| (set-car! rst (cdar rst))))))) | |
| acc))) | |
| (if (null? lsts) | |
| (initf) | |
| (call-with-values initf acc))) | |
| (define (mvfold! f initf . lsts) | |
| (define (acc . vals) | |
| (if (any null? lsts) | |
| (apply values vals) | |
| (call-with-values | |
| (lambda () | |
| (apply f | |
| (append! | |
| vals | |
| (let* ((lst (car lsts)) | |
| (vals lst)) | |
| (set-car! lsts (cdr lst)) | |
| (set-cdr! lst '()) | |
| (do ((lsts-rest (cdr lsts) (cdr lsts-rest)) | |
| (vals-last vals (cdr vals-last))) | |
| ((null? lsts-rest) vals) | |
| (let ((lst (car lsts-rest))) | |
| (set-car! lsts-rest (cdr lst)) | |
| (set-cdr! vals-last lst) | |
| (set-cdr! lst '()))))))) | |
| acc))) | |
| (if (null? lsts) | |
| (initf) | |
| (call-with-values initf acc))) | |
| (values mvfold mvfold!))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment