mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2025-04-26 15:13:56 +00:00
Merge pull request #456 from mut0u/master
fix some mistake in common-lisp
This commit is contained in:
commit
1f42f890f6
@ -5,15 +5,16 @@ contributors:
|
||||
- ["Paul Nathan", "https://github.com/pnathan"]
|
||||
translators:
|
||||
- ["Mac David", "http://macdavid313.com"]
|
||||
- ["mut0u", "http://github.com/mut0u"]
|
||||
lang: zh-cn
|
||||
---
|
||||
|
||||
ANSI Common Lisp 是一个广泛通用于各个工业领域的、支持多种范式的编程语言。
|
||||
这门语言也经常被引用作“可编程的编程语言”(可以写代码的代码)。
|
||||
|
||||
经典的入门点为[已完全免费提供的《实用 Common Lisp 编程》](http://www.gigamonkeys.com/book/)
|
||||
免费的经典的入门书籍[《实用 Common Lisp 编程》](http://www.gigamonkeys.com/book/)
|
||||
|
||||
另外还有一本近期内比较热门的
|
||||
另外还有一本热门的近期出版的
|
||||
[Land of Lisp](http://landoflisp.com/).
|
||||
|
||||
```scheme
|
||||
@ -23,7 +24,7 @@ ANSI Common Lisp 是一个广泛通用于各个工业领域的、支持多种范
|
||||
|
||||
;;; 一般形式
|
||||
|
||||
;; Lisp有两个基本的语法部件:原子,以及S-表达式。
|
||||
;; Lisp有两个基本的语法单元:原子(atom),以及S-表达式。
|
||||
;; 一般的,一组S-表达式被称为“组合式”。
|
||||
|
||||
10 ; 一个原子; 它对自身进行求值
|
||||
@ -52,12 +53,12 @@ t ;还是一个原子,代表逻辑真值。
|
||||
|
||||
;;; 运行环境
|
||||
|
||||
;; 有很多不同的Common Lisp的实现;并且大部分的实现是符合标准的。
|
||||
;; 有很多不同的Common Lisp的实现;并且大部分的实现是一致(可移植)的。
|
||||
;; 对于入门学习来说,CLISP是个不错的选择。
|
||||
|
||||
;; 可以通过QuickLisp.org's Quicklisp系统可以管理你的库。
|
||||
|
||||
;; 通常,使用一个文本编辑器和一个同时在运行的“REPL”来开发Common Lisp;
|
||||
;; 通常,使用一个文本编辑器和一个的“REPL”来开发Common Lisp;
|
||||
;; (译者注:“REPL”指读取-求值-打印循环)。
|
||||
;; “REPL”允许对程序进行交互式的运行、调试,就好像在系统中这是一场“现场直播”。
|
||||
|
||||
@ -120,10 +121,10 @@ nil ; 逻辑假,或者空列表
|
||||
"Hello, world!"
|
||||
"Benjamin \"Bugsy\" Siegel" ;反斜杠用作转义字符
|
||||
|
||||
;; 字符串可以被连接起来
|
||||
;; 可以拼接字符串
|
||||
(concatenate 'string "Hello " "world!") ; => "Hello world!"
|
||||
|
||||
;; 一个字符串也可被视作一个字符的序列
|
||||
;; 一个字符串也可被视作一个字符序列
|
||||
(elt "Apple" 0) ; => #\A
|
||||
|
||||
;; `format`被用于格式化字符串
|
||||
@ -138,9 +139,10 @@ nil ; 逻辑假,或者空列表
|
||||
;; 2. 变量
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; 你可以通过`defparameter`创建一个全局(动态)变量
|
||||
;; 除了:()[]{}",'`;#|\ 这些字符,其他任何字符都可被用于变量名
|
||||
;; 变量名可以是除了:()[]{}",'`;#|\ 这些字符之外的其他任何字符
|
||||
|
||||
;; 动态变量名应该由*号开头与结尾!
|
||||
;; (译者注:这个只是一个习惯)
|
||||
|
||||
(defparameter *some-var* 5)
|
||||
*some-var* ; => 5
|
||||
@ -153,7 +155,7 @@ nil ; 逻辑假,或者空列表
|
||||
;; 不要尝试那样做。
|
||||
|
||||
|
||||
;; 局部绑定:'me'被绑定到"dance with you"上,当且仅当它在(let ...)内有效。
|
||||
;; 局部绑定:在(let ...)语句内,'me'被绑定到"dance with you"上。
|
||||
;; `let`总是返回在其作用域内最后一个表达式的值
|
||||
|
||||
(let ((me "dance with you"))
|
||||
@ -177,7 +179,7 @@ nil ; 逻辑假,或者空列表
|
||||
|
||||
;; Dog-p,make-dog,以及 dog-name都是由defstruct创建的!
|
||||
|
||||
;;; 点对单元
|
||||
;;; 点对单元(Pairs)
|
||||
;; `cons`可用于生成一个点对单元, 利用`car`以及`cdr`将分别得到第一个和第二个元素
|
||||
(cons 'SUBJECT 'VERB) ; => '(SUBJECT . VERB)
|
||||
(car (cons 'SUBJECT 'VERB)) ; => SUBJECT
|
||||
@ -185,7 +187,7 @@ nil ; 逻辑假,或者空列表
|
||||
|
||||
;;; 列表
|
||||
|
||||
;; 所有列表都是由点对单元构成、并以'nil'(或者'())结尾的一种被称为“链表”的数据结构
|
||||
;; 所有列表都是由点对单元构成的“链表”。它以'nil'(或者'())作为列表的最后一个元素。
|
||||
(cons 1 (cons 2 (cons 3 nil))) ; => '(1 2 3)
|
||||
;; `list`是一个生成列表的便利途径
|
||||
(list 1 2 3) ; => '(1 2 3)
|
||||
@ -274,7 +276,7 @@ nil ; 逻辑假,或者空列表
|
||||
|
||||
;; 然而,你可能想使用一个更好的数据结构,而并非一个链表
|
||||
|
||||
;;; 在Common Lisp中,你也可以使用“字典”的概念——哈希表
|
||||
;;; 在Common Lisp中,“字典”和哈希表的实现是一样的。
|
||||
|
||||
;; 创建一个哈希表
|
||||
(defparameter *m* (make-hash-table))
|
||||
@ -285,7 +287,7 @@ nil ; 逻辑假,或者空列表
|
||||
;; (通过键)检索对应的值
|
||||
(gethash 'a *m*) ; => 1, t
|
||||
|
||||
;; 注意此处有一细节:Common Lisp的`gethash`往往会返回两个值。
|
||||
;; 注意此处有一细节:Common Lisp往往返回多个值。`gethash`返回的两个值是t,代表找到了这个元素;返回nil表示没有找到这个元素。
|
||||
;;(译者注:返回的第一个值表示给定的键所对应的值或者nil;)
|
||||
;;(第二个是一个布尔值,表示在哈希表中是否存在这个给定的键)
|
||||
;; 例如,如果可以找到给定的键所对应的值,则返回一个t,否则返回nil
|
||||
@ -370,7 +372,7 @@ nil ; 逻辑假,或者空列表
|
||||
; => Hello, Mr Jim, from the alpacas you met last summer
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; 4. 等价性
|
||||
;; 4. 等式
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Common Lisp具有一个十分复杂的用于判断等价的系统,下面只是其中一部分的例子
|
||||
@ -381,9 +383,11 @@ nil ; 逻辑假,或者空列表
|
||||
|
||||
;; 若要比较对象的类型,则使用`eql`
|
||||
;;(译者注:抱歉,翻译水平实在有限,下面是我个人的补充说明)
|
||||
;;(`eql`在二者`eq`等价,或者同为数字与字符下相同的类型)
|
||||
;;(`eq` 返回真,如果对象的内存地址相等)
|
||||
;;(`eql` 返回真,如果两个对象内存地址相等,或者对象的类型相同,并且值相等)
|
||||
;;(例如同为整形数或浮点数,并且他们的值相等时,二者`eql`等价)
|
||||
;; (想要弄清`eql`,其实有必要先了解`eq`)
|
||||
;;(想要弄清`eql`,其实有必要先了解`eq`)
|
||||
;;([可以参考](http://stackoverflow.com/questions/547436/whats-the-difference-between-eq-eql-equal-and-equalp-in-common-lisp))
|
||||
;;(可以去CLHS上分别查看两者的文档)
|
||||
;;(另外,《实用Common Lisp编程》的4.8节也提到了两者的区别)
|
||||
(eql 3 3) ; => t
|
||||
@ -400,12 +404,12 @@ nil ; 逻辑假,或者空列表
|
||||
|
||||
;;; 条件判断语句
|
||||
|
||||
(if t ; “测试”,即判断语句
|
||||
"this is true" ; “下一步”,即判断条件为真时求值的表达式
|
||||
"this is false") ; “否则”,即判断条件为假时求值的表达式
|
||||
(if t ; “test”,即判断语句
|
||||
"this is true" ; “then”,即判断条件为真时求值的表达式
|
||||
"this is false") ; “else”,即判断条件为假时求值的表达式
|
||||
; => "this is true"
|
||||
|
||||
;; 在“测试”(判断)语句中,所有非nil或者非()的值都被视为真值
|
||||
;; 在“test”(判断)语句中,所有非nil或者非()的值都被视为真值
|
||||
(member 'Groucho '(Harpo Groucho Zeppo)) ; => '(GROUCHO ZEPPO)
|
||||
(if (member 'Groucho '(Harpo Groucho Zeppo))
|
||||
'yep
|
||||
@ -450,7 +454,7 @@ nil ; 逻辑假,或者空列表
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; 6. 变异
|
||||
;; 6. 可变性
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; 使用`setf`可以对一个已经存在的变量进行赋值;
|
||||
@ -461,15 +465,13 @@ nil ; 逻辑假,或者空列表
|
||||
; => 2
|
||||
|
||||
|
||||
;; 所谓好的Lisp编码风格就是为了减少破坏性函数的使用,防止副作用的发生。
|
||||
;;(译者注:很惭愧,确实不明白原作者的“变异”到底指的是什么特性)
|
||||
;;(我猜测应该是和词法变量、闭包等特性有关,还望高人指点、修正与完善)
|
||||
;; 所谓好的Lisp编码风格就是为了减少使用破坏性函数,防止发生副作用。
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; 7. 类与对象
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; 我们就不写什么有关动物的类了,下面给出的是一个很“人文主义”的类
|
||||
;; 我们就不写什么有关动物的类了,下面给出的人力车的类
|
||||
|
||||
(defclass human-powered-conveyance ()
|
||||
((velocity
|
||||
@ -481,7 +483,7 @@ nil ; 逻辑假,或者空列表
|
||||
(:documentation "A human powered conveyance"))
|
||||
|
||||
;; `defclass`,后面接类名,以及超类列表
|
||||
;; 再接着是槽的列表(槽有点像Java里的字段),最后是一些可选的特性
|
||||
;; 再接着是槽的列表(槽有点像Java里的成员变量),最后是一些可选的特性
|
||||
;; 例如文档说明“:documentation”
|
||||
|
||||
;; 如果超类列表为空,则默认该类继承于“standard-object”类(standard-object又是T的子类)
|
||||
@ -545,8 +547,7 @@ nil ; 逻辑假,或者空列表
|
||||
;; 假设我们已经知道了效率值(“efficiency value”)和船桨数大概呈对数关系;
|
||||
;; 那么效率值的定义应当在构造器/初始化过程中就被完成。
|
||||
|
||||
;; 下面是一个如何初始化实例的例子:
|
||||
;; 构造它:
|
||||
;; 下面是一个Common Lisp构造实例时初始化实例的例子:
|
||||
|
||||
(defmethod initialize-instance :after ((object canoe) &rest args)
|
||||
(setf (average-efficiency object) (log (1+ (number-of-rowers object)))))
|
||||
@ -564,7 +565,7 @@ nil ; 逻辑假,或者空列表
|
||||
;; 宏可以让你扩展语法
|
||||
|
||||
;; 例如,Common Lisp并没有自带WHILE循环——所以让我们自己来为他添加一个;
|
||||
;; 如果按照“拼装者”的直觉来看,我们会这样写:
|
||||
;; 如果按照汇编程序的直觉来看,我们会这样写:
|
||||
|
||||
(defmacro while (condition &body body)
|
||||
"While `condition` is true, `body` is executed.
|
||||
|
Loading…
Reference in New Issue
Block a user