Skip to content

Instantly share code, notes, and snippets.

@wjur
Forked from jaeschliman/change_fun.lisp
Created October 30, 2012 11:43
Show Gist options
  • Save wjur/3979759 to your computer and use it in GitHub Desktop.
Save wjur/3979759 to your computer and use it in GitHub Desktop.
;; your original change_fun
(defun change_fun (fun x)
(cond ((eq fun 'sin) (list 'cos x))
((eq fun 'cos) (list '- 0 (list 'sin x)))
((eq fun 'tan) (list '+ 1 (list '* (list 'tan x) (list 'tan x))))
((eq fun 'log) (list '/ 1 x))
(T
(error "Not a function! ~S " fun)))
)
;; using backquote and case
(defun change-fun (fun x)
(case fun
(sin `(cos ,x))
(cos `(- 0 (sin ,x)))
(tan `(+ 1 (* (tan ,x) (tan ,x))))
(log `(/ 1 ,x))
(t (error "Not a function! ~S " fun))))
;;; built in function subst:
;;CL-USER> (subst 'n :x '(+ 1 (* (tan :x) (tan :x))))
;; => (+ 1 (* (TAN N) (TAN N)))
;; to subst more than one thing:
(defun subst-all (pairs tree)
(reduce (lambda (tree p)
(subst (cdr p) (car p) tree))
pairs :initial-value tree))
;;CL-USER> (subst-all '((x . 5) (y . 10)) '(+ x y))
;; => (+ 5 10)
;; a nice macro
(defmacro subst-case (form (&rest vars) &body cases)
(let ((pairs (mapcar (lambda (sym)
`(cons ',sym ,sym)) vars))
(cases (mapcar (lambda (clause)
(if (eq (car clause) t)
clause
(list (car clause)
`(quote ,@(cdr clause)))))
cases)))
`(subst-all (list ,@pairs)
(case ,form
,@cases))))
;; nice and clean now!
(defun change-fun (fun x)
(subst-case fun (x)
(sin (cos x))
(cos (- 0 (sin x)))
(tan (+ 1 (* (tan x) (tan x))))
(log (/ 1 x))
(t (error "Not a function! ~S " fun))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment