• 締切済み

Lispのリストの破壊

Lispではリストの破壊を行う関数と非破壊的関数がありますがどのようなときにそれらを使い分ければいいのでしょうか? それぞれについてプログラムを行う上でどうゆう利点、欠点があるか知りたいです。

みんなの回答

  • hpsk
  • ベストアンサー率40% (48/119)
回答No.3

破壊関数のほうが効率が良いのは既出の通り. 欠点は,リストが文字通り破壊されてしまうのでそのリストが別の場所から参照されていた場合,思わぬバグを招くことがあること. 使い分けの方針としては,とりあえず非破壊関数で動くものを書いておいて,後から性能上重要なところかつ置き換えても安全だと確信できるところを破壊関数に置き換えていく,というのがよいです. なおNo.2の方の > (setq a (nconc a '(x)) もしくは (nconc a '(x)) というのは,(setq a (nconc a '(x))の代わりに(nconc a '(x))とだけ書くのでもOKという意味ではありません.念のため.

  • notnot
  • ベストアンサー率47% (4846/10257)
回答No.2

動作が異なるので、どちらを使っても同じ結果にケースは限定されます。 (setq a '(a b c)) (setq b a) としたとき、 (setq a (append a '(x)) と (setq a (nconc a '(x)) もしくは (nconc a '(x)) では、b の値が違ってきます。 同じ結果になるケースでは、破壊のほうが効率がいいです。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

非破壊的関数の利点はちょっと考えればわかるはずなので省略. 破壊的関数の利点として重要なのは, (破壊的操作が許されるのなら) メモリが節約できることです.

関連するQ&A

  • Lispの問題

    lispを最近習い始めた初心者です。以下の問題【2】つが解けないので回答をお願いします。 【1】 ;;; CONS CL-USER(1): (cons 'a 'b) (A . B) ; ドッティドペア ;;; (1 2 3) ;;; (1 . 2) 関数 CONS は上に並べたある関数の特別な場合と同じと見ることができる それは何か? 以下の ◇ は何に相当するか? ;;; (cons a b) ≡ (◇ a b) 【2】関数 PRINC を利用し、リストをドッティドペアとしてプリントする関数を定義してみよ です。【2】の問題は (dotted-print '(1 2 3)) => (1 . (2 . (3 . NIL))) が例としてあるのですが、理解できません。 例についても解説していただけると助かります。 【1】,【2】単体の回答でもどうかご教授御願いします。 後lisp初心者にオススメなサイトなどあったら教えてください。

  • lispの入門書

    lispの入門書を探しています。 lispの書き方をただ説明するだけでなく、他の言語と違ってどういう利点が あるのかを説明したものがいいです。 なにかおすすめの本があったら教えてください。

  • LISPを今から覚えたい

    最近Lispを覚えようとパソコンで動作するLISPを探しているのですが、CommonLispに対応する学習に最適なフリーのインタープリタが見つかりませんでした。手に入れることは可能でしょうか? まずはじめにやりたいことは、数値と文字(Hellow world)を関数?に渡して、数値分文字を表示させるものが作りたいのですが、 そのようなサンプルがかける方、教えてください。 LISPを覚えるにはたくさんの関数?を覚えると習得が早いでしょうか? それとも、考え方を先に身につけた方が早いでしょうか?

  • Lispでマージソート

    Lisp初心者のものです。 Lispでマージソートはどのように書けばいいのでしょうか? 結果のリストは、二つの引数リストの要素すべてを含んでいなければならず、たとえば (marge ' (3 3 6 7) ' (2 5 8)) の答えは (2 3 3 5 6 7 8) です。

  • LISPで・・・

    LISPで8Queenを作ろうと思うのですが、どう作ればいいのかわかりません。 ソースじゃなくても、作る上でのヒントでも何でもいいので、わかることがあれば 教えて下さい。

  • Lispについて

    最近プログラミングについて学ぼうと思っていろいろ調べてるのですが、その中でLispというものを見つけました。 関数型プログラミング言語であることや人工知能の開発に使われているということは分かったのですが、他にどのようなことができるのでしょうか? C言語に代わってソフトウェアの開発などもできるのでしょうか? (C++を学校で学び始めたばかりでまだ何もできないのですが…)

  • リストを逆順にする関数(LISP)

    「初めての人のためのLISP[増補改訂版]」のP150のリストを逆順に関数がよくわかりません。 以下がその関数です。 (defun nreverse (x) (nrev2 x nil)) (defun nrev2 (x r) (cond ((null x) r) (t (nrev2 (cdr x) x) (rplacd x r) ))) xがnilになるまで再帰を繰り返し、((null x) r) で再帰を戻りますがなぜs (rplacd x r)でリストが逆順になるんでしょうか。例えばxを(a b c)とすると x:(a b c) r:nil ↓ x:(b c) r:(a b c) ↓ x:(c) r:(b c) ↓ x:nil r:(c) ↓ rplacd (c) (b c) ↓ rplacd (b c) (a b c) ↓ rplacd (a b c) nil となるのですが、これじゃあ全然リストは逆順になりませんよね。 誰が教えてください、お願いします。 ちなみにrplacd は第一引数のcdrを第二引数に変換する関数です。

  • Lisp

    Lisp 今リリカルLispをやっているのですが、 詰まってしまって答えがないので困っています。 問題は (s n)を評価すると1+2+・・・+nが返るように関数をsiを定義する(ただしsは次のように定義されている define (s n) (si n 0) ) という問題です。 一応自分なりに考えたのが (define si (lambda (n x) (if (= n 1) (x) (si (- n 1) (+ n x))))) なんですが無限ループのようになるのかこれを実行すると固まって落ちてしまいます。 ご指摘よろしくお願いします。

  • Emacs Lisp: consセルと引用符?

    お世話になります。 Emacs Lispについて勉強しています 今は、リスト、consセルについて勉強しています。 以下、拙い質問になるかと思いますが、よろしくお願いします。 Lisp Interactionモードのバッファに、 '(1 2 3) というリストを書いて行末でC-jを押下すると (1 2 3) という式を返します。 しかし、 (1 2 3) という式を書いて行末でC-jを押下すると Debugger entered--Lisp error: (invalid-function 1) というエラーになります。 これは、1が関数、2と3が引数として評価されるからですね。 さて、リストではなく「consセル」を作るとします。 (1 . 2) と書いてC-jを押下すると、やはり Debugger entered--Lisp error: (invalid-function 1) というエラーになります。 '(1 . 2) であれば (1 . 2) と、正しくconsセルが出来ます。 '(1 . nil) であれば (1) というリストを返します。 これは、cdr部がnilであるconsセルはリストになるからですね。 では、3と、「1とnilからなるリスト」のconsセルを作って、結果的に(3 1)というリストにしようとします。 '(3 . '(1 . nil)) この場合は、予想に反して (3 quote (1)) となります。 '(3 . (1 . nil)) であれば、 (3 1) となります。一方、 (3 . (1 . nil)) とすると、 Debugger entered--Lisp error: (invalid-function 3) となります。 まとめると、 3と、「1とnilからなるリスト」のconsセルを作って、結果的に(3 1)というリストにしようとした場合は、 '(3 . (1 . nil)) のように外側のconsセルはクォートし、内側のconsセルはクォートしない、ということになりますね。 このクォートの振る舞いの違いはなぜでしょうか。 よろしくお願いします。

  • LISPプログラムをexeにしたい

    UbuntuでLISPプログラムを書いています。 eclというのを使ってコンパイルすることでスタンドアロンで実行できるファイルはできました。 でもこれはLinux上で実行できるものでWindowsでは使えません。 LISPで書いたプログラムをexeファイルにしてWindows上で使う良い方法はあるでしょうか? もしWindows用のソフトを使えば簡単だと言うならWindowsを使った方法でも構いません。

専門家に質問してみよう