style - naming conventions java




メタプログラミング-自己説明的なコード-チュートリアル、記事、書籍 (5)

私はプログラミングスキルを向上させることに目を向けています(実際に私はジェフアトウッドが書いたように、毎年少なくなるように努力しています)ので、私はメタプログラミングと自己説明的なコードについて読むことを考えていました。

私はこれに馬鹿のガイドのようなものを探しています(ダウンロードのための無料の書籍、オンラインリソース)。 また、私はあなたの平均的なwikiページと、言語にとらわれないもの、あるいはJavaの例を用いることが望ましい。

あなたは、そのすべてを効率的に実践できるようなリソースを知っていますか?経験はたくさんありますが、流れの悪い決定を回避するエクスペリエンスを作りたいと思っています。

編集:

Pragmatic Programmerのこの例のようなもの:

...単純な図面パッケージを制御するミニ言語を実装する...言語は一文字のコマンドで構成されています。 いくつかのコマンドの後には、単一の番号が続きます。 たとえば、次の入力は四角形を描画します。

P 2 # select pen 2
D # pen down
W 2 # draw west 2cm
N 1 # then north 1
E 2 # then east 2
S 1 # then back south
U # pen up

ありがとうございました!


Tclは、ジェネリックプログラミング機能を必要とするところまで複雑になってきたため、ドメイン特有の言語を作成する方法としてはじまりました。 さらに、それは言語の重要なユースケースなので、あなた自身のコマンドを正確に追加するのは非常に簡単です。

Javaと統合された実装を希望するJaclJaclはJava Tcl 実装しており、DSLに焦点を当てたスクリプト性を提供し、Javaオブジェクトへのアクセスにもアクセスします。

(メタプログラミングはプログラムを書くプログラムですが、いくつかの言語は他の言語よりもはるかに優れています。実行時にスクリプトを許可するスクリプト言語はすべて、メタプログラミングがより柔軟になるように記述されているため、メタプログラミングが容易になる傾向があります。



さて、Javaエコシステムでは、ミニ言語を実装する最も簡単な方法は、 GroovyRubyようなスクリプト言語を使うことです(RubyはJavaエコシステムのネイティブな市民ではありません)。 どちらも、DSL仕様メカニズムを提供しています。これにより、Java言語よりもはるかに単純なものにすることができます。

しかし、純粋なJavaのラテラネイティブがありますが、実装するのが少し難しくなると思います。


メタプログラミングについてのPluralsightに関するコースがあります。これは、良いエントリーポイントになるかもしれません。https://app.pluralsight.com/library/courses/understanding-metaprogramming/table-of-contents


上記の私のコメントでは、C ++テンプレートのメタプログラミングについて触れました。 したがって、C ++テンプレートのメタプログラミングを使用した簡単な例を提供しましょう。 私はあなたがあなたの質問をjavaでタグ付けしたことを知っていますが、これは洞察力があるかもしれません。 私はあなたがC ++コードを理解できることを願っています。

例によるデモンストレーション:

フィボナッチ系列 (0,1,2,3,5,8,13、...)を生成する次の再帰関数を考えてみましょう。

unsigned int fib(unsigned int n)
{
    return n >= 2 ? fib(n-2) + fib(n-1) : n;
}

フィボナッチシリーズから項目を取得するには、この関数、たとえばfib(5)を呼び出し、値を計算して返します。 今のところ特別なものはありません。

しかし、C ++では、テンプレートを使ってこのコードを書き直すことができます(Javaのジェネリックに似ています)ので、フィボナッチシリーズは実行時には生成されませんが、 コンパイル 時に生成されます

// fib(n) := fib(n-2) + fib(n-1)
template <unsigned int n>
struct fib                     // <-- this is the generic version fib<n>
{
    static const unsigned int value = fib<n-2>::value + fib<n-1>::value;
};

// fib(0) := 0
template <>
struct fib<0>                  // <-- this overrides the generic fib<n> for n = 0
{
    static const unsigned int value = 0;
};

// fib(1) := 1
template <>
struct fib<1>                  // <-- this overrides the generic fib<n> for n = 1
{
    static const unsigned int value = 1;
};

このテンプレートを使用してフィボナッチシリーズからアイテムを取得するには、単純にfib<5>::valueの定数値を取得しfib<5>::value

結論(「メタプログラミングとは何が関係していますか?」):

テンプレートの例では、実行中のプログラムではなく、コンパイル時にFibonacciシリーズを生成するのはC ++コンパイラです。 (これは最初の例では関数を呼び出しているが、テンプレートの例では定数値を取得していることから明らかです)フィボナッチ数を計算する関数を書かずにフィボナッチ数を取得します。 その関数をプログラミングする代わりに、コンパイラが明示的に設計されていないことをあなたに向けてプログラムしました。これは非常に顕著です。

したがって、これはメタプログラミングの一形態です:

メタプログラミングは、他のプログラム(またはそれ自身)をそのデータとして書き込むか、または操作するコンピュータプログラムの書き込みであり、そうでなければ実行時に実行されるコンパイル時の作業の一部である

- 私が追加Metaprogramming定義。

(上記のテンプレートの例の副作用にも注意してください:コンパイラがあなたのフィボナッチ数をあらかじめ計算するようになると、どこかに格納する必要があります。プログラムのバイナリのサイズは、 fib<n>::valueという用語。実行時に計算時間を節約できます。





coding-style