質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Scheme

Schemeは、Lispから派生したプログラミング言語の一つであり、仕様または実装を指す場合もあります。言語自体の仕様はシンプルで、関数型言語として理解しやすいことから記号処理などで主に用いられている言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

LISP

LISPはプログラミング言語の一種であり、関数型言語に分類されています。 特徴として、括弧を多様する独特の構文を持ちます。

Q&A

解決済

2回答

628閲覧

lispやschemeにコンスセルは必要なのですか?

hojo

総合スコア195

Scheme

Schemeは、Lispから派生したプログラミング言語の一つであり、仕様または実装を指す場合もあります。言語自体の仕様はシンプルで、関数型言語として理解しやすいことから記号処理などで主に用いられている言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

LISP

LISPはプログラミング言語の一種であり、関数型言語に分類されています。 特徴として、括弧を多様する独特の構文を持ちます。

1グッド

1クリップ

投稿2018/01/03 08:14

編集2018/01/03 08:23

javascriptでlispのようなものを実装して遊んでいます。

lispやschemeの根元にはコンスセルという対になったポインタが存在し、コンスセルのcdr部にコンスセルのポインタが連続格納されることでリストが作られる。そして同時にlispやschemeのプログラム自体もリストで構成されているという認識をしています。

javascriptでコンスセルを作成することを考えた時、私はjavascriptのArrayの[0]と[1]を利用して作成することを考えました。しかしここで違和感を感じました。Arrayはもともとリストであるのに、リストを作るためにArrayを使ってコンスセルを作成してもう一度リストを作ることに意味はあるのか?ということです。

schemeでlambdaを作成した時、restargumentを取得する際にパラメータ部分にドット対を使うことで以降の引数をリストで受け取れることを知って、なるほどドット対はこんな風に使うのかと思いました。その他の言語では...restなんて書いたりしますよね。しかしrestargumentを受け取る方法は他にも作れそうです。(lambdaの中で__args__を参照できるとか)

何言ってんだ!コンスセルがあるから木構造ができるんだよ。という意見もありそうですが、リストを使った木構造の方が複雑な木構造を実現できる気がしています。

また、コンスセルが存在するからこそconsを使ったエレガントなリストの作成や、carやcdrを使って好きな部分を参照できるため、Arrayだったらsliceなどを使わないと実現できないことが負荷なくできるのであろうとも考えています。

しかしそもそもコンスセルのポインタ地獄で式を評価すること自体、javascriptにとってかなり負荷になるのではないか?と思いました。またコンスセルの存在しないlispのようなものを作ったとしたら、それはドット対という特殊な構文を必要としないシンプルなものになるのでは?とも感じています。

ドット対の存在しないlispなんてlispとは言えない!なんて思われるかもしれませんが、まさにそう思われた方はなぜそう思うのか教えていただきたいです。

lispやschemeでまともにプログラムを組んだことがないのにlispのようなものを実装していること自体がおかしいとは思うのですが、修行が足りないためにコンスセルやドット対にメリットを感じられません。Arrayを使ったリストだけを利用してLISPを実装したら、何か不便なことが起こるのでしょうか?

C言語のような可変長配列の存在しない言語(確かないですよね?)でLISPを実装する場合にはコンスセルは可変長配列を実現するだけでなく柔軟な切り貼りができる便利な存在となりえるが、Javascriptには可変長配列のArrayが元々存在するからメリットを感じにくいということなのでしょうか?

詳しい方、アドバイスよろしくおねがいいたします。

tf2014👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

Arrayは順番付きの静的な列を効率よく実現できるデータ構造ですけど、構造の共有に適した構造ではありません。例えばJavascriptのArrayやPythonのlistでLispのリストを実現したとしますと以下のことが簡単には実現できないと思います。

lisp

1(setq a '(a b c)) ;; a = (a b c) 2(setq b (cdr a)) ;; b = (b c) 3(setf (car b) 'bb) ;; b = (bb c) かつ a = (a bb c)

lispでも何でもかんでも構造の共有を起こすわけではなく、他のリストと共通部分を持たないという仮定を置くべきケースと共通部分を持つという前提のものが両方出てきます。しかしながら少なくとも後者が充分効率的に実装できる必要があります。

その理由で一般の配列は向いておらずlinked listつまりドット対のようなデータ構造にする必要があると考えるとよいと思います。


ただ・・・ドット対はランダムアクセスに向いた構造ではないとかメモリー効率がよくないといった理由で、Lispの実装でも「他と共有部分がない」とか「cdrでリストの部分列をトラバースするのではなく要素をインデックスでアクセスするのが主」というケースでは内部的に配列を用いるような最適化は考えられると思います。さらに構造を変更しないという前提が置けるケースではcdrの結果として「実体の配列とその何番目以降を指しているかのインデックス」を用いてリストの部分共有を実現するなどといった工夫も考えられると思います。

Lispのドット対は外部仕様は極めて単純ながら内部の実装はこういった様々な工夫をする余地があるような気がします。個々の実装について詳しくないですがそうしたアイデアの記事を見かけたことはあります(ずいぶん昔に見たものなので今日のポピュラーな実装でそのような実装が行われているかどうかについてはすみませんがわかりません)

投稿2018/01/03 08:52

編集2018/01/03 09:14
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hojo

2018/01/03 09:07

なるほど、大変わかりやすい回答ありがとうございましたm(_ _)m
guest

0

はじめまして。言語仕様にあっているならば、コンスセル構造(これは実装の一種であって、このように実装しなければならない、という規則ではありません)使わなくともルール違反ではないと思います。むしろすべてをコンスセル構造にすると効率が落ちる場合もあると思います。
例えば、リストを(要素の値を描き変えない)配列として実装することも可能だと思います。ランダムアクセスができるので要素を見つけるのは効率が上がることが期待できますが、リスト構造を変える操作は効率が下がりそうです。
C++なら、長さが実行時に決められるvectorというデータ構造もあります。
schemeでもクロージャーは内容を見ようとしてもそのままでは中身が見えません。クロージャーもコンスセルを使って実装することは可能ですが効率が悪いのでしょう。

投稿2019/01/16 11:19

編集2019/01/16 11:28
myoon

総合スコア100

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問