プログラミング言語でのマクロサポートは有害と見なされますか?


8

Cで私の頭に浮かぶ最初の乱用は:

#define if while 

しかし同時に、正しく使用すると非常に便利で強力です。

Common Lispマクロでも同様のことが起こります。

すべてのプログラミング言語がこのようなマクロをサポートしていないのはなぜですか?

彼らは有害だと考えられていますか?


20
ナイフは危険です。別の方法は、スプーンで物を切ることです。
Matt Ellen


1
@Mattまたは適切なハンドルを提供します。
OscarRyz 2010

回答:


15

言語にマクロがある場合、それらは十分に計画され、コンパイラーではなく言語の不可欠な部分である必要があると私は考えています。

たとえば、Lispのマクロシステムは非常に強力な統合言語機能であり、Lisp自体のすべての規則と規制の対象となります。

反例として、C / C ++マクロシステムは言語から分離されており、コンパイラに組み込まれています。その結果、言語の制約に限定されず、無効なコードが作成され、言語固有のキーワードが再定義される可能性があります。

結局のところ、マクロ機能を持たない言語がいくつかありますが、それらの機能はそれほど見逃されていません。それはすべて、言語がどれほど表現力豊かであり、メタプログラミングへの代替アプローチがあるかどうかに依存します。メタプログラミングは、Xを実行するときに、アプリケーション全体でXが同じ方法で実行されるようにするための方法にすぎません。


4
さらに悪いことに、Cプリプロセッサはコンパイラの一部でさえありません。

1
ここで描き出そうとしている「言語」と「コンパイラ」の違いは何ですか?Cのマクロシステムは言語標準で定義されており、Lispのマクロは実際にはLispコンパイラーによって拡張されており、すべての言語実装は、コンパイラと標準ライブラリによって定義されています。したがって、「言語から分離されてコンパイラに組み込まれている」という句は無意味です。おそらく、あなたが探している違いは、Cマクロがコンパイラのフロントエンドに実装されており、Lispマクロがバックエンドに実装されていることですか?
メイソンウィーラー

区別は言語の一貫性に関係しています。このように考えて、あなたは外国に行く計画を立てており、あなたはフランス語を話して場所に行って食べ物を買うことを学ぶ必要があります。税関を扱うときは、スウェーデン語を学ぶか、フランス語だけを扱う必要があります。Cプリコンパイラマクロは、標準のCと構文的にも文法的にも異なります。認識の課題は、他の言語が標準のCプログラムに対して何を行うかを理解することです。簡単な場合もありますが、コードフレーズ全体をマクロ定義と見なしました。それをデバッグします。
Berin Loritsch 2015

8

CマクロとLispマクロは完全に異なります。Cマクロは、他の処理が行われる前に、文字列置換を使用して展開されます。Lispマクロは、入力テキストが構文ツリー1に解析された後に展開され、展開中に言語全体を使用できます。Lispマクロを使用すると、のような愚かなことを実行できるだけでなく#define begin {、独自の制御構造を定義したり、コンパイル時に、必要なコードを使用して配列にデータを追加したりすることもできます。

マクロを含めない理由の1つは、Cスタイルの構文を使用する言語では、単純な文字列置換よりも複雑なものを扱うのが非常に難しい場合があるためです。マクロに関するもう1つの不満は、マクロがコードを読みにくくする可能性があることです。これは、上手に実装されない場合に当てはまります。よく書かれたLispマクロは実際にコードを読みやすくすることができます。

1構文を作成するプロセス中に展開される読み取りマクロを除きます。


2

一部の言語でサポートされていない特定の理由があるとは思いません。大文字と小文字が区別される場合とそうでない場合があるのと同じです。通常、本当の理由はなく、行われた決定だけです。

しかし、それらが確実に含まれていない理由は、セキュリティではありません。の

#define X Y

ステートメントは、コンパイル時にすべてのXをYに変更します。#defineステートメントを変更できる場合は、変更したいソースをコピー/置換して、再度コンパイルします。

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