常见的lisp中的奇怪语法

时间:2013-11-25 19:34:22

标签: common-lisp

我在google搜索时找到了这个lisp函数

(defun filter (lst items-to-filter)
   (cond ((null lst) nil)
         ((member (car lst) items-to-filter) #1=(filter (cdr lst) items-to-filter))
         (t (cons (car lst) #1#))))

这只是设置差异,但这是我第一次看到#1 =和#1#,语法。我想通过查看代码我明白它意味着什么,但我不太确定。我认为#1 =用于标记表达式,以便以后在需要时不再重新键入它,可以通过#index#引用它,在这种情况下index = 1。我想知道是否有人可以对此有所了解。这些构造的名称是什么,如果有它们的引用,以及它们是否被广泛用于现代的lisp代码中。感谢

1 个答案:

答案 0 :(得分:6)

在书面源代码中查看它是非常不寻常的。大多数时候你会在数据中看到它。它用于在s表达式中创建或打印共享数据项。这样您还可以读取或打印循环s表达式。

您可以使用它来更轻松地创建重复的代码,但通常会为此编写函数或宏。函数具有节省代码空间的优点 - 除非它们是内联的。

CL-USER 3 > (pprint '(defun filter (lst items-to-filter)
                       (cond ((null lst) nil)
                             ((member (car lst) items-to-filter)
                              #1=(filter (cdr lst) items-to-filter))
                             (t (cons (car lst) #1#)))))

(DEFUN FILTER (LST ITEMS-TO-FILTER)
  (COND ((NULL LST) NIL)
        ((MEMBER (CAR LST) ITEMS-TO-FILTER)
         (FILTER (CDR LST) ITEMS-TO-FILTER))
        (T
         (CONS (CAR LST) (FILTER (CDR LST) ITEMS-TO-FILTER)))))

如上所示,打印机不会以这种方式打印。这是为什么? 有一个全局变量*print-circle*来控制它。对于上面的示例,它设置为NIL。让我们改变一下:

CL-USER 4 > (setf *print-circle* t)
T

CL-USER 5 > (pprint '(defun filter (lst items-to-filter)
                       (cond ((null lst) nil)
                             ((member (car lst) items-to-filter)
                              #1=(filter (cdr lst) items-to-filter))
                             (t (cons (car lst) #1#)))))

(DEFUN FILTER (LST ITEMS-TO-FILTER)
  (COND ((NULL LST) NIL)
        ((MEMBER (CAR LST) ITEMS-TO-FILTER)
         #1=(FILTER (CDR LST) ITEMS-TO-FILTER))
        (T
         (CONS (CAR LST) #1#))))

因此,这表明可以在Common Lisp中读取和打印这样的s表达式

在计算代码中共享一些源代码数据结构更为常见:

CL-USER 22 > (defmacro add-1-2-3 (n) `(,n 1 2 3))
ADD-1-2-3

CL-USER 23 > (walker:walk-form '(+ (add-1-2-3 4) (add-1-2-3 5)))
(+ (4 . #1=(1 2 3)) (5 . #1#))