(Translated by https://www.hiragana.jp/)
メタプログラミング - Wikipedia コンテンツにスキップ

メタプログラミング

出典しゅってん: フリー百科ひゃっか事典じてん『ウィキペディア(Wikipedia)』

メタプログラミング (英語えいご: metaprogramming) [注釈ちゅうしゃく 1]とはプログラミング技法ぎほう一種いっしゅで、一般いっぱんに「プログラム記述きじゅつするプログラム」をくこと、またはそのプログラムを[1]対象たいしょう言語げんごまれたマクロ言語げんごによっておこなわれることもある。

概要がいよう[編集へんしゅう]

一般いっぱんに、スクリプト言語げんごはメタプログラミングが得意とくいだとされている。コンパイルがた言語げんご実行じっこうまえソースコード一括いっかつ変換へんかんするという特性とくせいじょう翻訳ほんやく実行じっこうかえすスクリプト言語げんごよりも実行じっこうみや変換へんかん自由じゆうひく[2]

代表だいひょうてきなメタプログラミングのれいLispのマクロである。Lispはデータ、コードがすべSしき表現ひょうげんされるが、マクロによりSしき言語げんご処理しょりけい解釈かいしゃくされるまえべつなSしきへと変換へんかんすることができる。これによりたとえば、

(defstruct point (x 0) (y 0))

という記述きじゅつから

  • 構造こうぞうたい定義ていぎ pointがた
  • コンストラクタ make-point (省略しょうりゃく初期しょきは0, 0)
  • アクセサ point-x point-y
  • 複製ふくせい copy-point
  • 述語じゅつご point-p

自動的じどうてき生成せいせいされる。

これがメタプログラミングとばれるのは、「自動じどう生成せいせい言語げんごみの機能きのうではなくLispのマクロによって記述きじゅつされており、必要ひつようなら同様どうよう機構きこうをプログラマが定義ていぎできる」ためである。これは事実じじつじょう言語げんご文法ぶんぽう拡張かくちょうひとしく、非常ひじょう強力きょうりょくなプログラム能力のうりょくることになる。反面はんめん、マクロは任意にんい字句じくえが可能かのうであるため、展開てんかいされたコードが言語げんご文法ぶんぽうから逸脱いつだつする可能かのうせいがあることを意味いみしている。そのため一般いっぱん必要ひつようでないメタプログラミングはけられるべきとされる。

たとえば、文字もじれつ整形せいけいして出力しゅつりょくするformat関数かんすう

(format t "hello,world")

もちいたれい[3]紹介しょうかいする。LispのSしきがLispフォームになるためには、「Sしき最初さいしょ要素ようそは(関数かんすう、マクロ、特殊とくしゅフォーム)のいずれかではならない。」しかし、

(defmacro backwards (expr) (reverse expr))

定義ていぎすると、以下いかのようにける:

(backwards ("hello,world" t format))

このことは、Lispのマクロが、うえのかぎ括弧かっこ「」でくくった言語げんご仕様しよう変更へんこうし、独自どくじ文法ぶんぽうつくげたともかんがえられる。しかし、この文法ぶんぽうは、通常つうじょうのLispにおいて期待きたいされるような構成こうせいをしていない「記述きじゅつどおりでない動作どうさおこなうプログラム」のいちれいであり、コードの可読かどくせいそこなうおそれのある必要ひつようなメタプログラミングである。

メタプログラミングのほかれいとしてはC++における「テンプレートメタプログラミング」などがげられる。

危険きけんせい[編集へんしゅう]

ただ、メタプログラミングが強力きょうりょく手段しゅだんである以上いじょう、それにともな危険きけんせい理解りかいしておかねばならない。

つぎJavaScriptにおけるメタプログラミングのれいである。

const add = new Function(..."xy", "return x + y");

add(2, 3); // => 5

このれいでは、文字もじれつから関数かんすうadd生成せいせいしたうえで、その関数かんすう利用りようして計算けいさんおこなっている[注釈ちゅうしゃく 2]

ただ、このような野放図のほうず使つかかたをすると、Functionコンストラクタあたえる引数ひきすうあいだちがえただけで破壊はかいてきかつ致命ちめいてき結果けっかこす場合ばあいがある。

そこでJavaScriptでは、「既存きそん機能きのう拡張かくちょうする」ことに注力ちゅうりょくした、

  • Proxy
  • Reflect

というオブジェクトを提供ていきょうしている[4]。このように、目的もくてきありきの手段しゅだんとして使用しようすることにより、危険きけんせい最小限さいしょうげんにまでおさえながらつよみを最大さいだいすることができる。

脚注きゃくちゅう[編集へんしゅう]

出典しゅってん[編集へんしゅう]

  1. ^ あんどうやすし 2020, p. 343.
  2. ^ あんどうやすし 2020, pp. 343–344.
  3. ^ Seibel, Peter (2005ねん4がつ11にち). “Practical Common Lisp”. Internet Archive. p. 95. 2023ねん12月11にち閲覧えつらん
  4. ^ あんどうやすし 2020, p. 345-346.

註釈ちゅうしゃく[編集へんしゅう]

  1. ^ "meta-"は「高次こうじ」、「ちょう」をあらわ接頭せっとう
  2. ^ ただのれいであって、推奨すいしょうされないかたであるてん十分じゅうぶん留意りゅうい

参考さんこう文献ぶんけん[編集へんしゅう]

  • あんどうやすし「メタプログラミングをまなぶ」『ハンズオンJavaScript』(初版しょはん)オライリー・ジャパン、東京とうきょう、2020ねん11月13にちISBN 978-4-87311-922-9 

関連かんれん項目こうもく[編集へんしゅう]