24

C ++はおそらく静的メタプログラミングで最も人気のある言語であり、Javaはそれをサポートしていません

生成プログラミング(プログラムを作成するプログラム)をサポートするC ++以外の言語はありますか?

4

15 に答える 15

33

テンプレートスタイルのメタプログラミングに代わるものは、さまざまなLisp実装で見られるマクロスタイルです。JVM上で実行されるマクロを備えたLispに興味がある場合は、PaulGrahamのOnLispをダウンロードし、Clojureも確認することを勧めします

LispのマクロはC/C ++スタイルよりもはるかに強力であり、それ自体が言語を構成します。メタプログラミングを目的としています。

于 2008-09-22T18:36:56.487 に答える
25

メタプログラミングがlisp(またはschemeslate、またはお気に入りの「動的」言語を選択)でどのように機能するかについて、いくつかの重要な詳細をリストします。

  • lispでメタプログラミングを行う場合、2つの言語を扱う必要はありません。メタレベルのコードは、生成されるオブジェクトレベルのコードと同じ言語で記述されています。メタプログラミングは2つのレベルに限定されるものではなく、脳にとっても簡単です。
  • lispでは、実行時にコンパイラを利用できます。実際、コンパイル時と実行時の区別は非常に人工的なものであり、視点をどこに置くかによって大きく異なります。単なる関数呼び出しを伴うlispでは、関数をコンパイルして、それ以降、ファーストクラスのオブジェクトとして使用できるマシン命令を作成できます。つまり、ローカル変数やグローバルハッシュテーブルなどに保持できる無名関数にすることができます。
  • lispのマクロは非常に単純です。ハッシュテーブルに詰め込まれ、コンパイラに渡される一連の関数です。コンパイラがコンパイルしようとしているフォームごとに、そのハッシュテーブルを参照します。関数が見つかった場合は、コンパイル時に元のフォームを使用して呼び出し、元のフォームの代わりに、この関数が返すフォームをコンパイルします。(いくつかの重要でない詳細を法として)したがって、lispマクロは基本的にコンパイラのプラグインです
  • lispコードを評価するlisp関数をlispで書くことは、約2ページのコードです(これは通常evalと呼ばれます)。このような関数では、メタレベルで必要な新しいルールを導入するためのすべての権限があります。(ただし、高速で実行するには、ある程度の努力が必要です...新しい言語のブートストラップとほぼ同じです... :)

lispメタプログラミングを使用してユーザーライブラリとして実装できるもののランダムな例(これらは一般的なlispライブラリの実際の例です):

  • 区切られた継続で言語を拡張する(hu.dwim.delico)
  • javascript(lispから生成される)で使用できるjs-to-lisp-rpcマクロを実装します。js / lispコードの混合に拡張され、参照されているすべてのローカル変数を自動的に(httpリクエストで)投稿し、サーバー側でデコードし、サーバーでlispコード本体を実行し、戻り値をjavascriptに返します。側。
  • 「通常の」lispコードと非常にシームレスに統合する言語にバックトラックのようなプロローグを追加します(screamerを参照)
  • Common lispへのXMLテンプレート拡張( lispパーサーのプラグインであるリーダーマクロの例を含む)
  • ループのような小さなDSLのトン、またはループを簡単にするための反復
于 2008-09-23T10:45:41.990 に答える
14

テンプレートメタプログラミングは、本質的にテンプレートメカニズムの乱用です。私が言いたいのは、基本的に、計画外の副作用であった機能から期待するものが得られるということです---それは混乱であり、(ツールは良くなっていますが)言語がないのでお尻の本当の痛みですそれを行う際にあなたをサポートします(私は本質的にアプローチをあきらめたので、これに関する最先端の私の経験は時代遅れであることに注意する必要があります。しかし、大きな進歩は聞いたことがありません)

'98年頃にこれをいじって、より良い解決策を探すようになりました。私はそれに依存する便利なシステムを書くことができましたが、それらは地獄でした。突っついた結果、私はCommonLispにたどり着きました。確かに、テンプレートメカニズムはチューリング完全ですが、インターカルも完全です。

CommonLispはメタプログラミングを「正しく」行います。あなたはそれをしている間利用可能な言語の全力を持っており、特別な構文はありません、そして言語は非常に動的であるため、あなたはそれでより多くをすることができます。

もちろん他のオプションもあります。私が使用した他の言語は、Lispよりも優れたメタプログラミングを実行しません。そのため、私はそれを研究コードに使用しています。他のことを試してみたいと思う理由はたくさんありますが、それはすべてトレードオフになります。Haskell / ML / OCamlなどを見ることができます。多くの関数型言語には、Lispマクロの力に近いものがあります。.NETをターゲットにしたものをいくつか見つけることができますが、それらはすべて(ユーザーベースなどの点で)かなり限界的です。工業的に使用されている言語の大手企業のどれも、実際にはこのようなものを持っていません。

于 2008-09-22T19:49:04.627 に答える
12

NemerleBooは、そのようなものの私の個人的なお気に入りです。Nemerleは、ドキュメントが不十分であるにもかかわらず、非常に洗練されたマクロ構文を備えています。Booのドキュメントは優れていますが、そのマクロは少しエレガントではありません。ただし、どちらも非常にうまく機能します。

どちらも.NETを対象としているため、C#や他の.NET言語、さらにはIKVMを使用している場合はJavaバイナリと簡単に相互運用できます。

編集:明確にするために、私はCのプリプロセッサマクロではなく、Lispという言葉の意味でのマクロを意味します。これらにより、コンパイル時に新しい構文と大量のメタプログラミングを定義できます。たとえば、Nemerleには、コンパイル時にSQLサーバーに対してSQLクエリを検証するマクロが付属しています。

于 2008-09-22T18:37:08.917 に答える
10

Nim は比較的新しいプログラミング言語で、静的メタプログラミングを幅広くサポートし、効率的な (C++ のような) コンパイル済みコードを生成します。

http://nim-lang.org/

コンパイル時の関数評価、マクロによる Lisp のような AST コード変換、コンパイル時のリフレクション、任意の値でパラメーター化できるジェネリック型、およびユーザー定義の高レベルの型認識を作成するために使用できる項の書き換えをサポートします。のぞき穴の最適化。コード生成に影響を与える可能性のあるコンパイル プロセス中に、外部プログラムを実行することさえ可能です。例として、コード内の ORM 定義 (一部の DSL を介して提供される) がデータベースのスキーマと一致することを確認するために、ローカルで実行されているデータベース サーバーと対話することを検討してください。

于 2015-07-28T14:01:48.817 に答える
6

D」プログラミング言語はC++に似ていますが、メタプログラミングのサポートがはるかに優れています。コンパイル時のメタプログラミングのみを使用して記述されたレイトレーサーの例を次に示します。

Ctrace

さらに、C ++ではサポートされていない(少なくともまだ)メタプログラミング構造をサポートする「ConceptGCC」と呼ばれるgccブランチがあります。

コンセプトGCC

于 2008-09-22T19:22:40.867 に答える
5

Common Lisp は、いくつかの異なる方法でプログラムを作成するプログラムをサポートしています。

1) プログラムのデータとプログラムの「抽象構文木」が統一されている (S 式!)

2)defmacro

3) リーダー マクロ。

4) モップ

これらのうち、本当の驚異的なのは MOP です。「メタオブジェクト プロトコルの技術」を読んでください。それはあなたのために物事を変えるでしょう、私は約束します!

于 2008-09-23T17:51:53.557 に答える
4

Haskellをお勧めします。これは、コンパイル時のメタプログラミング機能について説明した論文です。

于 2008-09-22T18:38:04.487 に答える
3

Haskell での多くの作業: ドメイン固有言語 (DSL)、実行可能仕様、プログラム変換、部分適用、段階的計算。開始するためのいくつかのリンク:

于 2008-11-19T08:01:28.773 に答える
2

「メタプログラミング」は、少なくとも複数の言語について話し合っている場合は、この特定の機能の悪い名前です。この機能は、次のような言語の狭い範囲でのみ必要になるためです。

  • 静的
  • 機械語にコンパイル
  • コンパイル時のパフォーマンスを大幅に最適化
  • ユーザー定義のデータ型で拡張可能(C ++の場合はOOP)
  • 非常に人気があります

これらのいずれかを取り出してください。「静的メタプログラミング」は意味がありません。したがって、C ++で理解されているように、リモートで主流の言語にそのようなものがあるとしたら、私は驚きます。

もちろん、動的言語といくつかの関数型言語は、メタプログラミングとも呼ばれるまったく異なる概念をサポートしています。

于 2008-09-22T19:29:56.420 に答える
2

ほとんどの人は、自己検査のための「究極の反映」と、新しいコードを具体化するための「評価」のような言語を見つけようとします。そのような言語は見つけるのが難しく(LISPが主な反例です)、確かに主流ではありません。

しかし、別のアプローチは、プログラムコードを検査、生成、および操作できる一連のツールを使用することです。Jackpotは、Javaに焦点を当てたツールです。http://jackpot.netbeans.org/

当社のDMSソフトウェアリエンジニアリングツールキットは、C、C ++、C#、Java、COBOL、PHP、Javascript、Ada、Verilog、VHDL、およびその他のさまざまな言語で動作するツールです。(本番品質のフロントエンドを使用して、これらすべての言語を読み取れるようにします)。より良いことに、それは同時に複数の言語でこれを行うことができます。http://www.semdesigns.com/Products/DMS/DMSToolkit.htmlを参照してください

DMSは、ASTとしてプログラム構造に完全にアクセスするための通常の方法とサポートインフラストラクチャを提供し、ほとんどの場合、高度なプログラム操作を行うために必要なシンボルテーブル、タイプ情報、制御、データフロー分析などの追加データを提供するため成功します。

于 2009-06-14T04:48:17.497 に答える
2

MLファミリーの言語は、この目的のために特別に設計されました。OCamlの最も有名なサクセスストーリーの1つは、OCamlプログラムによってほぼ完全に生成されたCコードである高性能FFT用のFFTWライブラリです。

乾杯、ジョン・ハロップ。

于 2008-10-19T10:03:50.737 に答える
1

もちろん、メタ言語(ML):http: //cs.anu.edu.au/student/comp8033/ml.html

于 2008-09-22T19:33:44.493 に答える
1

Lispは「メタプログラミング」の形式をサポートしていますが、C++テンプレートメタプログラミングと同じ意味ではありません。また、「静的」という用語は、このコンテキストでは異なる意味を持つ可能性がありますが、Lispは静的型付けもサポートしています(それが意味する場合)。

于 2008-09-22T18:36:43.833 に答える