From: jrwats
Subject: anaphoric lambda
Date: 
Message-ID: <0fba4408-3b7f-4924-a021-9ab194d4172d@12g2000pri.googlegroups.com>
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) ?

From: gugamilare
Subject: Re: anaphoric lambda
Date: 
Message-ID: <3fcd66e8-e48a-40c0-ad81-71b999da2e3c@37g2000yqp.googlegroups.com>
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.
From: Ron Garret
Subject: Re: anaphoric lambda
Date: 
Message-ID: <rNOSPAMon-460E7E.19530103072009@news.albasani.net>
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