I'm trying to improve upon Graham's alambda macro (because who really
wants to code up Y-combinator every time they want a recursive
anonymous function?) so that it can be called like lambda (i.e. w/out
a funcall).
;; Anaphoric lambda.
;;
(defmacro alambda (parms &body body)
`(labels ((self ,parms ,@body))
#'self))
;; John's improvement. Allow alamba to be called like lambda.
;;
(defmacro jalambda (parms &body body)
`(lambda ,parms
(labels ((self ,parms ,@body))
(funcall #'self ,@parms))))
This "improvement" however is moot. The macro expands to #'(lambda
(....) ...). Rendering it unable to be called like so (this was the
end goal for those w/ ADD):
((jalambda (n)
(if (> n 0) (cons n (self (- n 1)))))
4)
A simpler explanation (via code) can be seen here:
(defmacro test ()
`(lambda ()
(format t "this works!")))
TEST
CL-USER> (macroexpand '(test))
#'(LAMBDA () (FORMAT T "this works!"))
T
CL-USER> ((test))
; in: LAMBDA NIL
; ((TEST))
;
; caught ERROR:
; illegal function call
;
; compilation unit finished
; caught 1 ERROR condition
; Evaluation aborted.
So I take it as impossible to make a macro that can act like the
equivalent of:
((lambda (...) ...) args) ?
On 3 jul, 22:19, jrwats <······@gmail.com> wrote:
> I'm trying to improve upon Graham's alambda macro (because who really
> wants to code up Y-combinator every time they want a recursive
> anonymous function?) so that it can be called like lambda (i.e. w/out
> a funcall).
>
> ;; Anaphoric lambda.
> ;;
> (defmacro alambda (parms &body body)
> `(labels ((self ,parms ,@body))
> #'self))
>
> ;; John's improvement. Allow alamba to be called like lambda.
> ;;
> (defmacro jalambda (parms &body body)
> `(lambda ,parms
> (labels ((self ,parms ,@body))
> (funcall #'self ,@parms))))
This won't work if you need &rest, &optional or &key parameters. You
can (not tested):
(defmacro jalambda (parms &body body)
(let ((args (gensym)))
`(lambda (&rest ,args)
(labels ((self ,parms ,@body))
(apply #'self ,args)))))
or
(defmacro jalambda (parms &body body)
`(lambda ,parms
(labels ((self ,parms ,@body))
,(if (find '&rest parms)
`(apply #'self ,@(extract-parameters parms))
`(self ,@(extract-parameters parms))))))
It should be easy to implement the function EXTRACT-PARAMETERS.
[snip]
> So I take it as impossible to make a macro that can act like the
> equivalent of:
> ((lambda (...) ...) args) ?
Yes, this is impossible unless you use some reader macro of some sort.
In article
<····································@37g2000yqp.googlegroups.com>,
gugamilare <··········@gmail.com> wrote:
>
> > So I take it as impossible to make a macro that can act like the
> > equivalent of:
> > ((lambda (...) ...) args) ?
>
> Yes, this is impossible unless you use some reader macro of some sort.
Or you can hack the implementation. I have working versions of this for
MCL/CCL, SBCL and CLisp. At least they worked at one time. If anyone's
interested let me know and I'll dig them out of the mothballs.
rg