コンテンツにスキップ

英文维基 | 中文维基 | 日文维基 | 草榴社区

「メタプログラミング」の版間の差分

出典: フリー百科事典『ウィキペディア(Wikipedia)』
削除された内容 追加された内容
編集の要約なし
編集の要約なし
2行目: 2行目:
{{プログラミング・パラダイム}}
{{プログラミング・パラダイム}}


'''メタプログラミング'''(''Metaprogramming'')とは、自己反映性のプログラムロジックを操作して、コードまたはデータ定義情報の変容による再帰的かつ帰納的なプログラムの自己修正を表現するためのプログラミング技法である。そのプログラムロジックは[[形而上学|形而上的]]要素になぞらえられて実装面では[[メタデータ]]と呼ばれる。プログラムの自己修正はランタイム時とコンパイル時に大別される。ランタイム時の方はプログラム開始時の動作制約を越えた実行プロセスの最適化を目的にしており[[機械学習]]にも似た性質を持つ。コンパイル時の方は[[ソースコード]]の記述量削減と[[オブジェクトコード]]の最適化を目的にしている。ランタイム時メタの実装方式には[[動的型付け]]向けのメタオブジェクトと[[静的型付け]]向けの[[リフレクション (情報工学)|リフレクション]]がある。コンパイル時メタの実装方式には[[マクロ (コンピュータ用語)|マクロ]]と[[テンプレートメタプログラミング]]がある。[[自動プログラミング]]、{{仮リンク|属性指向プログラミング|en|Attribute-oriented programming|label=}}{{仮リンク|多段階プログラミング|en|Multi-stage programming|label=}}といったスタイルも存在する。メタプログラミングの原点は「[[LISP]]」であり[[人工知能]]研究とも関係性がある。
'''メタプログラミング'''(''Metaprogramming'')とは、自己反映性のプログラムロジックを操作して、コードまたはデータ定義情報の変容による再帰的なプログラムの自己修正と、帰納的なプログラムの自己検証を表現するためのプログラミング技法である。そのプログラムロジックは[[形而上学|形而上的]]要素になぞらえられて実装面では[[メタデータ]]と呼ばれる。プログラムの自己修正および自己検証はランタイム時とコンパイル時に大別される。ランタイム時メタの方はプログラム開始時の動作制約を越えた実行プロセスの最適化を目的にしており[[機械学習]]にも似た性質を持つ。コンパイル時メタの方は[[ソースコード]]の記述量削減と[[オブジェクトコード]]の最適化を目的にしている。ランタイム時メタの実装方式にはメタオブジェクトと[[リフレクション (情報工学)|リフレクティブプログラミ]]がある。コンパイル時メタの実装方式には[[マクロ (コンピュータ用語)|マクロ]]と[[テンプレートメタプログラミング]]がある。[[自動プログラミング]]、{{仮リンク|属性指向プログラミング|en|Attribute-oriented programming|label=}}{{仮リンク|多段階プログラミング|en|Multi-stage programming|label=}}といったスタイルも存在する。メタプログラミングの原点は「[[LISP]]」であり[[人工知能]]研究とも関係性がある。


== LISPのメタプログラミング ==
== 概要 ==
代表的なメタプログラミングの例は[[LISP]]のマクロである。LISPではデータ、コードが全て[[S式]]で表現されるが、マクロによりS式が言語処理系に解釈される前に別なS式へと変換することができる。これにより例えば、
代表的なメタプログラミングの例は[[LISP]]のマクロである。LISPではデータ、コードが全て[[S式]]で表現されるが、マクロによりS式が言語処理系に解釈される前に別なS式へと変換することができる。これにより例えば、
(defstruct point (x 0) (y 0))
(defstruct point (x 0) (y 0))
25行目: 25行目:
このことは、Lispのマクロが、'''上のかぎ括弧「」で括った言語仕様を変更し、独自の文法を作り上げた'''とも考えられる。しかし、この文法は、通常のLispにおいて期待されるような構成をしていない「記述どおりでない動作を行うプログラム」の一例であり、コードの可読性を損なう恐れのある不必要なメタプログラミングである。
このことは、Lispのマクロが、'''上のかぎ括弧「」で括った言語仕様を変更し、独自の文法を作り上げた'''とも考えられる。しかし、この文法は、通常のLispにおいて期待されるような構成をしていない「記述どおりでない動作を行うプログラム」の一例であり、コードの可読性を損なう恐れのある不必要なメタプログラミングである。


== マクロ ==

== リフレクティブプログラミング ==

== テンプレートメタプログラミング ==
メタプログラミングの他の例としては[[C++]]における「[[テンプレートメタプログラミング]]」などが挙げられる。
メタプログラミングの他の例としては[[C++]]における「[[テンプレートメタプログラミング]]」などが挙げられる。

== メタオブジェクト ==

== 代表的なメタプログラミング採用言語 ==

*[[LISP]]
*[[REBOL]]
* [[クワイン (プログラミング)]]


== 脚注 ==
== 脚注 ==
31行目: 44行目:


== 関連項目 ==
== 関連項目 ==
* [[LISP]]
* [[REBOL]]
* [[クワイン (プログラミング)]]
* [[ドメイン固有言語]] - メタプログラミングにより構築することもできる。
* [[ドメイン固有言語]] - メタプログラミングにより構築することもできる。
* [[部分評価]]
* [[部分評価]]

2021年2月24日 (水) 06:31時点における版

メタプログラミングMetaprogramming)とは、自己反映性のプログラムロジックを操作して、コードまたはデータ定義情報の変容による再帰的なプログラムの自己修正と、帰納的なプログラムの自己検証を表現するためのプログラミング技法である。そのプログラムロジックは形而上的要素になぞらえられて実装面ではメタデータと呼ばれる。プログラムの自己修正および自己検証はランタイム時とコンパイル時に大別される。ランタイム時メタの方はプログラム開始時の動作制約を越えた実行プロセスの最適化を目的にしており機械学習にも似た性質を持つ。コンパイル時メタの方はソースコードの記述量削減とオブジェクトコードの最適化を目的にしている。ランタイム時メタの実装方式にはメタオブジェクトとリフレクティブプログラミングがある。コンパイル時メタの実装方式にはマクロテンプレートメタプログラミングがある。自動プログラミング属性指向プログラミング英語版多段階プログラミング英語版といったスタイルも存在する。メタプログラミングの原点は「LISP」であり人工知能研究とも関係性がある。

LISPのメタプログラミング

代表的なメタプログラミングの例は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")

を用いた例[1]を紹介する。LispのS式がLispフォームになるためには、「S式の最初の要素は(関数、マクロ、特殊フォーム)のいずれかではならない。」しかし、

(defmacro backwards (expr) (reverse expr))

を定義すると、以下のように書ける:

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

このことは、Lispのマクロが、上のかぎ括弧「」で括った言語仕様を変更し、独自の文法を作り上げたとも考えられる。しかし、この文法は、通常のLispにおいて期待されるような構成をしていない「記述どおりでない動作を行うプログラム」の一例であり、コードの可読性を損なう恐れのある不必要なメタプログラミングである。

マクロ

リフレクティブプログラミング

テンプレートメタプログラミング

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

メタオブジェクト

代表的なメタプログラミング採用言語

脚注

  1. ^ Peter Siebel: Practical Common Lisp 第三章の8から引用

関連項目