我在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代码中。感谢
答案 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#))