今天有人问到我Ansi Common Lisp里关于macro的一个函数。书里面在讲解macro的实现时以一个简单的macro为例子:
(defmacro nil! (x) (list 'setf x nil))
这段代码定义了一个叫nil!的macro。而为了实现这个macro定义后会有一个对应的函数来把使用nil!的代码转换成lisp代码。这个函数的定义是:
(lambda (expr) (apply #'(lambda (x) (list 'setf x nil)) (cdr expr)))
如果我们把(nil! a)这样的表达式丢给上面的函数应该得到(setf a nil)。而此人的问题是他以为apply这个函数的作用类似于将(apply func '(a b c d))转换成(func a b c d)。事实上不是这样的。Common Lisp the Language里有明确的例子:
(apply 'cons '((+ 2 3) 4)) =>
((+ 2 3) . 4) not (5 . 4)
我这儿再举一个例子:
(defun samething (x) x) (setf a 'b) (setf b 'c) (apply #'samething '(a)) => A
February 23rd, 2008 · Tags lisp | No Comments »
很快就读完了这本书的前三章,因为这三章并不算太难。有一点编程基础的人应该很容易就pass了。不过有第三章两个地方还是想做下笔记的:
List types 和 Tuple types
书里把两个放在一页说明,这样就让读者有了一个很好的比较。总得来说: List的元素只能是同一个类型(type)而Tuple的元素可以是不同的类型。这就造成了不同长度(包含元素的个数)的List可以被当成是同一个类型(如[1, 2, 3]与[3, 4]的类型都是[Int]),而不同长度的Tuple则一定是不同的类型。这在Haskell里是相当重要的,因为数据的类型是要预先计算的,所以List可以Lazy(因为类型不依赖于长度)但Tuple不可以Lazy。所以只有类似与[1..]的写法,但没有(1, …)。
Integral class和Fractional class
Integral class的除法是用 `div`而Fractional class(包括Float)是用/。看来Haskell的类型系统是很严格的
February 13th, 2008 · Tags bk:pih, haskell | No Comments »
拿到这本书的第一感觉就是:真薄!序言目录附录什么的全部加起来不超过170页。让人想到那本经典的The C Programming Language, Second Edition。不过C语言可是比Haskell简洁的多呀。
February 13th, 2008 · Tags bk:pih | No Comments »
Welcome to WordPress. This is your first post. Edit or delete it, then start blogging! Wow!
February 11th, 2008 · Tags Uncategorized | 1 Comment »