C#Dev-Lispを試しましたが、うまくいきません[非公開]


37

CLと少しのClojureの両方についてLispを学び、遊んだ数ヶ月後、C#の代わりにLispで何かを書く説得力のある理由がまだ見当たりません。

いくつかの説得力のある理由、または誰かが私が本当に大きなものを見逃していることを指摘してほしい

Lispの長所(私の研究による):

  • コンパクトで表現力豊かな表記法-C#よりも、そうです...しかし、私はそれらのアイデアをC#でも表現できるようです。
  • 関数型プログラミングの暗黙的なサポート-LINQ拡張メソッドを使用したC#:
    • mapcar = .Select(lambda)
    • mapcan = .Select(lambda).Aggregate((a、b)=> a.Union(b))
    • car / first = .First()
    • cdr / rest = .Skip(1)....など
  • ラムダおよび高階関数のサポート-C#にはこれがあり、構文は間違いなく簡単です。
    • 「(lambda(x)(body))」対「x =>(body)」
    • Clojureでは、「#(」と「%」、「%1」、「%2」が適切です
  • オブジェクトから分離されたメソッドディスパッチ-C#には拡張メソッドを介してこれがあります
  • マルチメソッドディスパッチ-C#にはこれがネイティブにありませんが、数時間で関数呼び出しとして実装できます。
  • コードはデータ(およびマクロ)-マクロを「取得」していないかもしれませんが、マクロの概念を関数として実装できない単一の例を見たことはありません。「言語」は変更されませんが、それが強さかどうかはわかりません
  • DSL-関数合成を介してのみ行うことができます...しかしそれは動作します
  • 型なしの「探索的」プログラミング-構造体/クラスの場合、C#の自動プロパティと「オブジェクト」は非常にうまく機能します。
  • Windows以外のハードウェアで実行します-そうですか?大学以外では、自宅でWindowsを実行していない人、または* nix / Macで少なくともWindowsのVMを実行している人は1人しか知りませんでした。(もう一度、多分これは思ったよりも重要で、洗脳されたばかりです...)
  • ボトムアップ設計のためのREPL-わかりました、これは本当にすてきで、C#では見逃しています。

Lispに欠けているもの(C#、. NET、Visual Studio、Resharperが混在しているため):

  • 名前空間。静的メソッドであっても、コンテキストを分類するために「クラス」に結び付けるのが好きです(Clojureはこれを持っているようですが、CLはそうではないようです)。
  • 優れたコンパイルおよび設計時サポート
    • 型システムにより、渡すデータ構造の「正確さ」を判断できます
    • つづりの間違いはリアルタイムで下線が引かれます。ランタイムまで知る必要はありません
    • コードの改善(命令的なアプローチの代わりにFPアプローチを使用するなど)が自動的に提案されます
  • GUI開発ツール:WinFormsおよびWPF(ClojureがJava GUIライブラリにアクセスできることは知っていますが、それらは私にとってまったく異質なものです。)
  • GUIデバッグツール:ブレークポイント、ステップイン、ステップオーバー、値インスペクター(テキスト、xml、カスタム)、ウォッチ、スレッドごとのデバッグ、条件付きブレークポイント、任意のレベルのコードにジャンプできるコールスタックウィンドウスタック内
    • (公平を期すために、Emacs + Slimeでの私の仕事はこれの一部を提供しているように見えましたが、VS GUI駆動のアプローチには部分的です)

私はLispを取り巻く誇大広告が本当に好きで、それにチャンスを与えました。

しかし、Lispでできること、C#ではできないことはありますか?C#ではもう少し冗長かもしれませんが、オートコンプリートもあります。

私は何が欠けていますか?Clojure / CLを使用する理由は何ですか?


4
既に機能的なスタイルでプログラミングしており、Windowsインフラストラクチャにかなり依存しているように聞こえるので、C#から変更する必要がある理由はわかりません。私が知っているほとんどの人はMacまたはLinuxを使用しているので、多くは明らかにあなたが一緒に走る群衆に依存しています(3.1以降、Windowsのすべてのバージョンを使用しましたが、クロスプラットフォームソフトウェアと* nixシステム全般で作業することを今でも好みます...しかし、その後、ネイティブGUIの作業は一切行わず、すべてのサーバーとWeb UIを使用します)
ショーンコーフィールド

2
あなたは見て持つことができPerlの前に豚を。それは聞くのが楽しい話であり、マクロが何のために良いのかの簡単な例を提示します。
マティアスベンカード

4
「マクロの概念を関数として実装できない単一の例を見たことはありません」-あなたがどのように書くANDOR、または関数として見たいのか。それは行うことができます(LAMBDAこれはマクロでもあります)が、完全に吸うわけではない明白な方法はわかりません。

1
「名前空間。...Clojureはこれを持っているようですが、CLはそうではないようです」-あなたが探しているものについて、より具体的に教えてください。私は実際にClojureを使用していませんが、その名前空間はCLのパッケージとほとんど同じように見えます。

4
Jonathan:CLはパッケージ内のシンボルの命名に:(または::エクスポートされていないシンボルに)使用http:sessionchat:sessionます。たとえば、ここの例ではand を使用します。

回答:


23

マクロを使用すると、言語の快適さを損なわずにコンパイラを作成できます。C#のような言語のDSLは通常、ランタイムインタープリターに相当します。ドメインによっては、パフォーマンス上の理由で問題になる場合があります。速度は問題ない、そうでなければ、インタプリタ言語ではなくC#でコーディングすることと思います。

また、マクロを使用すると、人的要因も考慮することができます。特定のDSLで最も使いやすい構文は何ですか C#では、構文についてできることはあまりありません。

したがって、Lispを使用すると、効率化への道を犠牲にすることなく、言語設計に参加できます。そして、これらの問題はあなたにとっては重要ではないかもしれません、それらはすべての有用な生産指向プログラミング言語の基礎の根底にあるため、非常に重要です。C#では、この基本的な要素はせいぜい非常に限られた形式で公開されます。

マクロの重要性は他の言語でも失われません-テンプレートHaskell、camlp4が思い浮かびます。しかし、やはり使いやすさの問題です。これまでのLispマクロは、コンパイル時変換の最もユーザーフレンドリーで強力な実装である可能性があります。

つまり、一般的にC#などの言語で人々が行うことは、DSIL(Domain Specific Interpreted Languages)の構築です。Lispを使用すると、より過激なDSP(ドメイン固有のパラダイム)を構築できます。ラケット(以前のPLT-Scheme)は、この点で特に刺激的です-彼らは、怠zyな言語(Lazy Racket)、型付きのもの(Typed Racket)、Prolog、およびDatalogがすべてマクロを介して慣用的に埋め込まれています。これらすべてのパラダイムは、大規模なクラスの問題に対する強力なソリューションを提供します-命令型プログラミングやFPパラダイムでさえも最適に解決されない問題。


3
この議論で面白いと思うのは、DSL / DSILを実装する機会に出会ったことはまったくないということです(または、無知で見落とされただけです)。DSLのパワーについて詳しく教えてください。(開発者とユーザーの両方にとって。)これは、私が本当に見逃している大きなことかもしれません。

15
@Jonathan Mitchem、あなたはすでに多くの外部DSLを使用しています-構成ファイル、ビルドスクリプト、ORM構成、ビジュアルコードジェネレーター(例えば、winformsエディター)、XAML、パーサージェネレーターなど。個別のビルドツールは必要ありません。1つの言語で提供されます。そして、少なくとも2つの組み込みDSLに精通している必要があります。正規表現とSQLです。
SKロジック

わあ 私はそれらをDSLだと思ったことはありません。さて、「c#でできることは何でも、c#に固執する」ことに基づいて、私は意図的にその多くから外れました。個人的には、一貫した動作をする1つのツールに固執するのが好きです。しかし、これらの例でDSLの価値を理解しています。

2
@Jonathan Mitchem、与えられたツールの問題は、与えられた目的に必ずしも適合しないということです。タスクごとに異なるツールを選択する必要があります。そして、Lispを含むメタ言語の力は、メイン言語の上に独自のドメイン固有のツールを成長させることができるため、別のツールに完全に切り替える必要がないことです。Nemerleをご覧になることをお勧めします。C#開発者にとっては、Nemerleを理解する方が簡単であり、そのマクロはLispとほぼ同じくらい強力です。
SKロジック

3
「私は1つのツールにこだわるのが好きです...」Lispで適切に作成されたDSLは、Lispの能力を完全に隠さないため、ツールは1つだけです。特定のドメインのコーディングをより「自然」にする方法で、つまりより優れた抽象化と全体的な編成で、語彙を追加するだけです。

15

もともとLispsでしか利用できなかったほとんどすべてが、ありがたいことに他の多くの現代言語に移行しました。最大の例外は、「コードはデータ」という哲学とマクロです。

コードはデータ(およびマクロ)-マクロを「取得」していない可能性がありますが、マクロの概念を関数として実装できない単一の例を見ていない

ええ、マクロは理解しにくいです。一般に、メタプログラミングは理解しにくいです。あなたが見た場合に任意の機能として実装することができ、マクロを、その後、プログラマはそれが間違っていました。マクロは、機能が機能しない場合にのみ使用してください。

マクロの「hello world」の例は、condの観点から「if」を書くことです。マクロの力を学ぶことに本当に興味があるなら、関数を使用してclojureで「my-if」を定義してみて、それがどのように壊れるかを見てください。私は神秘的になるつもりはありません、説明だけでマクロを理解し始める人を見たことがありませんが、このスライドショーはかなり良いイントロです:http : //www.slideshare.net/pcalcado/lisp-macros-in -20分のフィーチャリングプレゼンテーション

マクロを使用して文字通り数百/数千行のコードを保存する小さなプロジェクトがありました(Javaでの場合と比較して)。Clojureの多くはClojureに実装されていますが、これはマクロシステムのためにのみ可能です。


3
コードに手を触れることなく、ClojureとC#の両方で、頭の中でマクロなしの「if」を実装するシナリオを実行しました。効果的に(または文字通り)実行できません。私はそれがきちんとしていることを認めます。しかし、私はそれが私にとってどのように役立つかについてのつながりがありません。巧妙な機能設計やオブジェクト指向設計ではできないマクロ( "if"の記述以外)で何ができますか?「これが私にどのように役立つか」は、言語を評価するための有効な基準ではありませんが、それを使用するかどうかを評価するためのものです。(私は本当にLispに切り替える価値があることを望んでいますが、実行可能な代替手段になるという点には

1
その例を理解するのに少し時間がかかります。私にとって、「定型コードの保存」は通常、「リファクタリング」という用語を呼び出します。これは、説明が私を納得させなかった理由の一部です。私はそれを適用したすべてのインスタンスで動作するソリューションを持っています。質問は、マクロを使用できるケースをどのように識別するのでしょうか?

1
マクロは価値があることに同意しますが、my-ifがマクロを必要とするのは事実ではなく、高次関数として記述することができます(以下のCLの例を参照)。コードをウォークスルーするか、新しいレキシカルコンテキストに配置する場合にのみ、マクロが本当に必要です。(defun my-if (test then &optional else) (cond (test (funcall then)) ('otherwise (funcall else))))

1
基本的に、関数を使用すると、引用符で囲まれたコードを受け入れるかどうかを選択できます。引用コードは歩くことができますが、関数のレキシカルコンテキストで実行しているため、レキシカルコンテキストがありません。または、クロージャを受け入れて、そのレキシカルコンテキストを保持することができますが、クロージャを呼び出したり、ウォークしたり、レキシカルコンテキストに何かを追加したりすることはできません。両方を行うには、マクロが必要です。マクロは、マクロ呼び出しのレキシカルコンテキストに展開される前に、コードをウォークしてラップできます。

7
@Jonathan Mitchem、LINQ構文はマクロでできることの良い例ですが、言語は適切なメタプログラミングをサポートしていないため、代わりに言語コアで実装する必要がありました。
SKロジック

14

私はCommon Lispの専門家ではありませんが、C#とClojureの両方をかなりよく知っているので、これが有用な視点になることを願っています。

  • 単純な構文=> power -Lispは、可能な限り単純な構文に関するものです。S式はあなたが必要とするすべてです。「(function-call arg1 arg2 arg3)」を調べたら、基本的にはそれが得られます。残りは、適切な関数呼び出しと引数を選択するだけです。ほとんど単純に思えますが、実際には、この単純さがLispに非常に強力で柔軟性を与え、特にLispで有名なメタプログラミング機能を可能にします。たとえば、マクロが同じ引数でいくつかの異なる関数を呼び出すようにしたい場合は、次のようにします(これは単なるランタイム関数アプリケーションではありません -個々の関数呼び出しをすべて書き出したかのようにコンパイルされたコードを生成するマクロです)手で):
(defmacro print-many [functions args]  
  `(do   
     ~@(map   
        (fn [function] `(println (~function ~@args)))   
        functions)))

(print-many [+ - * /] [10 7 2])  
19  
1  
140  
5/7
  • 信じられないほど単純な構文の結果として、Lispの「コードはデータ」という哲学は、関数の構成/テンプレート/ジェネリックなどでできることよりもはるかに強力です。 、言語の基本的な特徴として。C#やJavaのような非同音異義言語でこの種の機能を取得しようとすると、最終的にはLispを再発明することになります。したがって、有名なグリーンスパンの第10規則:「十分に複雑なCまたはFortranプログラムには、Common Lispの半分の、アドホックで、非公式に指定され、バグに乗った、遅い実装が含まれています。」アプリケーション内でチューリング完全なテンプレート/フロー制御言語を発明していることに気付いたなら、おそらく私が言っていることを知っているでしょう.....

  • 並行性はClojureのユニークな強みです(他のLispに比べても)が、プログラミングの将来が非常にマルチコアマシンに対応するアプリケーションを作成しなければならないと考えるなら、本当にこれを調べる必要があります-それはかなり画期的。Clojure STM(ソフトウェアトランザクションメモリ)は、Clojure がIDと状態の斬新な分離に基づいた不変性とロックフリーの同時実行構造を採用しているため機能しますIDと状態に関するRich Hickeyの優れたビデオを参照)。この種の同時実行機能を、APIの大部分が可変オブジェクトで動作する言語/ランタイム環境に移植することは非常に困難です。

  • 関数型プログラミング -Lispは、高階関数を使用したプログラミングを重視しています。クロージャー/関数オブジェクトなどを備えたオブジェクト指向オブジェクトでエミュレートできることは正しいですが、違いは、言語と標準ライブラリ全体が、この方法でコードを書くのに役立つように設計されていることです。たとえば、Clojure シーケンスは遅延であるため、C#/ JavaのArrayListsやHashMapsとは異なり、無限に長くなる可能性があります。これにより、いくつかのアルゴリズムの表現がはるかに簡単になります。たとえば、以下はフィボナッチ数の無限リストを実装します。

    (def fibs (lazy-cat '(0 1) (map + fibs (drop 1 fibs))))

  • 動的型付け -Lispは、関数型プログラミング言語の「動的」な端にいる傾向があります(Haskellのような静的型の非常に強力で美しい概念を持つ言語とは対照的です)。これには長所と短所の両方がありますが、動的言語は柔軟性が高いため、プログラミングの生産性を優先する傾向があると思います。この動的な型付けは、実行時のパフォーマンスにわずかなコストがかかりますが、それが気になる場合は、常にコードに型のヒントを追加して静的な型付けを行うことができます。基本的には、デフォルトで利便性が得られ、それを取得するために少し余分な作業を行う場合はパフォーマンスが向上します。

  • インタラクティブな開発 -実際、C#4.0で何らかのREPLを取得できると思いますが、Lispでは、それは目新しさではなく標準的な方法です。コンパイル/ビルド/テストサイクルを実行する必要はまったくありません。実行環境でコードを直接記述し、後でソースファイルにコピーするだけです。すぐに結果を確認し、ソリューションを反復的に改良する、非常に異なるコーディング方法を教えます。

「欠落」とみなされるものに関するいくつかの簡単なコメント:

  • おっしゃるように、Clojureには名前空間があります。実際、これらは動的な名前空間です。実行時に更新できます。これにより、インタラクティブな開発に驚くべき利点がもたらされます。実行中のスレッドの鼻の下で関数を再定義したり、ライブのデータ構造をハッキングしたりするのはとても楽しかった。
  • コンパイル/設計時のサポート-REPLでコーディングしている場合はあまり関係ありません-それを行うだけで、結果を直接確認できます。そうは言っても、Clojureは、Eclipse用CounterClockwiseプラグインなど、IDEサポートの改善を始めています。
  • GUI開発-はい、新しいAPIを習得する必要がありますが、言語を切り替える場合は常にそうです。良いニュースは、Java APIがそれほど難しくなく、興味深いClojureがいくつかあることです。非常に使いやすい特定のラッパー/例。良い例については、Clojure GUI開発に関するこの質問をご覧ください
  • GUIデバッグ:これは、EclipseのGUIデバッガーで、CounterClockwiseを使用している場合、またはNetbeansを使用している場合はEnclojureを使用している場合に機能します。そうは言っても、この機能は使用しません。REPLでの対話型デバッグの生産性が向上します。

個人的には、Clojure / Lispの利点は非常に魅力的であり、C#/ Javaに戻る予定はありません(すべての有用なライブラリを借りる必要がある以上です!)。

しかし、本当に頭を悩ませるのに数ヶ月かかりました。啓発的な学習体験としてLisp / Clojureを学ぶことに本当に興味があるなら、いくつかのことを実装するように飛び込んで強制することに代わるものはありません.....


1
アイデアの素晴らしい列挙をありがとう。私は実際にC#のIEnumerable <>コンストラクトを介してレイジーシーケンスをよく使用します(2005年以降、ArrayListに触れていません)が、その考えは理解しています。Clojureの並行処理プリミティブは非常に印象的です。私は数年前にグリッドコンピューティングをC#で行っていました(多くのマルチコアマシンでの同時実行)。それが未来だとまだ信じています。おそらく私が皆から得た最大のアイデアは、「あなたは本当にそれを掘り起こして経験しなければならない、それは本当に説明することはできません」です。だから、私は掘り続け、経験し続けるつもりです。

1
助けてくれて嬉しい-それは絶対に正しい精神です!!
ミケラ

10

C#には多くの機能がありますが、構成は異なっています。一部の言語にまだ機能があるということは、使いやすく、パラダイム的で、他の言語とうまく統合されていることを意味しません。

Common Lispには次の組み合わせがあります。

  • データ構文としてのs式
  • データとしてのコードは、マクロやその他の記号計算の手法につながります
  • 動的言語により、ランタイムの変更が可能(遅延バインディング、MOPなど)
  • 強く型付けされた、動的に型付けされた
  • インクリメンタルコンパイラーまたはインタープリターでのインタラクティブな使用
  • コア実行エンジンとしての評価者
  • ガベージコレクションを使用した管理メモリ
  • 命令型、関数型、オブジェクト指向のプログラミングを多用するハイブリッド言語。他のパラダイムを追加できます(ルール、ロジック、制約など)。

現在、C#などの他の言語にも同様の機能があります。しかし、多くの場合、同じ強調ではありません。

C#は

  • Cのような構文
  • ほとんどの命令型オブジェクト指向、いくつかのFP機能
  • 静的に型付けされた
  • 主にバッチコンパイラでのバッチ使用
  • ガベージコレクションを使用した管理メモリ

Lispのように広く使用されていない場合、たとえばC#にコード操作機能があるのは役に立ちません。Lispでは、あらゆる種類の単純な方法と複雑な方法でマクロを頻繁に使用しないソフトウェアはあまりありません。コード操作の使用は、Lispの大きな機能です。いくつかの用途をエミュレートすることは多くの言語で可能ですが、Lispのように中心的な機能にはなりません。例については、「On Lisp」または「Practical Common Lisp」などの本を参照してください。

対話型開発でも同じです。大規模なCADシステムを開発する場合、開発のほとんどはエディターとREPLから対話型で実行され、実行中のCADアプリケーションに直接実行されます。多くの場合、拡張言語を実装することで、C#または他の言語でその多くをエミュレートできます。Lispの場合、変更を追加するために開発中のCADアプリケーションを再起動するのは愚かなことです。CADシステムには、CADオブジェクトとそれらの関係(一部、含まれる、...)を記述するための言語機能(マクロおよびシンボリック記述の形式)を追加した拡張Lispも含まれます。C#でも同様のことができますが、Lispではこれがデフォルトの開発スタイルです。

インタラクティブな開発プロセスを使用して複雑なソフトウェアを開発する場合、またはソフトウェアにかなりの象徴的な部分(メタプログラミング、その他のパラダイム、コンピューター代数、作曲、計画など)がある場合、Lispが適している可能性があります。

Windows環境で作業している場合(私はしていません)、C#はMicrosoftの主要な開発言語であるため、利点があります。Microsoftは、Lispのフォームをサポートしていません。

あなたが書く:

  • 名前空間。静的メソッドであっても、コンテキストを分類するために「クラス」に結び付けるのが好きです(Clojureはこれを持っているようですが、CLはそうではないようです)。

Common Lispは、名前空間をクラスに付加しません。名前空間はシンボルパッケージによって提供され、クラスに依存しません。CLOSを使用する場合は、オブジェクト指向プログラミングへのアプローチの方向を変える必要があります。

  • 型システムの優れたコンパイルおよび設計時のサポートにより、ミススペルされたすべてのデータ構造の「正確性」をリアルタイムで判断できます。コードの改善(命令的なアプローチの代わりにFPアプローチを使用するなど)が自動的に提案されるのをランタイムまで待つ必要はありません。

Lispコンパイラを使用します。未知の変数について通知し、スタイルの推奨事項(使用するコンパイラーに応じて)がある場合があり、効率のヒントを提供します。

  • GUI開発ツール:WinFormsおよびWPF(ClojureがJava GUIライブラリにアクセスできることは知っていますが、それらは私にとってまったく異質なものです。)

LispWorksやAllegro CLなどの商用Lispは、Windowsでも同様の機能を提供します。

  • GUIデバッグツール:ブレークポイント、ステップイン、ステップオーバー、値インスペクター(テキスト、xml、カスタム)、ウォッチ、スレッドごとのデバッグ、条件付きブレークポイント、任意のレベルのコードにジャンプする機能を備えた呼び出しスタックウィンドウスタック内(公平に言うと、Emacs + Slimeの私のスティントはこれの一部を提供しているように見えましたが、VS GUI駆動のアプローチには部分的です)

LispWorksやAllegro CLのような商用Lispは、Windowsですべてを提供します。


1
私の批判は、実際にはLispに対するものではありません。私はそれらが非常に有能であると思います。私は、私がまだしていないLispでできること/ギブミーを探しています。私は、ほとんどのC#開発者が「新しい」言語機能の多くを使用していないことを完全に理解しています。大きなポイントは、私がやるということであり、正直なところ、GUIの外では、ほぼ100%FPスタイルで記述していると思います。FPは概念的な飛躍でしたが、価値があります。ただし、現在の場所からLispに切り替えても、ほとんど利点はありません。私はチャンスを与え続けなければならない理由があることを見つけたいと思っています。

@Jonathan Mitchem:C#は実際にはFP言語のように見えません。たとえ言語にサポートする機能があり、いくつかのライブラリがそれらを使用している場合でも。MicrosoftエコシステムでFPプログラミングを行いたい場合は、F#が最適です。

@Rainerいいえ、FP言語のようには見えませんが、それはできますが、かなりコンパクトです。そして、命令型コード、つまりオブジェクト指向が必要な場合は、それもできます。(少しトピックから外れています:F#を掘り下げる価値のある深刻な言語だとはあまり考えていません。Haskellでモナドに興味を持ちたいと思います。 「本当の」言語のいずれか[そして当時はそうではなかった、私見])


@Jonathan Mitchem:なぜ見なければならないのですか?私は、C#がいくつかのFP機能をサポートしていると書きました。それは命令型のオブジェクト指向言語に追加されたばかりで、Lisp、Schemeのように慣用的ではありません。特に、SML、F#、Haskell、または他の主に機能的な言語と比較されません。私の要点は、C#では一部のFPが可能ですが、コア機能ではありません。

5

Rainier Joswigが一番いいと言った。

私にとって、Lispの機能は、Lispの機能のリストを見ただけでは理解できません。Lisp、特にCommon Lispの場合、全体は部分の合計よりも大きくなります。REPLとS式、マクロ、マルチメソッドディスパッチ、クロージャ、パッケージ、CLOS、再起動、X、Y、Zだけではありません。すべてが巧妙に統合されています。これは、他のプログラミング言語の日々の経験とは非常に異なる、日々の経験です。

Lispは見た目が異なり、使用方法も異なります。Lispを使用するときは、プログラミング方法が異なります。エレガントで、完全で、大きく、シームレスです。それは、それ自身の傷とペッカディロなしではありません。確かに、他の言語と比較して、それが先に出てこないかもしれない場所で行われるかもしれません。しかし、Lispが言語XとREPLおよびマクロ、または言語Yとマルチメソッドのディスパッチと再起動を行うことは決してありません


3
コードはデータ(およびマクロ)-マクロを「取得」していないかもしれませんが、マクロの概念を関数として実装できない単一の例を見たことはありません。「言語」は変更されませんが、それが強さかどうかはわかりません

通常、マクロは関数呼び出しとして表現できないものに使用する必要があります。C#にswitch-like条件があるかどうかはわかりません(switch(form){case ...}のようにCに存在するものに似ています)が、それが同じ制限に近いと仮定します(整数型が必要です)。

さて、あなたはそのように見えるが、文字列でディスパッチする何かが欲しいとさらに仮定しましょう。lisp(まあ、特にCommon Lispおよびおそらく他の言語)では、それは「ちょうど」マクロを離れており、ユーザーが一致する定数文字列(おそらく困難ではない)を持つように制限すると、(コンパイル時)計算できますどのケースが一致するかを判断するための最小限のテストシーケンス(または、クロージャーを格納するハッシュテーブルを使用する場合があります)。

これを関数(比較文字列、実行するケースとクロージャーのリスト)として表現することは可能かもしれませんが、おそらく「通常のコード」のようには見えず、それがlispマクロが確実に勝つ場所です。あなたは、おそらくのように、かなりの数のマクロやマクロ等であるtaht特別なフォームを使用しましたdefundefmacrosetfcondloopおよび多く。


2

これは、読者がLispの擁護の表面から読者を連れて、使用されている概念のより深い意味合いのいくつかを示す最高の説明記事です。

http://www.defmacro.org/ramblings/lisp.html

他の場所でこのような考えを読んだことを思い出します。他の言語はLispのさまざまな機能を採用しています。より良いC ++ / C / Algolを生成するためのガベージコレクション、動的型付け、匿名関数、クロージャ。しかし、Lispのフルパワーを得るには、その本質的な機能のすべてが必要です。その時点で、Lispの別の方言があります。

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