Dear Log,
Today's inane new elisp macro of mine:
(defmacro f_x (&rest Body)
"Make these expressions a function with 'x' holding its one parameter"
(list 'function (cons 'lambda (cons (cons 'x nil) Body))))
So this:
(f_x (print "I like pie and %s" x) (* 3.14 x))
is a handy shorthand that expands to this:
(function (lambda (x) (print "I like pie and %s" x) (* 3.14 x)))
This just came to me; I stole the idea from the implicitly-declared parameters in Perl 6.
(defmacro fn (&rest body)
(let* ((env (make-hash-table:test 'eq))
(new-body (fn-expand env `(progn,@body)))
(parameters '()))
(maphash #'(lambda (key &optional value)
(setq parameters (cons key parameters)))
env)
`(lambda,(sort parameters #'string-lessp)
,@(cdr new-body))))
(defun fn-expand (env body)
(cond ((symbolp body)
(when (let ((case-fold-search t))
(string-match "^\\^[a-z][-_a-z0-9]*$" (symbol-name body)))
(puthash body t env))
body)
((and (consp body) (symbolp (car body)))
(when (eq (car body) 'fn)
(throw "(fn BODY...) does not yet support nesting"))
(cons (car body)
(mapcar #'(lambda (arg) (fn-expand env arg))
(cdr body))))
(t
body)))
Now you can do things like this:
(fn (print "I like pie and %s" ^x) (* 3.14 ^x))
(mapcar (fn (+ 7 ^x)) list)
(maphash (fn (puthash ^key ^val new-hash)) old-hash)
That last one in particular is something that can't be done with your f_x
macro.
Share and enjoy!
Re:An alternative approach
TorgoX on 2006-07-17T22:25:46
WOW! You're hardcore!