

このようなコードを作成しましたが、結果は普通なリストになっていませんでした。

[code]

    (defun ins (x f s)
      (cons
       (append f (cons x s))
       (if (null s)
           nil
         (ins x
              (reverse (cons (car s) (reverse f)))
              (cdr s)))))
    
[/code]

実行結果：

[code]

    (ins 4 nil '(1 2 3))
    ((4 1 . #1=(2 . #2=(3))) (1 4 . #1#) (1 2 4 . #2#) (1 2 3 4))
    
[/code]

同じコードをemacsで実行した場合、問題がなかったです。

[code]

    (ins 4 nil '(1 2 3))
    ((4 1 2 3) (1 4 2 3) (1 2 4 3) (1 2 3 4))
    
[/code]

xyzzyでemacsと同じ結果になれないでしょうか。


CC BY-SA 4.0
2020-06-06T03:51:14.463
67348
2020-06-07T02:31:09.103
2020-06-06T04:16:24.150
40507
40507
question
emacs common-lisp lisp xyzzy
xyzzyで((4 1 . #1=(2 . #2=(3))) (1 4 . #1#) (1 2 4 . #2#) (1 2 3 4))は普通のリストで表示されない


`#1=` `#1#` というのはCommon Lisp系Lispでは同じデータを参照していることを示す表示です。  
xyzzyはCommon Lispに六割程度準拠とのことですが、Common Lispであれば、 `*print-circle*` を `nil`
に設定することで、共有構造の表示を無効にできます。

[code]

    (setq *print-circle* nil)
    
    (ins 4 nil '(1 2 3))
    → ((4 1 2 3) (1 4 2 3) (1 2 4 3) (1 2 3 4))
    
[/code]

しかし、上記をxyzzyで試したところ、この設定は有効にならないようです(バグ?)

今回の場合は、同じセルデータを共有していることが明示されているだけですので、`ins` が出力するデータの内容については変わりありません。

[code]

    (equal '((4 1 . #1=(2 . #2=(3))) (1 4 . #1#) (1 2 4 . #2#) (1 2 3 4))
           '((4 1 2 3) (1 4 2 3) (1 2 4 3) (1 2 3 4)))
    → t
    
[/code]

なお発想を転換して、構造を共有しないことにすれば(使い回しではなく毎度新規に作成する)、当然ながら共有構造の表示はされなくなります。

[code]

    (defun ins (x f s)
      (cons
       (append (copy-tree f) (cons x (copy-tree s)))
       (if (null s)
           nil
           (ins x
                (reverse (cons (car s) (reverse f)))
                (cdr s)))))
    
[/code]

[code]

    (ins 4 '((a) (b) (c)) '(1 2 3 (4)))
    → (((a) (b) (c) 4 1 2 3 (4))
       ((a) (b) (c) 1 4 2 3 (4))
       ((a) (b) (c) 1 2 4 3 (4))
       ((a) (b) (c) 1 2 3 4 (4))
       ((a) (b) (c) 1 2 3 (4) 4))
    
[/code]

上記では、`copy-tree`で、リスト`f`と`s`をディープコピーしています。


CC BY-SA 4.0
2020-06-06T09:32:55.810
67360
2020-06-07T02:31:09.103
2020-06-07T02:31:09.103
3510
3510
67348
answer