;;; SELF-MOD.LSP
;;; example for self-modifying code within AutoLISP
;;; works only with simple lisps which store functions as lambda lists
;;;
;;; (c) 1996 Reini Urban
;;; Permission to use, copy, modify, and distribute this software
;;; for any purpose and without fee is hereby granted, provided
;;; that the above copyright notice appears in all copies and that
;;; both that copyright notice and this permission notice appear in
;;; all supporting documentation.
;;; This is the normal recursive definition of the factorial
;;; its simple but inefficient, because it doesn't store intermediate results
(defun fact-simple (n)
(cond ((zerop n ) 1)
(T (* n (fact-simple (1- n))))))
;;; therefore we cache previously calculated results in the function itself
;;;
;;; (fact 1) -> 1
;;; creates:
;;; (defun fact (n)
;;; (cond ((zerop n) 1)
;;; ((= n 1) 1)
;;; (T .. (* n (fact (1- n))))))
;;;
;;; (fact 4) -> 24
;;; creates:
;;; (defun fact (n)
;;; (cond ((zerop n) 1)
;;; ((= n 1) 1)
;;; ((= n 4) 24)
;;; (T .. (* n (fact (1- n))))))
;;;
;;; fact: ((n) (cond ((zerop n) 1) .. (T .. (* n (fac (1- n)))))))
;;; car cadr cdadr (last (cdadr fact))
(defun fact (n / old result)
(cond ((zerop n) 1)
(T
(setq old fact)
(setq fact (list '(n)
(cons 'cond
(append (butlast (cdadr old))
(list (list (list '= 'n n)
(setq result (* n (fact (1- n))))))
(list (last (cdadr old)))))
))
result
)
)
)
;;; helper functions for list manipulation
;;; list without the last
(defun butlast (lst)
(head lst (- (length lst) 2)))
;;; all elements until the including (nth n lst),
;;; (head '(0 1 2 3) 2) -> '(0 1 2)
(defun head (lst n)
(if (not (minusp n))
(cons (car lst) (head (cdr lst) (1- n)))))