Я думаю, что проблема заключается в принтере lisp, реализация показывает нам одно и то же для обеих вещей, в то время как внутренне кажется, что на самом деле это список против функции.
Обычный и сбивающий с толку паттерн показывает:
<i>[hao@wendy:~]$ ecl
;;; Loading "/nix/store/j48bf40ssnzgil3qmdc759y0navk079d-ecl-readline/lib/init.lsp"
n;;; Loading "/nix/store/j48bf40ssnzgil3qmdc759y0navk079d-ecl-readline/lib/ecl-readline.fas"
ix-;;; Loading "/nix/store/j48bf40ssnzgil3qmdc759y0navk079d-ecl-readline/lib/ecl-completions.fas"
sECL (Embeddable Common-Lisp) 16.1.3 (git:UNKNOWN)
Copyright (C) 1984 Taiichi Yuasa and Masami Hagiya
Copyright (C) 1993 Giuseppe Attardi
Copyright (C) 2000 Juan J. Garcia-Ripoll
Copyright (C) 2016 Daniel Kochmanski
ECL is free software, and you are welcome to redistribute it
under certain conditions; see file 'Copyright' for details.
Type :h for Help.
Top level in: #<process TOP-LEVEL>.
h+CL-USER[1]> (macroexpand '(lambda (a) (+a 12)))
#'(LAMBDA (A) (+A 12))
T
+CL-USER[2]> (equal (macroexpand '(lambda (a) (+ a 12))) '(lambda (a) (+ a 12)))
NIL
+CL-USER[3]> (map 'list #'type-of (list (macroexpand '(lambda (a) (+ a 12))) '(lambda (a) (+ a 12))))
(CONS CONS)
+CL-USER[4]> (map 'list #'functionp (list (macroexpand '(lambda (a) (+ a 12))) '(lambda (a) (+ a 12))))
(NIL NIL)
+CL-USER[5]> (map 'list #'car (list (macroexpand '(lambda (a) (+ a 12))) '(lambda (a) (+ a 12))))
#'LAMBDA
И вроде разница только в hashquote
?
+CL-USER[8]> (ignore-errors (list *print-escape* *print-readably* *print-case* *print-circle* *print-level* *print-length* *print-pretty*))
(T NIL :UPCASE NIL NIL NIL T)
+CL-USER[9]> (let ((*print-readably* t)) (list (macroexpand '(lambda (a) (+ a 12))) '(lambda (a) (+ a 12)))))
(#'(LAMBDA (A) (+ A 12)) (LAMBDA (A) (+ A 12)))
;;; Warning: Ignoring an unmatched right parenthesis.
+CL-USER[10]> (setq *print-pretty* nil)
NIL
+CL-USER[11]> (setq the-funs (list (macroexpand '(lambda (a) (+ a 12))) '(lambda (a) (+ a 12))))
(#'(LAMBDA (A) (+ A 12)) (LAMBDA (A) (+ A 12)))
+CL-USER[12]> *print-pretty*
NIL
Я пытался заставить принтер явно отображать (function (lambda ...))
часть определения [22], но я не могу вспомнить, когда в последний раз делал то же самое, пытаясь выяснить, почему тонкое проявление возникло именно тогда, когда начинало завоевывать доверие к lisp
+CL-USER[21]> (type-of (car the-funs)))
CONS
;;; Warning: Ignoring an unmatched right parenthesis.
+CL-USER[22]> (car (car the-funs))
FUNCTION
На самом деле мы видим список / минусов (ниже) и функцию (вверху)
+CL-USER[23]> (values #1=(cadr the-funs) (type-of #1#))
(LAMBDA (A) (+ A 12))
CONS
И, возможно, разница не только в визуальном напечатанном символе; Вот SBCL:
<i>[hao@wendy:~]$ sbcl
This is SBCL 2.0.0.nixos, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (setq fs (list (macroexpand '(lambda (x) (1+ x))) '(lambda (x) (1+ x))))
; in: SETQ FS
; (SETQ FS (LIST (MACROEXPAND '(LAMBDA # #)) '(LAMBDA (X) (1+ X))))
;
; caught WARNING:
; undefined variable: COMMON-LISP-USER::FS
;
; compilation unit finished
; Undefined variable:
; FS
; caught 1 WARNING condition
(#'(LAMBDA (X) (1+ X)) (LAMBDA (X) (1+ X)))
* (let (*print-pretty*) (print (lambda (x) (1+ x))))
#<FUNCTION (LAMBDA (X)) {52B1CABB}>
#<FUNCTION (LAMBDA (X)) {52B1CABB}>
* (let (*print-pretty*) (print ' (lambda (x) (1+ x))))
(LAMBDA (X) (1+ X))
(LAMBDA (X) (1+ X))
Цитата показана здесь более подробно
#<FUNCTION (LAMBDA (X)) {52B1CABB}>
(LAMBDA (X) (1+ X))
Дерево и типы в чем-то похожи на то, что сказано в ECL.
* (mapcar #'functionp fs)
(NIL NIL)
* (mapcar #'type-of fs)
(CONS CONS)
* (mapcar #'car fs)
#'LAMBDA
* (values (car (car fs)) (car (cdr fs)))
FUNCTION
(LAMBDA (X) (1+ X))
Наконец, (не предпринимайте) случайное блуждание по дереву через лес подтверждает, что мы можем пройтись по списку, но функция просто закрыта?
* (defun walk-tree (fun tree)
(subst-if t
(constantly nil)
tree
:key fun))
WALK-TREE
* (walk-tree 'print (lambda (x) (1+ x)))
#<FUNCTION (LAMBDA (X)) {52B1CD5B}>
#<FUNCTION (LAMBDA (X)) {52B1CD5B}>
* (walk-tree 'print '(lambda (x) (1+ x))))
(LAMBDA (X) (1+ X))
LAMBDA
((X) (1+ X))
(X)
X
NIL
((1+ X))
(1+ X)
1+
(X)
X
NIL
NIL
(LAMBDA (X) (1+ X))
* (defun walk-tree-atoms (fun tree)
(tree-equal tree tree
:test (lambda (element-1 element-2)
(declare (ignore element-2))
(funcall fun element-1)
t)))
WALK-TREE-ATOMS
* (walk-tree-atoms 'print (lambda (x) (1+ x)))
#<FUNCTION (LAMBDA (X)) {52B1CF9B}>
T
* (walk-tree-atoms 'print '(lambda (x) (1+ x)))
LAMBDA
X
NIL
1+
X
NIL
NIL
T
* (quit)
<i>[hao@wendy:~]$
Функции ходьбы были взяты из LispTips, который, к сожалению, кажется, удален. У меня только что вспомнилось, когда я прочитал это, вы все еще можете посмотреть архив здесь: https://web.archive.org/web/20191204131626/https://lisptips.com/post/43404489000/the-tree-walkers-of-cl
Вы также можете просмотреть весь сеанс, я вставил его в суть: https://gist.github.com/LaloHao/fd6499b68cc98cf440aad6447ebd9b89
person
Eduardo V.
schedule
11.10.2020