Jasper wrote:I don't like any of them very well, but the one with the dollar signs the best. See no particular reason to use $1 ,etc and not $any-symbol.
; cf = Compose function with optional currying.
; Example usage:
; (mapcar (cf (* 2) (+ 10 20) -) '(1 2 3))
; ==> (-32 -34 -36)
; Each argument to cf gets converted to a function,
; and the functions are applied in left to right
; order. E.g. (cf f1 f2 f3) is equivalent to
; (lambda (x) (f3 (f2 (f1 x))))
; Arguments accepted by cf:
; * #'name and 'name have their usual meanings.
; I.e. #'name names a function in lexical scope
; but 'name is only global.
; * name (unquoted) is #'name with #' elided. Note
; this contradicts the normal Lisp convention.
; * ''form has the same meaning form unquoted would
; have in the normal Lisp convention. E.g. to
; get the function from a variable as in
; (funcall var) use ''var instead of just var.
; * (/x a b c) is shorthand for (lambda (x) a b c)
; But there is no /y or anything, just /x.
; * (func 1 2 3) is to curry. I.e. it gets
; converted to (lambda (x) (func x 1 2 3))
; * Special case: If one of the curry args is a $
; then the non-curried arg takes the place of the
; $ instead of being leftmost.
; (func 1 2 $) = (lambda (x) (func 1 2 x))
; E.g. (cf (+ 1) (/ 1 $)) = 1/(x+1)
(defmacro cf (&rest xs)
(loop with argname = (gensym)
as x in (cons nil xs)
as curryargs = nil
as func = (if (atom x)
(case (car x)
(quote (if (and (consp (cadr x))
(eq (caadr x) 'quote))
(/x `(lambda (x) ,@(cdr x)))
(t (setq curryargs (cdr x))
as args = (if (member '$ curryargs)
(loop as x in curryargs collect
(if (eq x '$) argname x))
(nconc (list code) curryargs))
as code = argname then `(funcall ,func ,@args)
finally (return `(lambda (,argname) ,code))))
Users browsing this forum: No registered users and 2 guests