onlisp 小笔记

10 views
Skip to first unread message

linlin lin

unread,
Jun 8, 2011, 10:56:46 AM6/8/11
to lisp-...@googlegroups.com
onlisp
Lisp是一门可以编程的编程语言。
自底以上编写程序的方法,是Lisp与生俱来的强项。
一旦定位错误的地方,就立即重写它,那么是终的产品将会比事先你花几个星期的时间精心设计的结果更加优雅。
(应用: Emacs,AutoCAD,Interleaf(高端出版系统))


第二章
(defun double (x) (+ x x))
#'double ; 将函数double 映射为对象
(eq #'double (car (list #'double)))
lambda 用法: lambda 参数列表 包含零个以上表达式主体
(lambda (x) (* x 2))
((lambda (x) (+ x x)) 3) ; 6
(setf double 5)
(double double) ; 10 ,第一个double为函数,第二个为数值5,lisp自动区分
(symbol-value 'double) ;由符号映射到数值
(symbol-function 'double) ; 由符号映射到函数


函数与变量可以有不同的命名空间
(setq double 2)
(double double) ; 4,前者为函数,后者为数值2
(symbol-value 'double) ;
(symbol-function 'double) ;
(setq x #'append)
(eq (symbol-value 'x) (symbol-function 'append)) ; t

(+ 1 2)
(apply #'+ '(1 2))
(apply (symbol-function '+) '(1 2))
(apply (symbol-function '+) 1 2 '(3 4)) ;后面用cons组合成参数
(funcall #'+ 1 2 3) ;类似apply,但参数不是列表

(mapcar #'(lambda (x) (+ x 10)) '( 1 2 3))
(remove-if #'evenp '(1 2 3 4))

(remove-if #'(lambda (x) (> x 3)) '(1 2 3 4 5 6 2))
(1 2 3 2)
(remove-if-not #'(lambda (x) (> x 3)) '(1 2 3 4 5 6 2))
(4 5 6)
(remove-if (complement #'evenp ) '(1 2 3 4 5))
(2 4)

自己实现一个remove-if
(defun our-remove-if (fn lst)
(if (null lst)
nil
(if (funcall fn (car lst))
(our-remove-if fn (cdr lst))
(cons (car lst) (our-remove-if fn (cdr lst))))))

与其把功能写死,不如传去一个函数参数

(setq a '(a b)) b '(b c))
(nconc a b) ; (setq a (append a b))

(mapcan #'sqrt '(1 2 3)) ; 1.73205, (sqrt (car (last '(1 2 3))))
(funcall #'sqrt 9)

(defun find2 (fn,lst)
(if (null lst)
nil
(let ((val (funcall fn (car lst))))
(if val
(values (car lst) val)
(find2 fn (cdr lst))))))

(> (length '(a b c)) (length '(d e f)))
(mapcar fn (append x y z))

(proclaim '(inline last1 single append1 conc1 mklist)) ;声明为inline函数
(defun last1 (lst)
(car (last lst)))

(= (length lst) 1) ;低效
(defun single (lst)
(and (consp lst) (not (cdr lst))))

(defun append1 (lst obj)
(append lst (list obj)))

(defun conc1 (lst obj)
(nconc lst (list obj)))

(defun mklist (obj)
(if (listp obj) obj (list obj)))

比较两个列表的长度,也可以
(> (length x) (length y)) ;低效
(defun longer (x y)
(labels ((compare (x y)
(and (consp (x)
(or (null y)
(compare (cdr x) (cdr y))))))
(if (and (listp x) (listp y))
(compare x y)
(> (length x) (length y))))))

(defun filter (fn lst)
(let ((acc nil))
(dolist (x lst)
(let ((val (funcall fn x)))
(if val (push val acc ))))
nreverse acc))

(dolist (x '(1 2 3)) (print (+ x 10)))
(nreverse '(a b c)) ; (c b a)
(reverse '(a b c)) ; (c b a)

(zerop 3) ; 是否为0

(defun group (source n)
(if (zerop n) (error "zero length"))
(labels ((rec (source acc)
(let ((rest (nthcdr n source)))
(if (consp rest)
(rec rest (cons (subseq source 0 n) acc))
(nreverse (cons source acc)))))))
(if source (rec source nil) nil))

(subseq '(a b c d e) 2 4) ; (c d)
(nth 2 '(a b c d)) ; c
(nthcdr 2 '(a b c d)) ; (c d)
(listp '()) ; T
(consp '()) ; nil, listp 与 consp都是判断是否为列表,但当列表为空时,listp返回T,consp返回nil

(mapcar #'(lambda (x) (+ x 10)) '(1 2 3))
(reduce #'+ '(1 2 3)) ; 求和
(reduce #'* '(1 2 3)) ; 求乘积
reduce 用法
reduce function sequence &key key from-end start end initial-value => result

(position 'b '(a b c d)) ; 1

潘飞

unread,
Jun 8, 2011, 9:44:51 PM6/8/11
to lisp-...@googlegroups.com
感谢分享

2011/6/8 linlin lin <maka...@gmail.com>



--
Stay Hungry. Stay Foolish.

Reply all
Reply to author
Forward
0 new messages