chapter-2
1.symbol-value & symbol-function
lisp中可以通过symbol-value, symbol-function从对应的symbol获取变量值和函数值。
(defun double (x) (* x 2))
(defvar double 0)
(setq double 2)
(symbol-value 'double)
(symbol-function 'double)
2、将函数,谓词作为参数
与其把功能写死,不如传进去一个函数参数。
mapcar remove-if sort
3.闭包
(defun make-adder (n)
#(lambda (x) (+ x n))
4.局部函数
(defun count-instances (obj lsts)
(labels ((instances-in (lst)
(if (consp lst)
(+ (if (eq (car lst) obj) 1 0)
(instances-in (cdr lst)))
0)))
(mapcar #'instances-in lsts)))
5.eql&equal
eql比较两个对象是否是同一个对象,equal表示两个对象的内容是否相同。
chapter-3
1、副作用&函数式编程
函数式编程意味着利用返回值而不是副作用来写程序。副作用包括破坏性修改对象(例如通过replaca)以
及变量赋值(例如通过setq)。如果副作用很少并且局部化,程序就会容易阅读,测试和调试。(感觉就是吐槽命令式编程C&C++)
2、返回多值(values,multiple-value-bind)
(defun powers (x)
(values x (sqrt x) (expt x 2)
3.简码之美(lisp宏)
如果说简洁是智慧的灵魂,那么它和效率也同是优秀软件的本质特征。编写和维护一个程序的开销与其长
度成正比。同等条件下,程序越短越好.
chapter-5
1记住过去.
通用的将函数设计为记忆的代码:
(defun memoize (fn)
(let ((cache (make-hash-table :test #'equal)))
#'(lambda (&rest args)
(multiple-value-bind (val win) (gethash args cache)
(if win
val
(setf (gethash args cache)
(apply fn args)))))))
2 复合函数
(defun compose (&rest fns)
(if fns
(let ((fn1 (car (last fns)))
(fns (butlast fns)))
#'(lambda (&rest args)
(reduce #'funcall fns
:from-end t
:initial-value (apply fn1 args))))
#'identity))
3、条件,逻辑变形
if else的变形,and,or的变形实现
(defun fif (if then &optional else)
#'(lambda (x)
(if (funcall if x)
(funcall then x)
(if else (funcall else x)))))
(defun fint (fn &rest fns)
(if (null fns)
fn
(let ((chain (apply #'fint fns)))
#'(lambda (x)
(and (funcall fn x) (funcall chain x))))))
(defun fun (fn &rest fns)
(if (null fns)
fn
(let ((chain (apply #'fun fns)))
#'(lambda (x)
(or (funcall fn x) (funcall chain x))))))
4.在cdr上递归
(defun lrec (rec &optional base)
(labels ((self (lst)
(if (null lst)
(if (functionp base)
(funcall base)
base)
(funcall rec (car lst)
#'(lambda ()
(self (cdr lst)))))))
#'self))
; copy-list
(lrec #'(lambda (x f) (cons x (funcall f))))
; remove-duplicates
(lrec #'(lambda (x f) (adjoin x (funcall f))))
; find-if,
(defun find-if-1 (pred)
(lrec #'(lambda (x f) (if (funcall pred x) x (funcall f)))))
;for some function fn
(defun some-1 (pred)
(lrec #'(lambda (x f) (or (funcall pred x) (funcall f)))))
5. 在子树上递归
(defun ttrav (rec &optional (base #'identity))
(labels ((self (tree)
(if (atom tree)
(if (functionp base)
(funcall base tree)
base)
(funcall rec (self (car tree))
(if (cdr tree)
(self (cdr tree)))))))
#'self))
; our-copy-tree
(ttrav #'cons)
; count-leaves
(ttrav #'(lambda (l r) (+ l (or r 1))) 1)
; flatten
(ttrav #'nconc #'mklist)
(defun trec (rec &optional (base #'identiy))
(labels
((self (tree)
(if (atom tree)
(if (functionp base)
(funcall base tree)
base)
(funcall rec tree
#'(lambda ()
(self (car tree)))
#'(lambda ()
(if (cdr tree)
(self (cdr tree))))))))
#'self))
(trec #'(lambda (o l r) (or (funcall l) (funcall r)))
#'(lambda (tree) (and (oddp tree) tree)))