Skip to content

Instantly share code, notes, and snippets.

@geoffrasb
Created March 22, 2012 16:32
Show Gist options
  • Select an option

  • Save geoffrasb/2159403 to your computer and use it in GitHub Desktop.

Select an option

Save geoffrasb/2159403 to your computer and use it in GitHub Desktop.
self-lambda
#|
usage:
(funcall (self-lambda (n) (if (> n 0)
(self (- n 1))
n))
5)
|#
(defmacro self-lambda (param-lst &rest body)
(let ((fn (gensym)))
(labels ((replace-self (lst) ;replace "self" to "funcall fn fn"
(cond
((null lst) nil)
((not (listp lst)) lst)
((eql (car lst) 'self)
(append `(funcall ,fn ,fn) (replace-self (cdr lst))))
((listp (car lst))
(cons (replace-self (car lst)) (replace-self (cdr lst))))
(t
(cons (car lst) (replace-self (cdr lst)))))))
(let ((new-param '()) (param-length (list-length param-lst)))
(do ((i 0 (+ i 1)))
((= i param-length) nil)
(setf new-param (cons (gensym) new-param)))
`(lambda (,@new-param)
(labels ((lmbd (,fn ,@param-lst)
,@(mapcar #'replace-self body)))
(funcall #'lmbd #'lmbd ,@new-param)))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment