Common Lisp:如何显示一个点?

Common Lisp: how to display a dot?

我想使用点 (.) 作为符号,例如 ab

我发现我可以通过引用和转义点来做到这一点。但是,当点显示在屏幕上时,它被竖线包围:

'\.
=> |.|

如何让点显示没有竖线?

更新:谢谢 jkiiski,使用 format 效果很好。这就是我这样做的原因:为了我自己的教育,我编写了一个函数来将列表表示法中的列表转换为点表示法中的等效列表。感谢您的帮助,现在效果很好:

(defun list-notation-to-dot-notation (lst)
    (cond ((atom lst) lst)
          ((null (cdr lst)) (list (list-notation-to-dot-notation (car lst)) '\. 'NIL))
          (t (list (list-notation-to-dot-notation (car lst)) '\. (list-notation-to-dot-notation (cdr lst))))))

(defun list-2-dot (lst)
    (format t "~a" (list-notation-to-dot-notation lst)))

(list-2-dot '(a))
=> (A . NIL)

(list-2-dot '(a b))
=> (A . (B . NIL))

(list-2-dot '((a) b))
=> ((A . NIL) . (B . NIL))

(list-2-dot '(a (b) c))
=> (A . ((B . NIL) . (C . NIL)))

(list-2-dot '(a b (c)))
=> (A . (B . ((C . NIL) . NIL)))

(list-2-dot '((a) (b) (c)))
=> ((A . NIL) . ((B . NIL) . ((C . NIL) . NIL)))

为了达到相同的结果,这是一种更简洁的方法:

(defun print-dot-notation (list &optional (stream *standard-output*))
  (if (atom list)
      (format stream "~s" list)
      (format stream "(~a . ~a)"
              (print-dot-notation (car list) nil)
              (print-dot-notation (cdr list) nil))))

(print-dot-notation '(a (b) c))
; (A . ((B . NIL) . (C . NIL)))

无需创建额外的列表或为点使用符号。

仅供参考,lisp 打印机总是将点 (.) 符号打印为 |.|,因为点与特殊的 lisp reader 定义规则相关联。除非它是像 foo.bar 这样的名称的一部分,否则 reader 将始终假定您指的是某种虚线列表。

我发现这是最简单的解决方案:

(defun list-notation-to-dot-notation (list)
  (cond ((atom list) (format t "~S" list))
        (t (format t "(")
           (list-notation-to-dot-notation (car list))
           (format t " . ")
           (list-notation-to-dot-notation (cdr list))
           (format t ")"))))

如 David S. Touretzky 教授所著的 Common Lisp:符号计算的简要介绍

假设您有一个函数 list-notation-to-dot-notation,您知道它将列表从列表表示法转换为点表示法,:

  • 打印列表 (car list)
  • car
  • 打印一个点 .
  • 并打印列表 (cdr list)
  • cdr

然后,您所要做的就是在 carcdr 上递归调用该函数,将它们转换为点符号,并在它们之间放置一个点。

就我个人而言,我觉得基本条件有点棘手。 因为你不能简单地写 (cond ((atom list)list)) ... 因为它不会正确打印原子(根本!),可能是由于事实上 return 值将传递给 format.