快速业务通道

探索JVM上的LISP - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-20
仅返回lambda的函数也是有可能的,经典教科书中的例程会这样写:

#|kawa:10|# (define (make-adder a) (lambda (b) (+ a b)))   #|kawa:11|# (make-adder 2)   #

上面的语句都做些什么事情呢?首先定义了一个名为make-adder函数,它带有一个参数a,返回一个匿名函数,该匿名函数要接收另外一个参数b。当调用发生时,匿名函数会计算a与b的和。

执行(make-adder 2)——或者通俗的说“给我一个函数,可以把2加到传给它的参数上”,REPL将显示一些代码,它实际上是把lambda过程作为一个字符串打印出来,要用这个函数你还可以这样写:

#|kawa:12|# (define add-3 (make-adder 3))   #|kawa:13|# (add-3 2)   5

此处最为重要的事情在于lambda作为一个闭包执行。把它“封装”起来,保持它被创建时对作用范围内变量的引用。(make-adder 3)调用后,作为返回结果的lambda保有a的值,当(add-3 2)执行时,它计算3+2的值,并返回预期的5。

探索JVM上的LISP(3)

时间:2011-01-27 infoq 译:张凯峰

宏(MACROS)

到目前为止所看到的特性都和我们在比较新的动态语言中发现的相类似,例如Ruby,它也允许你使用匿名块处理对象收集,正如我们在前面用lambda和map函数所做的一样。所以,现在让我们来转变一下方向,看看独属于Lisp的特性:宏(macros)。

Scheme和Common Lisp都有宏系统。人们在提到Lisp时总说它是“可编程的程序设计语言”,其实指得就是这个。有了宏,你实际上就可以和编译器建立关联,重新定义语言本身。此时Lisp统一的语法才真正开始挥效用,所有的事情都变得有趣起来。

举个简单的例子,我们可以看一下循环。在Scheme语言中,最初并没有定义循环,典型的对某集合进行迭代的方式是使用map或者递归函数调用。多亏有一个编译器小窍门——尾调用优化递归(tail-call optimizations recursion)——可以采用而不必担心会挤爆栈。下面将介绍一个非常灵活的do命令并应用它来执行一个循环,实现的程序如下:

(do ((i 0 (+ i 1)))    ((= i 5) #t)    (display "Print this "))

上面程序中定义了一个索引变量i,初始化为0,设置按照增量1迭代增长。当表达式(= i 5)的值为真时,循环中止,返回#t(它和Java中的布尔值true相当)。在循环里我们只是打印了一个字符串。

如果我们所需要做的只是一个简单的循环,上面这个例子就有很多冗余的公式化代码了。在很多情况下更可取的应当是简单直接的实现方式:

(dotimes 5 (display "Print this"))

多亏了宏(macros),才有可能适当地使用称为define-syntax函数,把关于dotimes的特殊语法添加进语言:

(define-syntax dotimes   (syntax-rules ()    ((dotimes count command) ; Pattern to match     (do ((i 0 (+ i 1)))   ; What it expands to       ((= i count) #t)       command))))

执行上述命令可以告诉系统,任何对dotimes的调用都要被特别对待。Scheme将用我们定义的语法规则匹配一个模式,并在将结果送到编译器之前将其展开。在这个例子中,模式是(dotimes count command),它被转换为标准的do循环。

在REPL中执行该语句,你会得到如下结果:

#|kawa:14|# (dotimes 5 (display "Print this ")) Print this Print this Print this Print this Print this #t

上述例子之后必然产生两个问题。第一,为什么我们需要使用宏(macro)?用一个常规的函数不能做这些事情么?答案是“不可以”。任何对函数的调用实际上在开始之前都会触发对它所有参数的求值操作,在上面的例子中就不会发生这种情况。比方说,你怎样处理(do-times 0 (format #t

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号