Lisp语法与(operator-integer-operator)格式混淆

时间:2018-11-26 08:15:52

标签: lisp common-lisp

我是Lisp的新手,对此LISP语法有疑问:

(defparameter *binary-operators*
  '((+ 1 +) (- 1 -) (* 2 *)
    (x 2 *) (/ 2 %) (^ 3 expt)))

据我了解,defparameter允许重新分配二进制运算符变量,但我对如何评估(+1 +),(-1-)...感到困惑。我在LISP中知道(+ 4 6)将导致(4 + 6)= 10,但是相同的逻辑将导致(1 + +),这没有意义。上面的语法代表什么?

2 个答案:

答案 0 :(得分:6)

在Common Lisp中,

(defparameter name initial-value)

(请参阅manual)引入了一个新的特殊(全局)变量name,该变量具有通过评估initial-value得到的新值。

因此,在上面的示例中,为特殊变量*binary-operators*分配了一个三元组列表,每个三元组由一个符号,一个数字和另一个符号组成。换句话说,它为变量分配了一些数据,而不是您想的那样,重新定义了语言的语法。

从列表中的值进行猜测,这似乎是一个分配了算术运算符列表的变量,每个算术运算符都具有优先级,并具有等效的Common Lisp运算符/函数。也许这是某些程序的一行,它在lisp s表达式中映射算术表达式,或类似的东西。

答案 1 :(得分:4)

lisp:数据和代码中使用列表和符号

这是代码为数据的应用程序之一。在Lisp中,符号和列表是数据。但是它们也用于编写程序:然后,这些符号将用于变量名函数名等。列表用于用Lisp语言编写表达式-这些列表称为 forms

在Lisp程序中

(+ 1 2)

是具有两个值的名为+的函数的函数调用。

'(+ 1 2)

(quote (+ 1 2))

然后是数据->符号+以及数字12的列表。

示例:前缀转换的前缀

您使用的表单定义了从表示数学函数的符号到权重以及它代表转换的实际Lisp函数的映射。

请参见Lispology: Infix to prefix

(defparameter *binary-operators*
  ;  operator  weight  Lisp function
  '((+         1       +)
    (-         1       -)
    (*         2       *)
    (x         2       *)
    (/         2       %)
    (^         3       expt)))

我们可以使用它将中缀数学表达式转换为前缀Lisp表达式(有关代码,请参见上面的链接文章):

CL-USER 52 > (infix-prefix '(2 * 3 ^ 4))
(* 2 (EXPT 3 4))

当我们更改该assoc列表时,转换将有所不同。让我们更改^运算符的权重:

CL-USER 53 > (defparameter *binary-operators*
               '((+ 1 +)
                 (- 1 -)
                 (* 2 *)
                 (x 2 *)
                 (/ 2 %)
                 (^ 1 expt)))     ; weight changed to 1
*BINARY-OPERATORS*

现在,我们可以从上面转换示例,并获得不同的Lisp形式:

CL-USER 54 > (infix-prefix '(2 * 3 ^ 4))
(EXPT (* 2 3) 4)

因此,*binary-operators*是数据,它推动了从中缀数学表达式到Lisp格式的转换。此处没有使用规则将规则硬编码到代码中,而是使用关联列表来保留映射。因此,我们可以通过更改关联列表来添加新的运算符,而无需更改实际代码。