在LISP Lambda函数中使用参数作为操作符的问题(基于《The Roots of Lisp》)
解决Common Lisp中变量作为Lambda操作符调用的问题
问题核心在于Common Lisp的双命名空间设计——它将变量与函数的命名空间完全分离,而Paul Graham《The Roots of Lisp》基于的原始LISP是单命名空间,两者求值规则存在差异。
原代码里的f是变量,存储了你传入的lambda函数对象,但当你写(f '(b c))时,Common Lisp会去函数命名空间查找名为f的函数,而非从变量空间读取f的值,因此报错“函数F未定义”。
两种修复方案:
用
funcall调用变量中的函数对象
这是Common Lisp的标准写法,funcall会专门从变量空间取函数对象并执行:((lambda (f) (funcall f '(b c))) #'(lambda (x) (cons 'a x)))其中
#'是function的简写,用于将lambda表达式转换为标准函数对象(部分CL实现允许省略,但建议遵循标准写法)。切换到单命名空间Lisp方言(可选)
如果想完全贴合《The Roots of Lisp》的环境,可以使用Scheme这类单命名空间Lisp,它的求值规则和原始LISP一致,你的原代码可以直接运行。
至于简化后的代码能正常运行,是因为此时lambda表达式直接处于函数调用的操作符位置,Common Lisp会自动将其识别为函数对象处理,无需额外转换。
内容的提问来源于stack exchange,提问作者blex-max
相关产品推荐
相关产品推荐

