在Common Lisp中重命名lambda

iba*_*bab 11 macros lambda common-lisp

我最近开始学习Common Lisp,并且(只是为了好玩)决定重命名lambda宏.

我的尝试是这样的:

> (defmacro ? (args &body body) `(lambda ,args ,@body))
Run Code Online (Sandbox Code Playgroud)

它本身似乎正确扩展:

> (macroexpand-1 '(? (x) (* x x)))
(LAMBDA (X) (* X X))
Run Code Online (Sandbox Code Playgroud)

但是当它嵌套在表达式中时,执行失败:

> ((? (x) (* x x)) 2)
(? (X) (* X X)) is not a function name; try using a symbol instead
Run Code Online (Sandbox Code Playgroud)

我可能错过了一些关于宏扩展的明显信息,但却无法弄清楚它是什么.

也许你可以帮帮我吗?

编辑:它适用于lambda:

> ((lambda (x) (* x x)) 2)
4
Run Code Online (Sandbox Code Playgroud)

编辑2:使其工作的一种方法(由Rainer建议):

> (set-macro-character #\? (lambda (stream char) (quote lambda)))
Run Code Online (Sandbox Code Playgroud)

(在Clozure CL中测试)

Rai*_*wig 20

在Common Lisp中LAMBDA有两个不同的东西:宏和可以在LAMBDA表达式中使用的符号.

LAMBDA表达式:

(function (lambda (x) (foo x)))
Run Code Online (Sandbox Code Playgroud)

写得更短

#'(lambda (x) (foo x))
Run Code Online (Sandbox Code Playgroud)

应用的lambda表达式也有效:

((lambda (x) (+ x x)) 4)
Run Code Online (Sandbox Code Playgroud)

以上两种形式都是Common Lisp的核心语法的一部分.

在Common Lisp的定义的后期,LAMBDA添加了一个被调用的宏.令人困惑,但有良好的意图.;-)记录为Macro LAMBDA.

(lambda (x) (+ x x))
Run Code Online (Sandbox Code Playgroud)

扩展到

(function (lambda (x) (+ x x))
Run Code Online (Sandbox Code Playgroud)

它使Common Lisp代码看起来更像Scheme代码,然后没有必要编写

(mapcar #'(lambda (x) (+ x x)) some-list)
Run Code Online (Sandbox Code Playgroud)

LAMBDA宏我们可以写

(mapcar (lambda (x) (+ x x)) some-list)
Run Code Online (Sandbox Code Playgroud)

您的示例失败,因为

((my-lambda (x) (* x x)) 2)
Run Code Online (Sandbox Code Playgroud)

是无效的Common Lisp语法.

Common Lisp也希望如此

  • 一个数据对象
  • 一个变量
  • 表单中的函数调用 (function args...)
  • 表单中的函数调用 ((lambda (arglist ...) body) args...)
  • 像宏的形式 (macro-name forms...)
  • 使用内置的特殊运营商之一像一种特殊形式FUNCTION,LET......在列表中定义的特殊运营商 Common Lisp中

正如你可以看到的语法

((macro-name forms...) forms...)
Run Code Online (Sandbox Code Playgroud)

不是Common Lisp的一部分.

可以将角色读?LAMBDA:

(defun ?-reader (stream char)
  (declare (ignore char stream))
  'LAMBDA)

(set-macro-character #\? #'?-reader)
Run Code Online (Sandbox Code Playgroud)

例:

CL-USER 1 > ((? (x) (* x x)) 3)
9

CL-USER 2 > '(? (x) (* x x))
(LAMBDA (X) (* X X))
Run Code Online (Sandbox Code Playgroud)

  • @qrl:((λ(x)...)4)语法可以在CL实现中使用支持该字符的读宏.Lisp读者必须将λ扩展为LAMBDA. (3认同)
  • 它不是`lambda'扩展中的`函数'是一个问题,它是使用`lambda`的函数应用程序的硬连线行为.所以在你的解释中我会改变:"应用的lambda表达式也有效"到"应用的`lambda`表达式也是有效的(仅适用于`lambda`而不适用于扩展到它的宏)". (2认同)