为什么Common-Lisp Lambda表达式是有效的函数名? [英] Why is a Common-Lisp Lambda expression a valid function name?

查看:118
本文介绍了为什么Common-Lisp Lambda表达式是有效的函数名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,假设我要调用一些函数。如果我已使用defun定义了函数,则只需在列表的开头使用函数名称,后跟它的参数即可(在示例中,我将使用 =>来显示输入代码的输出进入CLisp REPL):

 (defun f(a)(lambda(b)(+ ab)))=> F 
(f 12)=> #<功能:LAMBDA(B)(+ A B)>

很简单。列表的第一个元素必须是函数,特殊运算符或宏的名称。除非,以下内容也有效:

 ((lambda(a)(+ a 12))1)=> 13 

快速的Google搜索表明LAMBDA既是符号又是宏。尝试扩展宏等级:

 (macroexpand’(lambda(a)(+ a 12)))=> #’(LAMBDA(A)(+ A 12))

这没有帮助。我无法区分宏LAMBDA和符号LAMBDA,而且我不清楚为什么可以使用lambda表达式作为函数名,但不能使用#'f,据我所知,应该以与#'(LAMBDA(A)(+ A 12))相同的方式对函数F求值,但是:

 (#'f 12)=> ***-EVAL:#’F不是函数名;尝试使用符号来代替

LAMBDA是第一个元素的特殊设置,否则该规则很难设置计算表达式必须的名称必须是某些操作的名称,还是我误解了一些更一致的规则集?

解决方案

Lambda表达式和函数名称



一个 lambda表达式不是函数名称。 Common Lisp中的功能名称被定义为符号(setf符号) lambda表达式基本上是用于描述匿名函数的内置语法。



请注意,Lambda表达式本身在Common Lisp中没有意义。 。它们仅以 lambda形式(见下文)出现,并在带有特殊运算符 function 的形式内出现。



列表形式


LAMBDA a $ e $ b


否则是硬性规定的一个特殊例外,即被求值表达式的第一个元素必须是某个操作的名称,还是我误会了一些更一致的规则集?


Common Lisp规范定义只有四个基于列表的 forms form 是有效的Lisp代码段。




  • 特殊格式(该格式以特殊运算符开头)

  • 宏形式(表格以宏运算符开头)

  • 函数形式(表格以函数运算符开头)

  • lambda形式(该形式以lambda表达式开头)



请参见Common Lisp HyperSpec:视为表单



请注意,Common Lisp中没有机制可以扩展此范围。基于列表的表单只有这四种类型。人们可能会想到扩展:数组作为函数,CLOS对象作为函数,不同类型的函数,例如fexprs,变量等... Common Lisp语法都不支持基于列表的表单,并且没有可移植的机制来添加这些扩展。



LAMBDA



LAMBDA 在Common Lisp中有两个不同的用途:




  • 它是 lambda表达式的头部

  • 作为宏 LAMBDA 。这会将(lambda ....)扩展为(function(lambda ....))



在第一个语言定义CLtL1之后,将 LAMBDA 宏添加到Common Lisp。能够写(lambda(x)x)而不是(function(lambda(x)x))#'(lambda(x)x)。因此,它是特殊操作符形式的缩写,使代码看起来更简单,更像 Scheme


So let's say I want to call some function. If I've defined the function with a defun, I just use the name of the function at the beginning of a list followed by it's arguments like so (I will be using "=>" in examples to show the output of entering the code into the CLisp REPL):

(defun f (a) (lambda (b) (+ a b))) => F
(f 12) => #<FUNCTION :LAMBDA (B) (+ A B)>

Simple enough. The first element of the list must be the name of a function, special operator, or macro. Except, the following is also valid:

((lambda (a) (+ a 12)) 1) => 13

A quick google-search reveals that LAMBDA is both a symbol and a macro. Trying to expand the macro yeilds:

(macroexpand '(lambda (a) (+ a 12))) => #'(LAMBDA (A) (+ A 12))

This is not helpful. I have no way to differentiate between the macro LAMBDA and the symbol LAMBDA, and I'm totally unclear as to why I can use a lambda expression as a function-name but not, say, #'f, which, to my knowledge, should evaluate to a valid function-designator for the function F in the same way that #'(LAMBDA (A) (+ A 12)) does and yet:

(#'f 12) => *** - EVAL: #'F is not a function name; try using a symbol instead

Is LAMBDA a special exception to the otherwise hard-set rule that the first element of an evaluated expression must be the name of some operation, or is there some more consistent ruleset that I'm misunderstanding?

解决方案

Lambda expressions and function names

A lambda expression is not a function name. function names in Common Lisp are defined to be either symbols or (setf symbol). A lambda expression is basically built-in syntax to describe an anonymous function.

Note that lambda expressions on their own are not meaningful in Common Lisp. They are only appearing in a lambda form (see below) and inside a form with the special operator function.

Lists as Forms

Is LAMBDA a special exception to the otherwise hard-set rule that the first element of an evaluated expression must be the name of some operation, or is there some more consistent ruleset that I'm misunderstanding?

The Common Lisp specification defines that there are only four list-based forms. A form is a valid Lisp piece of code.

  • special forms (the form begins with a special operator)
  • macro forms (the form begins with a macro operator)
  • function forms (the form begins with a function operator)
  • lambda forms (the form begins with a lambda expression)

See the Common Lisp HyperSpec: Conses as Forms.

Note that there is no mechanism in Common Lisp to extend this. There are only these four types of list-based forms. One could think of extensions: arrays as functions, CLOS objects as functions, different types of functions like fexprs, variables, ... None of those are supported by Common Lisp syntax for list-based forms and there is no portable mechanism to add those.

LAMBDA

LAMBDA has two different purposes in Common Lisp:

  • it's the head of a lambda expression.
  • as a macro LAMBDA. This expands (lambda ....) into (function (lambda ....))

The macro LAMBDA was added to Common Lisp after the first language definition CLtL1 as a convenience to be able to write (lambda (x) x) instead of (function (lambda (x) x)) or #'(lambda (x) x). Thus it's an abbreviation for the function special operator form and makes code look a bit simpler and more Scheme-like.

这篇关于为什么Common-Lisp Lambda表达式是有效的函数名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆