web-dev-qa-db-ja.com

SchemeとCommon Lispの実際の違いは何ですか? (またはLISPの他の2つの方言)

注:どちらを学ぶべきか、どちらが良いか、またはそのようなことは求めていません。

SICPの無料版を選んだのは、読むのがいいと感じたからです(それについて良いことを聞いたことがあり、そのようなプログラミングの側面に興味があります)。

SchemeはLISPの方言であることを知っていますが、実際にはSchemeとCommon Lispの違いは何ですか?

「CLには大きなstdlibがあります... Schemeは実際のプログラミングには向いていません」ということはたくさんあるようですが、「これはCLがこれである/これを持っているから」という実際のことはありません。

65

違いは技術的であり(より重要なことに、私の意見では)文化的であるため、これは少し難しい質問です。答えは、不正確で主観的な見方しか提供できません。これが私がここで提供するものです。生の技術的な詳細については、 Scheme Wiki をご覧ください。

Schemeは、実用的でアカデミックなアプリケーション言語の両方を構築できる、エレガントで一貫した、よく考え抜かれたベース言語基盤を提供するという原則に基づいて構築された言語ですに。

純粋なR5RS(またはR6RS)Schemeでアプリケーションを書いている人を見つけることはめったにありません。また、最小限の標準のため、ほとんどのコードはScheme実装間で移植できません。これは、何らかの種類のエンドユーザーアプリケーションを作成する場合、Scheme実装を慎重に選択する必要があることを意味します。選択により、使用可能なライブラリが大きく決まるからです。一方、実際のアプリケーション言語を設計する際の相対的な自由は、Schemeの実装が他では見られない機能をしばしば提供することを意味します。たとえば、PLTラケットを使用すると、静的な型指定を利用でき、言語を認識できるIDEが提供されます。

基本言語を超えた相互運用性は、コミュニティ主導のSRFIプロセスを通じて提供されますが、SRFIの可用性は実装によって異なります。

ほとんどのSchemeの方言とライブラリは、反復ではなく再帰のような関数型プログラミングのイディオムに焦点を当てています。 OOPを実行するときにライブラリとして読み込むことができるさまざまなオブジェクトシステムがありますが、既存のコードとの統合は、Schemeの方言とその周辺の文化に大きく依存しています(たとえば、Chicken SchemeはRacketよりもオブジェクト指向のようです)。

MIT Schemeは強力な対話型サポートで知られていますが、PLTラケットははるかに静的であると感じています。いずれにしても、対話型プログラミングは中心的ではないようです。ほとんどのSchemeサブコミュニティに関心があり、ほとんどのCommon Lisp'sと同様にインタラクティブなプログラミング環境を見たことはありません。

Common LISPは、実用的なプログラミング用に設計された使い古された言語です。それはいイボと互換性のハックでいっぱいです-Schemeのエレガントなミニマリズムとは正反対です。しかし、それはそれ自体でとられたとき、はるかに特徴的です。

Common LISPは、ポータブルライブラリの比較的大きなエコシステムを育ててきました。通常は、アプリケーションのデプロイ後であっても、あまり手間をかけずにいつでも実装を切り替えることができます。全体的に、Common LISPはSchemeよりもはるかに統一されており、より徹底的な言語実験が行われたとしても、通常、まったく新しい言語の方言を定義するのではなく、ポータブルライブラリとして埋め込まれます。このため、言語拡張機能は保守的である傾向がありますが、組み合わせ可能(およびオプション)である場合もあります。

外部関数インターフェイスのような普遍的に有用な言語拡張機能は、正式な手段では開発されていませんが、すべての主要なCommon LISP実装で利用可能な準標準ライブラリに依存しています。

言語イディオムは、機能的、命令的、オブジェクト指向のアプローチのワイルドな混合物であり、一般的に、Common LISPは機能的というより命令的言語のように感じます。また、非常に動的であり、ほぼ間違いなく人気のある動的スクリプト言語のいずれよりも多く(たとえば、クラスの再定義は既存のインスタンスに適用され、条件処理システムにはインタラクティブ機能が組み込まれています)、インタラクティブで探索的なプログラミングが重要な部分です「Common LISPの方法。」これは、Common LISPで利用可能なプログラミング環境にも反映されており、実際にはすべてが、実行中のLISPコンパイラと何らかの直接的な相互作用を提供します。

Common LISPには、ビルトインオブジェクトシステム(CLOS)、単なる例外処理よりもはるかに強力な条件処理システム、実行時のパッチ適用可能性、さまざまな種類のビルトインデータ構造とユーティリティ(悪名高い [ 〜#〜] loop [〜#〜] マクロ、Schemeには非常にい反復サブ言語ですが、言うまでもなく非常に便利ですが、GOTOサポートを備えたprintfに似たフォーマットメカニズムフォーマット文字列)。

画像ベースのインタラクティブな開発と、より大きな言語のために、LISP実装は通常、Scheme実装よりもオペレーティングシステム間で移植性が低くなります。たとえば、組み込みデバイスでCommon LISPを実行するのは、気弱な人には向いていません。 Java仮想マシンと同様に、仮想メモリが制限されているマシン(OpenVZベースの仮想サーバーなど)でも問題が発生する傾向があります。一方、スキームの実装は、コンパクトでポータブル:ECL実装の品質の向上により、この点は多少緩和されましたが、その本質は依然として真実です。

商用サポートが必要な場合は、グラフィカルGUIビルダー、特殊なデータベースシステムなど、独自のCommon LISP実装を提供する会社がいくつかあります。

要約すると、Schemeはよりエレガントに設計された言語です。これは主に、いくつかの動的機能を備えた関数型言語です。その実装は、独特の機能を持つさまざまな互換性のない方言を表します。 Common LISPは、さまざまな見苦しいが実用的な機能を備えた、本格的で非常に動的なマルチパラダイム言語であり、その実装は互いに互換性があります。スキームの方言は、Common LISPより静的でインタラクティブではない傾向があります。一般的なLISPの実装は、インストールがより重く、扱いにくい傾向があります。

どちらの言語を選択したとしても、私はあなたにたくさんの楽しみを願っています! :)

90

基本的な実際の違い:

  • Common LISPには、変数と関数の個別のスコープがあります。一方、Schemeには1つのスコープしかありません。関数は値であり、特定の名前で関数を定義すると、ラムダに設定された変数が定義されます。その結果、Schemeでは、関数名を変数として使用し、それを他の関数に保存または渡すことができ、その変数を関数であるかのように呼び出します。ただし、Common LISPでは、(function ...)を使用して関数を明示的に値に変換し、(funcall ...)を使用して値に格納されている関数を明示的に呼び出す必要があります
  • Common LISPでは、nil(空のリスト)はfalse(たとえばif内)と見なされ、唯一のfalse値です。 Schemeでは、空のリストはtrueとみなされ、(別個の)#fが唯一のfalse値です
19
newacct

特に、多くのLISPの人々がSchemeをLISPとして分類するため、これは公平に答えるのが難しい質問です。

Josh Bloch(およびこの類推は彼の発明ではないかもしれません)は、地元のパブを選ぶのと同じような言語の選択について説明しています。その観点から:

「Scheme」パブには多くのプログラミング言語研究者がいます。これらの人々は、言語の意味、適切に定義されたシンプルな状態を維持すること、および革新的な新機能について議論することに多くの注意を払っています。誰もがプログラミング言語の特定のコーナーを探索できるように設計された独自のバージョンの言語を持っています。 Schemeの人々は、LISPから取った括弧付きの構文が本当に好きです。柔軟かつ軽量で統一されており、言語拡張に対する多く障壁を取り除きます。

「LISP」パブ?まあ...私はコメントすべきではありません。私はそこに十分な時間を費やしていません:)。

8
John Clements

スキーム:

  • 元々、ごくわずかな仕様(新しいR7RSはより重いようです)
  • 簡単な構文により、スキームをすばやく学習できます
  • 実装は追加の機能を提供しますが、名前は実装によって異なる場合があります

一般的なLISP:

  • 多くの機能は、より大きな仕様で定義されています
  • 関数と変数の異なる名前空間(LISP-2)

それはいくつかのポイントです、もっとたくさんあることを確認してください、今は覚えていません。

2
Moe