(defun seq-map (func seq)
(let ((out nil))
(dolist (item seq)
(setq out (cons (funcall func item) out)))
(reverse out)))
(defun mapcar (func seq) (seq-map func seq))
(defun seq-filter (func seq)
(let ((out nil))
(dolist (item seq)
(when (funcall func item)
(setq out (cons item out))))
(reverse out)))
(defun seq-reduce (func seq initial)
(let ((acc initial))
(dolist (item seq)
(setq acc (funcall func acc item)))
acc))
(defun seq-find (func seq &optional default)
(let ((hit nil) (found nil))
(dolist (item seq)
(when (and (not found) (funcall func item))
(setq hit item)
(setq found t)))
(if found hit default)))
(defun mapconcat (func seq &optional sep)
(let ((parts (seq-map func seq))
(out "")
(first t)
(sep (or sep "")))
(dolist (s parts)
(if first
(setq first nil)
(setq out (concat out sep)))
(setq out (concat out s)))
out))
(defmacro prog1 (first &rest body)
(let ((sym (gensym "prog1-")))
`(let ((,sym ,first))
,@body
,sym)))
(defmacro prog2 (first second &rest body)
`(progn ,first (prog1 ,second ,@body)))
(defun sort (seq pred)
(let ((out nil))
(dolist (item seq)
(let ((inserted nil) (new nil))
(dolist (x out)
(if (and (not inserted) (funcall pred item x))
(progn (setq new (cons item new))
(setq new (cons x new))
(setq inserted t))
(setq new (cons x new))))
(unless inserted
(setq new (cons item new)))
(setq out (reverse new))))
out))