Common-Lisp教程(2)

前言

在lisp中有这许多迷人的特性,要弄清他们还真的不是很容易。我都不确定自己到最后可不可以真正的弄清楚。所以暂时将最简单和浅显的内容整理出来。

函数

函数的定义

(defun [函数名] ()[形参表]
“函数说明”
()[函数体])

这有几点要说明。首先这里面对形参表是指它前面一个括号里面的列表(list),当然也可以为空形参有多种形式一会介绍。函数说明可以不写,但是出于规范,我还是建议你写上函数的说明文档,函数说明可以通过某种方法得到。函数体可以使是一个合法的S-表达式。当函数被调用的时候。lisp将对这表达式求值并返回。
实例:

1
2
3
4
(defun add-two (x)
"add two to x"
(+ x 2))
;; (add-two 1) => 3

函数的形参

&key关键字形参

关键字形参使用&key作为关键字。默认的在&key后都视为关键字实参。与正常参数的不同关键字形参在赋实参时,需要像字典一样进行赋值。

1
2
3
4
(defun say-love (&key he her (say nil say-p))
"a funcation to make he say love to her"
'(he (if say-p (if say 'is 'not) 'not) say love to her))
;; (say-love :he banana :her hyacinth :say t)

我们可以看到在这里可以对关键字形参设置一个默认值,如果没有传值的情况下,该变量就会是这个值。而也可以使用一个x-p来接受是否传了这个值。正如上面的代码一样如果传了值say-p就是t,没有传的情况下就是nil。

在lisp中 t 表示逻辑真。 nil 表示逻辑假。

&optional 可选形参

可选形参表示参数是可选性的,如果不传值lisp并不会向你报错。当然你可以给他们附一个缺省值,默认情况下会是nil。

&rest 可变长参数

在编程的过程中,我们可能有不确定参数个数的情况。关于这个关键字。官方有这样的解释:

如果我们在函数的形参列表里的最后一个变量前,插入 &rest 符号,那么当这个函数被调用时,这个变量会被设成一个带有剩余参数的列表
以下是一个实现了funcall的例子。

1
2
(defun our-funcall (fn &rest args)
(apply fn args))

定义匿名函数

相信使用过其他语言的匿名函数对非常熟悉了,他在闭包中有很大的作用。这里匿名函数使用关键字lambda。这里的形式和函数的定义相似,就是把defun改成lambda不加函数说明就好了。其他是一样的。匿名函数没有那么多的参数列表类型。这正好与匿名函数的应用场景有关。
那么如何得到匿名函数呢?有一个语法糖。使用#'即可。如下:

1
(remove-if-not #'(lambda (x) (= (mod x 2))))

写在最后

我快疯了。我看了两个教程。发现两个教程的风格,完全不一样。一个是《实用Common Lisp编程》这个注重实践。不像一般教课书,一板一眼。一开始在我还没有了解语言的全部基本语法的情况下,带我写了一个简单的数据库。实用很多实用的函数还要宏的概念。让你你开始就看到了lisp的实力。
但是这本书不适合喜欢节奏的没有时间的宝宝们。如果你有热情,你还有时间可以一周内学完这本书的实例的话。我建议你使用这本书。
但是如果你没有时间,喜欢有章节的学习。忘了的时候还可以查询的话。我推荐你官方教程的翻译。传送门这个可能翻墙小伙伴们,学习科学上网吧。
看完这个教程你可能踌躇满志,想用lisp写点什么,突然不知道它可以写点什么。这时《使用Common Lisp编程》就成了最佳的选择。书中有进行垃圾处理的程序和一个音乐管理器。这都是不错很酷的尝试。
我教程的更新速度将更加慢了。因为我已经为你找到了,更好的学习路线。如果有机会我将,在以后的文章中写自己用Common Lisp做的有趣的事。
那个时候来到了。一定很快乐吧:)

我将一直的迷惑与无知,我是黄油香蕉君,再见。

给作者买杯咖啡吧。喵~