我最近开始学习Common Lisp,并且(只是为了好玩)决定重命名lambda宏。
我的尝试是这样的:
> (defmacro λ (args &body body) `(lambda ,args ,@body))
它本身似乎正确扩展:
> (macroexpand-1 '(λ (x) (* x x)))
(LAMBDA (X) (* X X))
但是当它嵌套在表达式中时,执行失败:
> ((λ (x) (* x x)) 2)
(Λ (X) (* X X)) is not a function name; try using a symbol instead
我可能错过了一些关于宏扩展的明显内容,但却无法找出它是什么。
也许你可以帮助我?
编辑: 它适用于lambda:
> ((lambda (x) (* x x)) 2)
4
编辑2: 使其运作的一种方法(如Rainer所建议):
> (set-macro-character #\λ (lambda (stream char) (quote lambda)))
(在Clozure CL中测试)
答案 0 :(得分:20)
在Common Lisp LAMBDA
中有两个不同的东西:一个宏和一个可以在LAMBDA表达式中使用的符号。
LAMBDA表达:
(function (lambda (x) (foo x)))
缩写为
#'(lambda (x) (foo x))
应用的lambda表达式也有效:
((lambda (x) (+ x x)) 4)
以上两种形式都是Common Lisp的核心语法的一部分。
在Common Lisp的定义后期,添加了一个名为LAMBDA
的宏。令人困惑,但有良好的意图。 ;-)记录为Macro LAMBDA。
(lambda (x) (+ x x))
扩展为
(function (lambda (x) (+ x x))
它使Common Lisp代码看起来更像Scheme代码,然后没有必要编写
(mapcar #'(lambda (x) (+ x x)) some-list)
使用LAMBDA
宏我们可以写
(mapcar (lambda (x) (+ x x)) some-list)
您的示例失败,因为
((my-lambda (x) (* x x)) 2)
无效的Common Lisp语法。
Common Lisp要求
(function args...)
((lambda (arglist ...) body) args...)
(macro-name forms...)
FUNCTION
,LET
,...
在Common Lisp中的special operators列表中定义正如您可以看到
的语法((macro-name forms...) forms...)
不是Common Lisp的一部分。
可以将字符λ
读为LAMBDA
:
(defun λ-reader (stream char)
(declare (ignore char stream))
'LAMBDA)
(set-macro-character #\λ #'λ-reader)
示例:
CL-USER 1 > ((λ (x) (* x x)) 3)
9
CL-USER 2 > '(λ (x) (* x x))
(LAMBDA (X) (* X X))
答案 1 :(得分:2)
您可能还认为LAMBDA是一个运算符,给定一个术语和一个自由变量列表,它返回一个函数。这个p.o.v.将LAMBDA从基本函数和基本宏的系列中取出 - 至少就解释器而言。
答案 2 :(得分:0)
(defun lambda-char (stream char)
"A lambda with only ONE arg _"
(declare (ignore char))
(let ((codes (read stream nil)))
`(lambda (_) ,codes)))
(set-macro-character #\λ #'lambda-char t)
λ(+ 1 2 _) ; => (lambda (_) (+ 1 2 _))
也许更简洁,只有一个_ _