From: Conrad Barski
Subject: utility macro for recursive calculation
Date: 
Message-ID: <a4af10cf.0308122133.6712f26c@posting.google.com>
I have this anaphoric macro that I find incredibly useful but its
somewhat goofy so there's probably a better way of solving the same
problem that I'm missing.

The macro is:

(defmacro rcalc (vars init &rest rest)
  `(labels ((fn ,vars
		,@rest))
	   (fn ,@init)))


Its like a cross between a lambda function and the "reduce" function,
with an anaphoric "function variable" 'fn for calling itself
recursively.

For instance, if you need find the smallest number in the fibonnachi
series greater than 100 you could write:

(rcalc (a b) (1 1) (if (> a 100) a (fn b (+ a b))))

I find this so useful I'm sure there's other lispers who know a better
(more standard, but just as brief) way of solving this type of
problem. (Obviously this example with a fib series is kind of
contrived, because one would most likely use a HOF that is passed a
fib generator function. The point is I often find it convenient to do
a recursive "in place" calculation like this macro allows...)

From: Björn Lindberg
Subject: Re: utility macro for recursive calculation
Date: 
Message-ID: <hcsy8xwo5zk.fsf@fnatte.nada.kth.se>
·····················@yahoo.com (Conrad Barski) writes:

> I have this anaphoric macro that I find incredibly useful but its
> somewhat goofy so there's probably a better way of solving the same
> problem that I'm missing.
> 
> The macro is:
> 
> (defmacro rcalc (vars init &rest rest)
>   `(labels ((fn ,vars
> 		,@rest))
> 	   (fn ,@init)))
> 
> 
> Its like a cross between a lambda function and the "reduce" function,
> with an anaphoric "function variable" 'fn for calling itself
> recursively.
> 
> For instance, if you need find the smallest number in the fibonnachi
> series greater than 100 you could write:
> 
> (rcalc (a b) (1 1) (if (> a 100) a (fn b (+ a b))))

In the book Common Lisp by Wade Hennessy, he introduces a similar
macro which he calls ITERATE:

(defmacro iterate (name bindings &body body)
  `(labels ((,name ,(mapcar #'car bindings)
	     ,@body))
    (,name ,@(mapcar #'cadr bindings))))

Using it for your example, it could be written as follows:

(iterate fib ((a 1) (b 1)) (if (> a 100) a (fib b (+ a b))))

The only difference I can see compared to your macro is that with his
you get to choose the name of the recursive function, and the variable
bindings are established in more of a LET style.


Bj�rn
From: Luke Gorrie
Subject: Re: utility macro for recursive calculation
Date: 
Message-ID: <lh7k5gpfhm.fsf@dodo.bluetail.com>
·······@nada.kth.se (Bj�rn Lindberg) writes:

> In the book Common Lisp by Wade Hennessy, he introduces a similar
> macro which he calls ITERATE:
> 
> (defmacro iterate (name bindings &body body)
>   `(labels ((,name ,(mapcar #'car bindings)
> 	     ,@body))
>     (,name ,@(mapcar #'cadr bindings))))

And that's also like the named `let' in Scheme:

> (iterate fib ((a 1) (b 1)) (if (> a 100) a (fib b (+ a b))))

  (let     fib ((a 1) (b 1)) (if (> a 100) a (fib b (+ a b))))

Cheers,
Luke