Common Lisp 学习记录 1

学习书籍--《Land of Lisp》

数据类型:
字符:#\
符号:'
字符串:""

特殊字符:
#\newline:新的一行
#\tab:
#\space:

45p:
1. Lisp函数使用命令'(defun funtion_name (arguments))' 创建函数
2. funtion_name后面的括号为空,表示该函数为无参函数

47p:
1. setf :命令,修改变量值

48p:
1. let :命令,对局部变量设值,用全括号对变量集进行包裹,同时,变量集中的每个变量赋值表达式,也用全括号包裹,例如 (let ((a 1)(b 2)(c 3)))

50p:
1.flet :命令,定义局部方法,括号的规则同let,例如 (flet ((a (n) (+ n 10)) (b (n) (+ n 20))))
2.labels :命令,也是定义局部方法,不同的是,labels中的方法可以互相调用,而flet命令下的方法不能互相调用

52p:
1.简单语法就是Lisp语言的规定特性

54p:
1.使用'/'除法函数时,如果除数与被除数都是整数,则计算结果表示为分数形式,如果其中之一为浮点数,则计算结果就为浮点数,除此以外,任何整数与浮点数进行算数操作时,结果都是浮点数。

56p:
1.Lisp通过代码模式(code mode)和数据模式(data mode)来区分所处理的语句是代码还是数据,加了单引号’的表达式即为数据,反之为需要计算的代码

2.Lisp的代码是一种特殊的列表类型: 形式(form)。
所有代码都当作命令(函数)来执行,而遵循form语法的代码就是一个合法命令,form的语法为:(funtion_name argment1 argment2 ...),命令(函数)名放置为form列表的第一个元素,其余元素即被当作为命令的参数。

58p:
1.列表lists是Lisp语言最重要的特性之一,它们是你所有的Lisp代码能关联在一起的关键。Lisp代码由N(N>=1)个List组合而成
2.cons cell 是lists结构的基本构成元素,lists是由1到多个的cons cell关联而成。
3.cons cell 是一种抽象的结构,cell通过之间的相互关联构成lists,cons cell就类似数据结构中的链表,多个cell构成一个表链,前一个cell持有下一个cell的引用。
例如,(1 2 3) 这个form由一个list构成,而其又由3个数字cons cell组合而成,数字1的cons cell 指向数字2的cons cell,然后数字2的cons cell指向数字3,以此类推,其中,数字3的cons cell最为最后一个cell,它的cell引用指向NIL,也就是空引用,以此作为list的终结
4.操作cons cell的基础lists操作函数有:
1) cons :关联任何两个数据cell为一个list。
例如 (cons 'a 'b) 结果为 (a . b) .符号标记此cons cell为两个cell构成
(cons 'a '(a b)) 结果为 (a a b) 超过两个cell的关联,就没有.标记符号
2) car : 获取list的第一个cell
3)cdr : 获取list的第二个cell
小技巧:
car 和 cdr的组合运用可以用一个组合函数来表示,
比如(car (cdr '(List))) = cadr ,(cdr (car '(List))) = cdar
函数的执行顺序是函数名的倒序,比如cadr 是先执行cdr,后执行car
Lisp已经内建了支持到四级组合c*r函数,比如cdaddr,超过四级的,需要自己创建,比如cdadadr

60p:
1.在Lisp中,cons cell 链和list实际上是同一个事物,list就只是持有两cell的cell长链

61p:
1.list : 函数可将多个cell合并为一个list

71p:
1.以下list等同于false,它们之间也互为等同:'() ,() , 'nil , nil

74p:
1.progn : 在单条表达式中,执行额外的命令,以达到在一条语句中处理不同命令,且相互之间无关联。它返回最后一个命令的计算值

74p:
依据判断条件来执行多个命令,且返回最后一个命令的计算值的命令有以下两个:

1.when : 判断条件为true时执行计算。
2.unless : 判断条件为false时执行计算。

76p:
代码错误(56页):函数pudding-eater 输入johnny参数值时,全局变量的值应为"stupid-lisp-alien",而不是"JOHNNY"

78p:
case 命令只能判断处理符号值,不能处理字符串类型值

81p:
1. member 命令返回匹配条件的list,而不是具体的值。例如 (member '2 '(1 2 3 4 5)) 返回 (2 3 4 5)
这样设计有利于将返回值用以作为其他函数的参数,此外,避免了判断list中是否有nil时,如果只返回值,而不是list,出现的条件处理操作不正确的问题。因为只会返回nil,则条件判断为false,会背离判断nil是否作为member存在于list中的初衷。
2. find-if 命令可以将函数作为参数,查找list元素传入函数计算,返回第一个计算结果为true的元素。
例如 (find-if #'oddp '(2 3 6 8)) ;查找list中为偶数的元素,并返回查找到的第一个符合条件的元素 2

82-8 p:
equal, eql, eq , =, string-equal , equalp 使用技巧:康纳德的大拇指原则
1.eq 用来对比符号(symbols)类型 'a
2.equal 用来对比所有类型 '(a b),"a",#\a,(list a a),5,5.0

其他区别:
1.eql : 与eq类似,它还能对比数字、字符类型
2.equalp : 与equal类似,它能处理更复杂的情况,例如对比整数与浮点数,忽略大小写对比字符串

注意:eq也可以用来对比cons cell,但除非cell是它自身(由同一个cons构造),否则对比结果会为false,这个特性可以用来判断一个cells是否是同一个
例如 (defvar *aa* (cons 'a 'a))
(eq *aa* *aa*) ;结果为true
(eq *aa* '(a a)) ;结果为false

84p:
代码错误(64页):
(equal '(1 2 3) (cons 1 (cons 2 (cons 3))))
应为:
(equal '(1 2 3) (cons 1 (cons 2 (cons 3 nil))))

91p:
assoc :命令,参数1为key,参数2为list。
使用key(键)检索list的条目

93p:
quasiquoting : 特性,允许在函数中嵌入数据块,使用重引号"`"来标记,这些代码块在函数中是数据模式,之后在函数的元算过程中,可以反转为代码模式,并计算后返回值。
其中,需要在数据块中动态计算的代码部分(函数,变量,参数),需要在函数前添加","符号,如果加了","符号的代码不是可计算的函数,则会报错,如果需要在显示","号而不是标注函数,则需要添加转义符"\"来进行转义

例如
(defvar *test* '(a b c))
(princ `(this is quasiquoting test \, values is ,(cdr *test*)))
将显示
(THIS IS QUASIQUOTING TEST , VALUES IS (B C))
(THIS IS QUASIQUOTING TEST |,| VALUES IS (B C))

94p:
mapcar :命令,参数1为所要执行的函数名称,参数2为list 。
遍历list中的所有元素,并传入函数执行计算,返回结果list
例如 (mapcar #'princ '(1 2 3 4 5)) 或者 (mapcar #'princ (list 1 2 3 4 5))
结果:
123
(1 2 3)

95p:
higher-order functions :Lisp高阶函数特性。代指一个函数传入另一个函数为参数的特性。
其中,被传入的函数以符号"#'"+函数名称(#'fun_name)的方式作为参数
例如 mapcar、find-if、apply

96p:
append : 命令,将多个单独的list合并成一个大list
apply : 命令,参数1为所要执行的函数名称,参数2为list
将list分解成多个独立的小list,然后同时作为多个参数全部传入参数函数中进行计算,返回结果list
注意事项:传入的参数函数必须是能接受多参的函数,否则将出现异常
例如 (apply #'append '((a 1) (b 2) (c 3)))
结果:(A 1 B 2 C 3)

101p:
find (item find_list :keyword):命令,指定条目和查找关键字参数,查找目标list并返回查找到的第一个条目list。
关键字使用":"符号标识,关键字参数包含两个部分:名称和键值,键值可以是#'标识的函数
例:
技巧1:在list的第一个cons cell中查找条目
(find '7 '((5 x) (3 y) (7 z)) :key #'car)
结果:
(7 Z)

技巧2:在list的第二个cons cell中查找条目
(find 'z '((5 x) (3 y) (7 z)) :key #'cadr) ;cdr查找到(z nil),然后car提取z,返回z所在的(7 z)
结果:
(7 Z)

(find 'b '((1 (b c)) (2 (d e)) (3 (f j))) :key #'caadr) :步骤cdr->(b c)->car->(b nil)->car->b
(1 (B C))

规则总结:
1. 只考察list中的单个条目,((a b) (. .))->(a b)
2. 如果是简单list,条目之前有几个前置条目,就加几个d,被查找的条目为a。
cell 1 : (a b) -> car ->a
cell 2 : (a b) -> cadr ->b
3. 如果是复杂组合list,参照规则1,并且左括号算作a。
cell 1 : (1 (a b)) -> caadr->a
cell 2 : (1 (a b)) -> cadadr->b

member,find,assoc区别:
1.member :只能处理单个大list,返回被查找的条目list
2.find : 能处理单个大list和组合list,其中,查找单个大list时,不需要指定关键词参数。
3.assoc :只能处理组合list,以list的条目的cons cell 1 作为键值查找条目,返回被查找条目的cons cell 2

102p:
1. push (new_item list) : 命令,往原list中添加新的条目
(defparameter *foo* '(b c))
(push 'a *foo*)
(A B C)
(push '(1 2) *foo*)
((1 2) A B C)

108p:
1. read :命令,可以获取用户的屏幕输入值
111p:
1. read-line :命令,读取行任意字符的字符串
2. homoiconic :特性,是指用相同数据结构存储数据与程序代码

112p:
1.eval :命令,将一段数据代码中的可执行部分当作程序代码进行计算处理。可以允许程序自更改代码

115p:
1. concatenate (type arg1 arg2 ...) :命令,联接字符串,type 为 联接参数,其余参数为被连接的字符串或返回值为字符串的命令。
例:
(concatenate 'string "(" (read-line) ")" "test" "command")
执行:
控制台输入:yoya
结果:
yoya testcommand

2. 为字符串添加单引号"'" : 使用'quote 或 ' 在list命令中拼合字符串。'quote是拼合成一个符号类型的字符串,'是拼合成新的带引号的list
注意:list命令中被添加引号的参数不能超过一个。
例:
(list 'quote 'abc) --> 'ABC
(list ' 'abc) --> ('ABC)
(list 'quote 'a 'b 'c) --> (QUOTE 'A 'B 'C)

118p:
1. prin1-to-string : 命令,把符号list转换为字符串,1表示结果保持为单行。
2. coerce :命令,把字符串转换成字符list

119p:
1. char-upcase、char-downcase :命令,转换字符的大小写,up为大写,down为小写。

124p:
1. (lambda (args) (fun_content)):命令,创建匿名方法,lambda表达式的Lisp实现。args参数作为匿名方法的接收参数,fun_content参数为匿名方法的方法体。
例:
(mapcar (lambda (n) (/ n 2)) '(2 4 6))
结果:
(1 2 3)

转载于:https://www.cnblogs.com/yoya/archive/2012/03/16/2399793.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值