Lisp.扩展Lisp

有两种方式来给Lisp添加新的操作符:函数和宏。在Lisp中,你定义的函数和内置的那些有一样的状态。如果你想要一个mapcar的变体,你可以自己定义一个,并像使用mapcar一样使用它。比如,如果你想要一个函数应用于1到10的变量后返回的一列值,你可以创建一个新的列表并将它传递给mapcar:

(mapcar fn
(do* ((x 1 (1+ x))
(result (list x) (push x result)))
((= x 10) (nreverse result))))

但是这种方法既丑陋又低效。你想定义一个新的映射函数map1-n,然后想下面这样调用它:

(map1-n fn 10)

定义函数相对来说是很直观的。宏提供了更加通用的,但是并不易懂的,定义新操作符的方法。宏是是写程序的程序。这种语句有广泛的蕴涵,探索它们是这本书的主要目的。


细心地使用宏可以得到令人惊奇的清晰和优雅的程序。这些宝石也不是免费得到的。最终宏将在这个世界最自然的东西,但是一开始要理解它会有些难度。部分原因是它们比函数更泛化,所以当写它们的时候需要想着更多的东西。但是宏难理解的主要原因是它们是外语。没有其它语言有像Lisp的宏这样的东西。这样,学习关于宏的东西就需要你忘记从其它语言中不经意间学到的概念。为什么数据结构应该是流畅且可变的,而程序不是?在Lisp中,程序就是数据,但是这种事实的蕴涵关系需要时间来深入理解。


如果需要一定的时间来适应宏,那也是非常值得的。今世是在迭代这样平常的使用,宏可以使得程序显著地变小和清晰。假设一个程序必须在某些代码上迭代a到b范围的x。内置的LIsp do 一本认为是更加泛化的情况。对于简单的迭代,它不会产生出最易读的代码:

(do ((x a (+ 1 x)))
((> x b))
(print x))

如果,假设我们能这样写:

(for (x a b)
(print x))

宏使得这样写成为可能。通过6行代码我们就能将for加入到语言中,就像它从一开始就在那里一样。随着章节的继续,写for仅仅是你可以用宏来做的事情的开始。


你没有被限制在通过函数和宏来扩展Lisp。如果你需要,你可以在Lisp上建立一整套语言,并且用这套语言写你的程序。Lisp是一个出色的编写编译器和解释器的语言,但是它

提供了另外一种定义新语言的方式,这种方式更加优雅,需要更少的工作:作为Lisp的变体定义的新语言。然后Lisp的部分可以在新语言中不经修改的出现,你只需要实现不同的部分。以这种方式实现的语言叫做嵌入式语言。


嵌入式语言是自下而上编程的自然结果。Common Lisp已经包含几个这样的语言。它们中最著名的是CLOS,在后面的章节中讨论。但是你也可以定义你自己的嵌入式语言。你可以让语言适应你的程序,可以最终看起来和Lisp很不同。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值