@yukiya68k

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Emacs Lisp の nconc の使い方

解決したいこと

Emacs Lisp でリストの連結にnconcを使い始めたのですが、初期値がnilだと更新されません。

(setq x '(1))
->(1)
(nconc x '(1))
->(1 1)
x
->(1 1)

(setq x nil)
->nil
(nconc x '(1))
->(1)
x
->nil

やっぱり append 同様 (setq x (nconc x '(1))) と書くしかないのでしょうか?
できれば nil でダメな理由もお願いします。

環境 Windows10 Emacs30.1

0 likes

1Answer

nconc の説明ではこう書かれています。

the last CDR of each of the lists is changed to refer to the following list.

各リストの最後の (コンスセルの) CDR を変更する仕組みなのでコンスセルが存在しないなら変更すべきものも存在しません。 NIL はリストでありながらコンスセルが含まれないという特別な立場なので注意を払う必要があります。

ドキュメントにはあまり詳細が書かれていませんが、引数に NIL があった場合は単に読み飛ばしてそれ以外を (最後のコンスセルの CDR フィールドを変更する形で) 連結するようです。 そうやってリストを連結しても質問の例では x が参照している先は NIL から動かないので NIL のままです。

一般論としては nconc で連結した結果は nconc の返却値から取得すべきです。

破壊的更新をする関数にも二種類あり、質問者が期待しているようなオブジェクトの変更に意味がある関数と、オブジェクトの再利用をするような関数です。 nconc の場合はどちらかというと再利用タイプと考えるべきでしょう。 CDR を書き換えるということ自体にはあまり意味はなく、連結の効率的な実装のためにそうしているに過ぎません。

1Like

Your answer might help someone💌