;; (take-and-drop 3 '(1 2 3 4 5 6)) => ((1 2 3) (4 5 6))
(defun take-and-drop (n l)
(label ((sazbi
(lambda (n l one)
(cond
((<= n 0) (list (nreverse one) l))
(true (sazbi (- n 1) (cdr l) (cons (car l) one)))))))
(sazbi n l nil)))
(defun take (n l) (car (take-and-drop n l)))
(defun drop (n l) (cadr (take-and-drop n l)))
(defun repeated (n v)
(cond
((<= n 0) nil)
(true (cons v (repeated (- n 1) v)))))
(defun left-pad-to (n v l)
(let ((lacking (- n (list-length l))))
(cond ((<= lacking 0) l)
(true (append (repeated lacking v) l)))))
;; example: (setq xs '(1 2 3 4 5))
;; (multilet ((a b c d e) xs) c) => 3
;; you can only multilet one list of variables at once.
(macro multilet
(lambda (args)
(cond
((atom (car args)) (error "multilet without enough parentheses"))
((atom (caar args)) (error "multilet without enough parentheses"))
(true
(label ((names (caar args))
(value-list (cadar args)))
`(apply (lambda ,names ,@(cdr args)) ,value-list))))))
;; example: (setq ns '(a b c d e))
;; (setq xs '((1 2 3 4 5) (6 7 8 9 10)))
;; (do-table (ns xs)
;; (print c))
;; => 3
;; 8
;; ()
(macro do-table
(lambda (args)
`(dolist (vlan ,(cadar args))
(multilet (,(eval (caar args)) vlan)
,@(cdr args)))))
;; elisp:
;; (put 'multilet 'lisp-indent-function 1)
;; (put 'do-table 'lisp-indent-function 1)