Skip to content

Instantly share code, notes, and snippets.

@alandipert
Created July 10, 2020 05:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alandipert/4a5fbcc03437703cfb550bc79e0fdbdc to your computer and use it in GitHub Desktop.
Save alandipert/4a5fbcc03437703cfb550bc79e0fdbdc to your computer and use it in GitHub Desktop.
(defconstant mv-limit 20)
(defparameter *mv-expected* 1)
(defparameter *mv* (make-array mv-limit))
(defun mv (&rest vals)
(do ((i 0 (1+ i))
(vs vals (cdr vs)))
((or (eql i *mv-expected*) (null vs))
(setq *mv-expected* (min i mv-limit))
(car vals))
(setf (aref *mv* i) (car vs))))
(defmacro mv-list (form)
(let ((val1# (gensym)))
`(let* ((*mv-expected* mv-limit)
(,val1# ,form))
(if (eql *mv-expected* mv-limit)
(list ,val1#)
(coerce (subseq *mv* 0 *mv-expected*)
'list)))))
(defun make-mv-bindings (vars val1# &aux (i 0))
(mapcar (lambda (var)
(prog1
(if (zerop i)
`(,var ,val1#)
`(,var (when (< ,i *mv-expected* mv-limit)
(aref *mv* ,i))))
(incf i)))
vars))
(defmacro mv-bind (vars expr &body body)
(let ((val1# (gensym)))
`(let* ((*mv-expected* ,(length vars))
(,val1# ,expr))
(let ,(make-mv-bindings vars val1#)
,@body))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment