I wrote this quicksort function:
(defun quicksort (lst)
(if (null lst)
nil
(let ((div (car lst))
(tail (cdr lst)))
(append (quicksort (remove-if-not (lambda (x) (< x div)) tail))
(list div)
(quicksort (remove-if (lambda (x) (< x div)) tail))))))
but I can’t rewrite it as macro, it does not work, nor does, for example, this simple foo (recursive sum – I know, a little silly, but just as example):
(defun Suma (lst)
(if (cdr lst)
(+ (Suma (cdr lst))
(car lst))
(car lst)))
works properly, but the macro:
(defmacro SumaMacro (lst)
'(if (cdr lst)
'(+ (prog (SUMAMACRO (cdr lst)))
(prog (car lst)))
'(car lst)))
seems to be wrong. Does someone have any suggestions about rewriting recursive functions as macro?
You’re mixing macro and runtime; or in other words, you’re mixing values and syntax. Here’s a very simple example:
The bad thing here is that the macro doesn’t execute the body, it just constructs a piece of code with the given body in it. So, when there’s that kind of a loop in a function, it’s protected by some conditional like
ifwhich will prevent an infinite loop. But in this macro code there is no such condition — you can see that the macro expands into the exact original form, which means that it’s trying to expand into some infinite piece of code. It’s just as if you’ve writtenthen hooked that generator function into the compiler. So to do these kinds of runtime loops, you’ll have to use a real function. (And when that’s needed, you can use
labelsto create a local function to do the recursive work.)