Archive for February 2009
descartes product; revisited
I’ve already posted a solution at this post. Sometimes the product itself is too big and/or it doesn’t make sense to store in memory all the elements. I needed to just iterate through the elements. Here’s the solution I invented : )
(defun circularize (li)
(loop
as e in (cons nil li)
collect e into result
finally
(nconc result result)
(return (cdr result))))
(defun lazy-citer (li)
(let ((rest (circularize li)))
(lambda ()
(destructuring-bind (h . re)
rest
(progn
(setf rest re) h)))))
(defun i-compose (lci1 lci2)
(let ((v2 (funcall lci2)))
(lambda ()
(let ((v1 (funcall lci1)))
(if v1
(cons v1 v2)
(progn
(setf v2 (funcall lci2))
(cons (funcall lci1) v2)))))))
(defun d-sequencer (&rest seqs)
(if (null seqs)
(lazy-citer seqs)
(i-compose (lazy-citer (car seqs))
(apply #'d-sequencer (cdr seqs)))))
You can use it like this (note that the result sequence is also circular and that arguments can’t contain nil as element of a list):
CL-USER> (d-sequencer '(1 2 3) '(a b c) (list #'car #'cdr))
#<CLOSURE (LAMBDA ()) {B6945D5}>
CL-USER> (setq s *)
#<CLOSURE (LAMBDA ()) {A929FED}>
CL-USER> (funcall s)
(1 A #<FUNCTION CAR>)
CL-USER> (funcall s)
(2 A #<FUNCTION CAR>)
CL-USER> (funcall s)
(3 A #<FUNCTION CAR>)
CL-USER> (funcall s)
(1 B #<FUNCTION CAR>)
CL-USER> (funcall s)
(2 B #<FUNCTION CAR>)
CL-USER> (funcall s)
(3 B #<FUNCTION CAR>)
CL-USER> (funcall s)
(1 C #<FUNCTION CAR>)
CL-USER> (funcall s)
(2 C #<FUNCTION CAR>)
CL-USER> (funcall s)
(3 C #<FUNCTION CAR>)
CL-USER> (funcall s)
(1 A #<FUNCTION CDR>)
CL-USER> (funcall s)
(2 A #<FUNCTION CDR>)
CL-USER>
insert defun for symbol; slime
A small extension of mine for slime. When you’re standing on a symbol, you can request emacs (with `C-c a f’ here) to place a new defun for the symbol right before the actual top level form at point.
(require 'slime)
(defun dot-emacs-my-add-def (what)
(let ((s (slime-symbol-name-at-point)))
(if s
(progn
(set-mark (point))
(beginning-of-defun)
(insert-string (concat "(" what " " s " ()\n\n"))
(backward-char 3)))))
(defun dot-emacs-my-add-defun ()
(interactive)
(dot-emacs-my-add-def "defun"))
(slime-define-key "af" 'dot-emacs-my-add-defun :prefixed t)
Moreover, when finished, by pressing `C-u C-Space’, one can return back to the point from where the command was called.