Clojureと他のLispの比較[終了]


93

私の質問の目的は、炎上戦争を開始することではなく、どのような状況で各言語が「仕事に最適なツール」であるかを判断することです。

私はClojureに関するいくつかの本(Programming ClojurePractical ClojureThe Joy of Clojure、およびManning Early Access edition of Clojure in Action)を読んだことがあり、それは素晴らしい言語だと思います。私は現在、Common Lispマクロを主に扱っているLet Over Lambdaを読んでおり、それも非常に興味深い言語です。

私はLispのエキスパートではありません(初心者の方が多いです)が、関数型プログラミングと同様に、この言語ファミリーは私を魅了します。

Clojureの利点(および「その他」の欠点):

  • JVMで実行されます。

    • JVMは非常に安定した高性能言語環境であり、Sunの「一度書くとどこでも実行できる」という夢を十分に満たしています。Macbook Proでコードを記述し、それを実行可能なJARファイルにコンパイルして、追加のテストをほとんど行わずにLinuxとMicrosoft Windowsで実行できます。

    • (ホットスポット、その他)JVMは、高品質のガベージコレクションと、非常に高性能なジャストインタイムのコンパイルと最適化をサポートしています。ほんの数年前、Cで高速に実行する必要のあるすべてのものを書いたのですが、今ではJavaで実行することをためらっていません。

    • 標準のシンプルなマルチスレッドモデル。Common Lispには標準のマルチスレッドパッケージがありますか?

    • 、、、およびでこれらすべての括弧の単調さを分解しますが[]、Common Lispの専門家はおそらく、リーダーマクロを使用すると、それらをCLに追加できると教えてくれます。{}#{}

Clojureの欠点

  • JVMで実行されます。
    • 末尾再帰や継続はありません。Common Lispは継続をサポートしていますか?Schemeは両方のサポートを必要とすると私は信じています。

その他の利点(特にCommon Lisp)(およびClojureの欠点):

  • ユーザー定義可能なリーダーマクロ。

  • 他の利点は?

考え?その他の違いは?


15
個人的に私は1種類の括弧が好きです;)「よりクリーンな」コードのように見えます
Moe

3
あなたのアドバンテージリストで読んだ内容から、おそらくあなたもアーランに似ているかもしれませんwww.erlang.org
Peer Stritzinger

4
Clojureは、「recur」特殊フォームによる明示的な末尾再帰をサポートしています。これにより、明示的に要求する場合にテール再帰のすべての利点を得ることができます(唯一の例外は、現在、複数の関数間の相互テール再帰をサポートしていないことです)。
mikera '15年

1
Clojureは、少なくとも「継続渡しスタイル」という意味で、継続もサポートします。それはファーストクラスの継続がないことは正しいです。stackoverflow.com/questions/1173133/continuations-in-clojureを
mikera '15年

@mikera:1つの関数の末尾再帰。お互いを呼び出す2つの関数は、「トランポリン」で実行する必要があります。これは一種の扱いにくいです(ただし、独自の方法でエレガントです:-))。
ラルフ

回答:


52

Clojureを他のLispよりも好む理由の私の個人的なリスト(すべてのLispはまだ素晴らしいと私はまだ思っています!):

  • JVMで実行-したがって、JVM自体の素晴らしいエンジニアリング(高度なガベージコレクションアルゴリズム、HotSpot JIT最適化など)に自動的にアクセスできます。

  • 非常に優れたJavaの相互運用性-Java / JVM言語エコシステムの広範なライブラリとの互換性を提供します。私は、Clojureを「接着剤」言語として使用して、さまざまなJavaライブラリを効果的に接続しました。たくさんのJavaコードも開発しているので、ClojureはJavaツールとうまく統合できるので便利です(たとえば、Clojure開発には、反時計回りのプラグインを備えたMaven、Eclipseを使用しています)。

  • ベクトル[1 2 3]、マップ{:bob 10, :jane 15}、セットの優れた構文#{"a" "b" "c"}-(もちろんリストに加えて)現代のプログラミングにこれらのかなり不可欠なツールを検討します。

  • 個人的には、フォームをバインドするために角かっこを使用するのが好き(defn foo [a b] (+ a b))です。

  • 永続的で不変のデータ構造を備えた遅延関数型プログラミングに重点を置きます-特に、すべてのコアClojureライブラリは、デフォルトでこれをサポートするように設計されています

  • マルチコア同時実行のための優れたSTM実装。Clojureは現在、どの言語でも最高の並行処理ストーリーを持っていると思います(Rich Hickey自身による詳細については、このビデオを参照してください)

  • それは私が個人的に好むLisp-1(Schemeのような)です(関数型言語では、関数とデータを同じ名前空間に保持することは理にかなっていると思います)


2
STMの場合は+1。それ自体は、Clojureの使用を正当化するのに十分です。
アンドレ・キャノン

2
引き続きCL-STMライブラリを使用してSTMを入手できます。
Mike Manilone 2013年

2
@AndréCaron(必要な場合のみ)。
2015年

単純なwebappを記述して、たとえば月額5ドルの安価なホストでホストしたい場合、JVMのためにClojureでは明らかに不可能ですよね?
Hexatonic 2016年

@Hexatonic私はあまり経験がありませんが、最近使用されているマシンにJVMがないとは思えません。
MasterMastic 2016年

25

Clojureは言語であり、実装(通常はJVM上)であることを覚えておいてください。Common Lispは、10以上の異なる実装を持つ言語です。したがって、ここにカテゴリの不一致があります。たとえば、ClojureとSBCLを比較します。

一般的に:

  • Common LispのバージョンはJVMで実行されます:ABCL

  • 他のほとんどのCommon Lisp実装は

  • ほとんどのCL実装にはマルチタスク機能があり、ライブラリは共通のインターフェースを提供します

  • Common Lispには配列の構文があります。他のデータ型の構文はユーザーが記述でき、さまざまなライブラリによって提供されます。

  • Common Lispは、末尾呼び出しの最適化も継続もサポートしていません。実装はTCOを提供し、ライブラリは何らかの形の継続を提供します。


24

ClojureとCommon Lispの重要な違いは、Clojureが関数型プログラミングについてより規範的であることです。Clojureの哲学、イディオム、およびある程度の言語/ライブラリーは、機能的な方法でプログラミングすることを強く推奨し、場合によっては主張します(副作用なし、変更可能な状態なし)。

Common Lispは間違いなく関数型プログラミングをサポートしますが、変更可能な状態と命令型プログラミングも可能にします。

もちろん、並行性の面などにおいて、関数型プログラミングには多くの利点があります。しかし、他のすべての条件が同じである場合、状況ごとに使用するアプローチを選択することも重要です。Clojureは命令型プログラミングを完全に禁止しているわけではありませんが、Common Lispよりもそのスタイルに適応していません。


3
@Charlie Flowers:Common Lispでは、「完全に機能する」スタイル(永続的なデータ構造のサポートなど)でプログラムすることは可能ですが、訓練が必要だと思います。正しい?
ラルフ

2
「副作用なし、変更可能な状態なし」の明確化-Clojureには変更可能な状態があります(参照、アトム、エージェントなどはすべて変更可能です)が、制御された方法(STMメカニズムおよび関連するトランザクションを介して)にアクセスする必要がありますupdate semantics)
mikera

5
@mikera:Clojureが使用可能になるにはJavaライブラリの使用に依存していることを除いて、これらのすべてのライブラリには命令スタイルが必要であり、副作用がたくさんあります。... Javaの持つバインディングは毒の贈り物であることを、私を見つけた
アンドレ・キャノン

1
@Andre-確かに、変更可能な状態と命令的なセマンティクスを必要とするライブラリを使用する場合は、これを管理する必要があります。これは、他の言語からそのようなライブラリにアクセスした場合と同じです。しかし、2つの適切なオプションがあります:a)このようなライブラリを使用しないでください-純粋なClojureで完全に優れたコードを記述できるか、b)これらのライブラリとのインターフェースの複雑さを、通常は簡単な、Clojureスタイルの機能的なインターフェースでラップしますマクロやエージェントなど。全体として、Javaライブラリーを利用する機能には、問題よりもはるかに大きなメリットがあることがわかりました。
mikera '15年

4
@mikera:ライブラリにはメリットがあります。Javaライブラリー(これは、Rich Hickeyの言語の主な目標の1つです)の使用は、Clojureの「他のlispsよりも機能的」な側面に本当に反することを指摘しているだけです。私のコメントは、「これらのライブラリを書き直したりラップしたりしない限り、命令型のコードが得られ、Clojureのより良い部分から利益を得られない」という意味を意図していた。
アンドレ・キャノン

10

これは、Scheme(主にRacket)とClojureを比較した優れたビデオです。

公平を期すために、ラケットにはデータ型(#ハッシュ、#、角括弧など)にも構文糖(追加のリーダースタッフ)があります。

さらに、適切な末尾呼び出しを行うClojureの唯一の方法はを使用するrecurことです。これは、JVMへのコンパイルの欠点です。

これrecurは、Clojureでスタックを消費しない唯一のループ構造です。末尾呼び出しの最適化はなく、未知の境界のループに自己呼び出しを使用することはお勧めしません。recurは機能的であり、テール位置での使用はコンパイラーによって検証されます。(特別フォーム)。


リンクが死んでいると思います。
nawfal 14

1
@nawfal私はそれを修正したと思います
Daniil

6
リンクが死んでいる(もう一度?)
アカウント

1
そのリンクのビデオがvimeo.com/22675078にあるようです。
GDP2 2016年

trampolineテールコールもあります。
HappyFace 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.