;;; 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. ;;; 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)))))