2008-08-05 10 views
41

私は、LISPがその場でマクロを使って構文を再定義できることをたくさん読んできました。私はこのことが実際にどれだけ遠くにあるのか不思議です。境界線が別の言語のコンパイラになるほど言語構造を再定義できますか?たとえば、LISPの機能的な性質をよりオブジェクト指向の構文と意味に変更できますか?Rubyのような構文に近いと言えるでしょうか?LISPマクロはどこまで行くことができますか?

特に、マクロを使用してかっこを取り除くことは可能ですか?自分のマイクロ機能でEmacsをカスタマイズするのに十分な(Emacs-)LISPを学んだことがありますが、言語をカスタマイズするにはどのくらいのマクロが使えるのか非常に興味があります。

+3

lispはオブジェクト指向であることに注意してください。 Common Lispオブジェクトシステムを参照してください。 – catphive

+2

[Peter Norvig](http://norvig.com/bio。html)は、[book](http://norvig.com/paip.html)に[Prolog Interpreter](http://norvig.com/paip/prolog.lisp)を作成しました。 –

+1

スキームマクロは非常に強力です。私はSchemeマクロとして完全なLINQ実装を書きました。 [https://ironscheme.svn.codeplex.com/svn/IronScheme/IronSchemeConsole/ironscheme/linq.ss](https://ironscheme.svn.codeplex.com/svn/IronScheme/IronSchemeConsole/ironscheme/linq.ss)このすべての力で、私はそれを適用する良いアイデアが不足している! – leppie

答えて

32

これは本当に良い質問です。

私はそれが微妙な間違いなく釈明だと思う:

マクロはS式で立ち往生されていません。キーワード(記号)を使って書かれた非常に複雑な言語については、LOOPマクロを参照してください。したがって、ループを括弧で開始して終了することができますが、その内部には独自の構文があります。

例:

(loop for x from 0 below 100 
     when (even x) 
     collect x) 

言われていること、最も簡単なマクロはちょうどS式を使用します。そして、あなたはそれらを使って「つぶれている」でしょう。

しかし、セルジオのようにs式が正しいと感じ始めた。構文は途中で消え、構文木でコーディングを開始します。読者マクロについては

、はい、あなたは、おそらくこのような何か書くことができます:

#R{ 
     ruby.code.goes.here 
    } 

をしかし、あなたはあなた自身のRubyの構文パーサを書く必要があると思います。

また、既存のLisp構造にコンパイルされたマクロを使って、ブロックのようなRuby構造を模倣することもできます。

#B(some lisp (code goes here)) 

(lambda() (some lisp (code goes here))) 

に変換でしょうそれを行う方法についてはthis pageを参照してください。

+1

あなたのマクロの例は、 "s-expressionsに詰まっていません"という言葉は、私にはs式のようです。 –

+12

ループマクロの例はs-exprですが、「サブ式」はそうではありません。 –

+0

*本当に良い質問です。*しかし、stackoverflow.comではありません。それは、分析や分析が不確定な時間に沈む空洞を埋めるために、意見や宗教が忍び寄ることなく、きちんと答えることができる仕事やものではありません。 – Kaz

2

もしあなたがRubyのように見えるようにするにはRubyを使います。

それは、彼らがこんなに早く受け入れられている主な理由の一つである非常にLispのような方法でのRuby(とPython)を使用することが可能です。

1

@sparkes

時々、LISPは、明確な言語の選択肢、すなわちEmacsの拡張です。私が望むならEmacsを拡張するためにRubyを使うことができると確信していますが、EmacsはLISPで拡張されるように設計されているので、そのような状況で使うのが理にかなっています。

0

これは難しい質問です。 lispはすでに構造的にパースツリーに近いので、多数のマクロとパーサジェネレータで独自のミニ言語を実装することの違いはあまり明確ではありません。しかし、開け閉めのparenを除いて、あなたは非常に簡単にlispのように見えない何かで終わることができます。

+1

"開閉括弧を除いて" < - あなたもこれを変更することができます。 Schemeの同等のリーダーを使用してScheme(Racket)に埋め込まれた標準MLについては、http://planet.plt-scheme.org/package-source/chongkai/sml.plt/1/6/planet-docs/ml/index.htmlを参照してくださいマクロ。 – p4bl0

10

通常のマクロはオブジェクトのリストで動作します。最も一般的には、これらのオブジェクトは他のリスト(ツリーを形成する)とシンボルですが、文字列、ハッシュテーブル、ユーザー定義オブジェクトなどの他のオブジェクトでもかまいません。これらの構造はs-expsと呼ばれます。

したがって、ソースファイルを読み込むと、Lispコンパイラはテキストを解析してs-expsを生成します。マクロはこれらのマクロで動作します。これは素晴らしく、s-expsの精神の中で言語を拡張する素晴らしい方法です。

また、前述の解析処理では、あなたのコンパイラは、S-EXPSにテキストを回す方法をカスタマイズしましょう「リーダーマクロ」を通じて拡張することができます。しかし、私は、Lispの構文を他のものに変換するのではなく、Lispの構文を採用することをお勧めします。

あなたはLispの「機能的な性質」とRubyの「オブジェクト指向構文」に言及するときは、少し混乱に聞こえます。私は "オブジェクト指向の構文"は何であるかは分かりませんが、Lispはマルチパラダイム言語であり、オブジェクト指向プログラミングをサポートしていますextremelly

はところで、私はLispのを言うとき、私はCommon Lispを意味します。

あなたの偏見を避けてgive Lisp an honest goとすることをお勧めします。

15

私はLispの専門家ではありません。私はLispプログラマでもありませんが、言語を少し試した後、しばらくすると、かっこが目に見えなくなり始めますあなたが望むようにコードを見てください。あなたは、s-exprsとマクロを使って作成した構文構造にもっと注意を払い始め、リストとカッコのテキストの字句形式にはあまり注意を払いません。

これは、あなたがインデントと構文の色付け(背景と非常によく似た色に括弧を設定してみてください)に役立ちます良いエディタを利用する場合は、特別に真です。

言語を完全に置き換えずに「Ruby」構文を取得することはできませんが、必要はありません。言語の柔軟性のおかげで、もしあなたが望むなら、それがあなたにとって意味のあるものなら、あなたは「プログラミングのRubyスタイル」に従っているように感じる方言を終わらせることができます。

私はこれが単なる経験的な観察であることを知っていますが、私はこれを実現したときにLisp啓蒙の瞬間の1つを持っていたと思います。

5

はい、基本的に構文を変更したり、 "かっこの地獄"をエスケープすることもできます。そのためには、新しいリーダー構文を定義する必要があります。読者のマクロを見てください。

しかし、そのようなマクロをプログラミングするためのLisp専門知識のレベルに達するには、もはや親の「地獄」を考慮しない程度に自分自身を言語に浸しておく必要があります。私。あなたがそれらを避ける方法を知っているときには、あなたはそれらを良いものとして受け入れるようになるでしょう。

8

大文字小文字hell?

(function toto) 

:私はこれ以上括弧を見ない

function(toto); 

そして

(if tata (toto) 
    (titi) 
    (tutu)) 

で超えない

に:

if (tata) 
    toto(); 
else 
{ 
    titi(); 
    tutu(); 
} 

を私はあまりカッコを参照し、 ';'しかし、。

+0

Rubyの構文を見てください...曖昧さを取り除くために絶対に必要とされない限り、あなたは完全に括弧を削除することができます...また、機能はLisp(またはあなたが指摘しているように他の言語)のような括弧に束縛されていません –

+1

@Mike:そうです。しかし、LispとC/C++/Java/C#との比較:それほど括弧はなく、大括弧もセミコラムもありません!それは50年前、これはいつも私を驚かせる。 –

+0

インデントを使用し、括弧を必要としないlispの中に/を書くことができます。それはコードのページについてです。それはずっと変わるでしょうか?それは、彼女の外見のための妻を探すようなものです...しかし、愚かですが、多くの人がそれを行う... :) –

19

はい、Lispがコンパイラになるように構文を再定義できます。これは、おそらく考えている通常の「コンパイラマクロ」とは異なる「リーダーマクロ」を使用して行います。

Common Lispはその構文を処理するために、読者と読者マクロの新しい構文を定義するための組み込みの施設があります。この処理は読み取り時に行われます(コンパイル時間または評価時間の前に来ます)。 Common Lispでのリーダマクロの定義の詳細については、Common Lisp Hyperspecを参照してください。Ch. 2, "Syntax"Ch. 23, "Reader"としてください。 (私はSchemeが同じ施設を持っていると信じていますが、私はそれに精通していません - Arc programming languageについてはScheme sourcesを参照してください)。

簡単な例として、あなたはLispが、中括弧ではなく、括弧を使用したいとしましょう。これには、以下のような読者の定義が必要です:

;; { and } become list delimiters, along with (and). 
(set-syntax-from-char #\{ #\() 
(defun lcurly-brace-reader (stream inchar) ; this was way too easy to do. 
    (declare (ignore inchar)) 
    (read-delimited-list #\} stream t)) 
(set-macro-character #\{ #'lcurly-brace-reader) 

(set-macro-character #\} (get-macro-character #\))) 
(set-syntax-from-char #\} #\)) 

;; un-lisp -- make parens meaningless 
(set-syntax-from-char #\) #\]) ; (and) become normal braces 
(set-syntax-from-char #\(#\[) 

あなたは{がaのようなものであることをLispに伝えています。次に、読者が{が見えるときはいつでも呼び出す関数(lcurly-brace-reader)を作成し、set-macro-characterを使用してその関数を{。次に、(と)は[と]のようなものです(意味のある構文ではありません)。

他にも例えばcreating a new string syntaxや、[と]を使用して固定内表記を囲み、S式に処理することができます。

また、リーダーにアクションをトリガーする独自のマクロ文字で全体の構文を再定義する、はるかにこれ以上行くことができますので、空が本当に限界です。これはちょうどPaul GrahamothersがLispがコンパイラを書くのに良い言語であると言っている理由の1つに過ぎません。何度も

14

再び、Lispの初心者は、「すべての括弧を取り除く。」にしたいですそれは数週間続きます。プログラマーは、現在、あなたが現在 "括弧の地獄"として認識していることをいつも好みているので、通常のS式パーサの上に深刻な汎用プログラミング構文を構築するプロジェクトはどこにもありません。少し慣れていますが、それほど多くはありません!いったんそれに慣れれば、デフォルト構文の柔軟性を本当に理解できます。特定のプログラミング構造を表現する唯一の方法がある言語に戻ってみると、本当にグレーティングです。言われていること

、Lispはドメイン固有言語を構築するための優れた基質です。 XMLより優れていても、XMLと同じくらい良い。

幸運を祈る!

+0

さて、私は長い間Lispや方言を使ったことがないことを認めていますが、構文を使うのはとても快適です(とシンプルさはとても素晴らしいです)。しかし、私が使った言語。 –

+2

文法が、あなたが手元にあるプログラムを表現するのに適していると感じられるものであればどうでしょうか? – jfm3

+0

実際に、誰かがS式の上に深刻な汎用プログラミング構文を開発しました - ["Sweet-expressions"](http://www.dwheeler.com/readable/)。彼らはS式の柔軟性の利点をすべて保持しています。その拡張機能のLispに慣れ親しんだユーザは* "括弧の地獄"を好むわけではありません。しかし、甘い表情は捉えられていません。これはSweet-expressionsの作者が少数のLisp方言の構文しか実装しておらず、それらの拡張をインストールする方法についてほとんど書かれていないためだと推測します。 –

1

は、リーダマクロはXMLのテンプレートのような複雑なタスクでLispリーダを拡張する方法のこの例を参照してください。

http://common-lisp.net/project/cl-quasi-quote/present-class.html

このユーザーライブラリは、XMLの静的な部分をコンパイルUTF-8にリテラルのエンコードコンパイル時には、ネットワーク・ストリームにwrite-sequenceされる準備ができている1バイトの配列があります。通常のLispマクロでは使えますが、それらは直交しています...カンマ文字の配置は、どの部分が定数で、実行時に評価されるべきかに影響します。 http://common-lisp.net/project/cl-quasi-quote/

のCommon Lisp構文拡張のために別のプロジェクト:あなたはすべてのことは、地獄のような取り外すことができるようhttp://common-lisp.net/project/cl-syntax-sugar/

8

何を求めていることは、やや専門ショコラティエになる方法を尋ねるようなものですで利用可能

詳細あなたのお気に入りのチョコレートケーキの茶色のもの。

0

私の心を傷つけたマクロの使用の1つは、DBに対するSQL要求のコンパイル時検証でした。

コンパイル時に完全な言語を手に入れたら、興味深い新しい視点が開かれます。これはまた、興味深い新しい方法(編集をレンダリングすることが再現不可能で、非常に簡単にデバッグの悪夢に陥るなど)で自分自身を足で撃つことができることを意味します。

11

私が今まで見てきたのLispのマクロの最良の説明は、約55分で始まる

https://www.youtube.com/watch?v=4NO83wZVT0A

である。これはピーター・サイベル、「実用的な共通の著者によって与えられた話の動画ですLisp "、これは最高のLisp教科書です。

Lispマクロの動機付けは、簡単なチュートリアルで提示するには余りにも時間がかかる状況で本当に自分たちのものになるため、説明するのは難しいです。ピーターは素晴らしい例を思いついた。それを完全に把握することができ、Lispマクロを適切かつ適切に使用することができます。

あなたは「LISPの機能をよりオブジェクト指向の構文とセマンティクスに変更できますか」と尋ねました。答えは「はい」です。実際には、Lispはもともとオブジェクト指向プログラミングを全く持っていませんでした.Lispはオブジェクト指向プログラミングの前からあったので意外ではありません!しかし、1978年にOOPについて最初に学んだときには、とりわけマクロを使ってLispに簡単に追加することができました。最終的にLispにうまく収まる非常に強力なオブジェクト指向プログラミングシステムであるCommon Lisp Object System(CLOS)が開発されました。すべてが拡張機能としてロードできます - 何も組み込まれていません!それはすべてマクロで行われます。

Lispには、言語の表面構文を拡張するために使用できる「リーダーマクロ」とは全く異なる機能があります。リーダマクロを使用すると、Cのような構文やRubyのような構文を持つサブ言語を作成できます。彼らは内部的にテキストをLispに変換します。これらは、ほとんどの実際のLispプログラマーが広く使用しているわけではありません。主に、対話型開発環境を拡張して新しい構文を理解することが難しいからです。例えば、Emacsインデントコマンドは、新しい構文で混乱します。あなたが元気であれば、Emacsも拡張性があり、新しい字句構文について教えることができます。

関連する問題