on-lisp要点(一)

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)))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值