PraticalCommonLisp第三章笔记(2)

1.
C: void foo(){ bar1(); bar2(); }
lisp: (defun foo()
    (函数体))

因此很自然地在“函数体”部分填入bar1, bar2

(defun bar1() (format t "bar1"))
(defun bar2() (format t "bar2"))
(defun foo()
    ((bar1) (bar2)))

很不幸这是错误的,对于list语句而且,"()"中第一个标识符必须是一个函数,比如(+ 1 2)(除非你使用'(1 2 3)这种稍后求值形式,第一个标识符不需要是一个函数).

而这里((bar1) (bar2))第一个标识符是(bar1)求值后的结果,也就是format t "bar1"语句的结果,也就是nil,根本不是一个函数,因此是错误的。
我们应该把“函数体"前面的括号去掉.
as follows:
(defun foo()
    (bar1)
    (bar2))

lisp基本上模糊了代码和数据....

2. lisp版的字符串转数字函数parse-integer
(parse-integer "7") => 7
(parse-integer "x7") =>debug error..
(parse-integer "x7" :junk-allowed t)=>nil
(parse-integer "7x" :junk-allowed t) = 7
第一个字符开始是数字的,则会解析正确

最后两个式子中,:junk-allowed t 是plist的手法,junk-allowed(垃圾-允许)
空格不影响结果
(parse-inteer " 73x73 " :junk-allowed t) => 73

3.lisp的循环,使用loop宏来实现
(loop
  (format t "1~%")
  (format t "2~%"))

 拼命地打印
 1
 2
 1
 2
 ....

4. 使用了中文的括号,导致编译错误,找了半天:( ,恰好也说明我解决问题的能力不强,编译器明明告诉我,encoding problem,但是我看了下代码,觉得没有任何中文字符,应该不会出现错误,结果...

5. list in a box中的SLIME还是挺有用的,比如你想看看with-open-file macro是怎么使用的,你可以敲下"(with-open-file ",SLIME就在Emacs的下方列出了这个Macro的定义,可惜这个定义我还是有些看不懂 :( ,比如&rest是指什么意思?

6.read-line是读入字符,而read是读入lisp代码

7.到目前为止实现这个简易型db的代码,一个感觉,代码很ugly :)

(defvar *db* nil)

(defun add-record(cd) (push cd *db*))

(defun make-cd(title name rating ripped)
  (list :title title :name name :rating rating :ripped ripped))

(defun prompt-read(prompt)
  (format *query-io* "~a: " prompt)
   (force-output *query-io*)
   (read-line *query-io*))

(defun prompt-for-cd ()
  (make-cd
   (prompt-read "title")
   (prompt-read "name")
   (or (parse-integer (prompt-read "rating") :junk-allowed t) 0)
   (y-or-n-p "ripped [y/n] :")))

(defun add-cds ()
  (loop (add-record (prompt-for-cd))
     (if (not (y-or-n-p "Another: ")) (return))))

(defun save-db(filename)
  (with-open-file (myfile filename :direction :output :if-exist :supersede)
    (with-standard-io-syntax (print *db* myfile))))

(defun load-db(filename)
  (with-open-file (myfile filename)
    (with-standard-io-syntax (setf *db* (read myfile)))))



8.(remove-if-not #'evenp '(1 2 3 4))中,#'的意思是:The funny notation #' is shorthand for “Get me the function with the following name.” Without the #', Lisp would treat evenp as the name of a variable and look up the value of the variable, not the function.
那为什么用这么怪的名字呢?我想,撇号已经被拿来用来区分一个数据与代码,从而使有撇号的列表或者原子稍后求值,所以干脆就在撇号前加了个标识 :)

9.lisp有个地方的语法我觉得和lisp本身的语法有些自相矛盾,(defun foo (arg1 arg2) (+ 1 2)),这里foo后面的参数列表(arg1 arg2),如果按照lisp的语法,如果是数据的话应该是'(arg1 arg2),或者换另外一种方式来说,(arg1 arg2)中arg1是一个函数..

总结:
仔细阅读了第三章,然后又巨艰难地浏览第四章,最后又扫了接下来几张关于一些基本语法的章节。lisp总算入门了。但是依然无法运用它来写程序,接下来的计划是阅读例子的章节,这几个例子的章节就当作是实战,在实战中巩固学习lisp知识。

学到的教训:
    挑重要的看,人的精力是有限的,不要死看书,挑重点,不用一行一行的死读书,多运用资源和工具,这样才比较又效率。多思考,多动手,多比较(比如查阅其他书籍类似主题的内容进行比较)等等。






 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值