web-dev-qa-db-ja.com

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

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

#define if while 

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

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

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

それらは有害であると考えられていますか?

8
OscarRyz

言語にマクロがある場合、それらは十分に計画されたlanguageの不可欠な部分であり、compilerの重要な部分ではないはずだと私は考えています。

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

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

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

15
Berin Loritsch

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

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

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

8
Larry Coleman

一部の言語でサポートされていない理由は特にないと思います。大文字と小文字が区別されるものとサポートされていないものがあります。通常、本当の理由はなく、ただ決定されただけです。

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

#define X Y

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

2
Mike M.