
リテラトプログラミング(LP)は、 1984年にドナルド・クヌースによって導入されたプログラミングパラダイムであり、コンピュータプログラムは、その動作を英語などの自然言語で説明され、マクロのスニペットと従来のソースコードが点在(埋め込まれ)ており、そこからコンパイル可能なソースコードが生成されます。[1]このアプローチは、再現可能な研究やオープンアクセスの目的で、科学計算やデータサイエンスの分野で日常的に使用されています。[2]現在、リテラトプログラミングツールは、何百万人ものプログラマーによって使用されています。[3]
ドナルド・クヌースが考案した文芸的プログラミングパラダイムは、コンパイラによって強制される方法と順序でコンピュータプログラムを記述することから離れ、代わりにプログラマーにマクロを提供し、ロジックと思考の流れによって要求される順序でプログラムを開発できるようにするものです。[4]文芸的プログラムは、マクロを使用して抽象化と従来のソースコードを隠す、より自然な言語でのロジックの説明として記述され、エッセイの本文のようになります。
文芸的プログラミングツールは、ソースファイルから2つの表現を取得するために使用されます。1つはコンパイラまたはインタープリタが理解できる「絡み合った」コードであり、もう1つはフォーマットされたドキュメントとして表示するためのもので、文芸的ソースから「織り込まれた」ものと言われています。[5]第一世代の文芸的プログラミングツールはコンピュータ言語に固有でしたが、後期のツールは言語に依存せず、個々のプログラミング言語を超えて存在します。
リテラティブプログラミングは、1984年にドナルド・クヌースによって初めて提唱されました。彼は、人間にとって適切な文学的プログラムを作成することを意図していました。彼はスタンフォード大学で、アルゴリズムとデジタルタイポグラフィの研究の一環として、この実装を実装しました。この実装は「 WEB 」と名付けられました。これは、彼がまだコンピューティングに応用されていなかった数少ない3文字の英語の単語の1つであると信じていたためです。[6]しかし、それは単純な材料から繊細に組み立てられたソフトウェアの複雑な性質に似ています。[1]リテラティブプログラミングの実践は、特にデータサイエンスにおいて、計算ノートブックの使用により、2010年代に重要な復活を遂げました。
文芸的プログラミングとは、プログラムロジックを人間の言語で記述し、コードスニペットとマクロを(プリミティブなマークアップで区切って)組み込むことです。文芸的ソースファイル内のマクロは、人間の言語で書かれたタイトルのような、あるいは説明的なフレーズであり、プログラミング上の問題を解決する際に生み出される人間の抽象概念を記述し、コードチャンクや低レベルのマクロを隠蔽します。これらのマクロは、コンピュータサイエンスの教育で一般的に用いられる擬似コードのアルゴリズムに似ています。これらの任意の説明フレーズは、プログラマーによって即座に作成される正確な新しい演算子となり、基盤となるプログラミング言語の上にメタ言語を形成します。
プリプロセッサは、任意の階層構造、あるいはむしろ「マクロの相互接続された『ウェブ』」[7]を置き換え、 1つのコマンド(「タングル」)でコンパイル可能なソースコードを作成し、別のコマンド(「ウィーブ」)でドキュメントを作成するために使用されます。プリプロセッサはまた、マクロの内容を書き出す機能や、文芸的プログラムソースファイルのテキスト内の任意の場所に既に作成されたマクロを追加する機能も提供します。これにより、従来のプログラミング言語による制約を念頭に置く必要がなくなり、思考の流れを中断する必要がなくなります。
クヌース[8] [9]によれば、 文芸的プログラミングは、プログラマーにプログラムの背後にある思考を明示的に述べることを強いるため、考え抜かれていない設計上の決定がより明白になり、より高品質なプログラムを生み出す。クヌースはまた、文芸的プログラミングは一流のドキュメンテーションシステムを提供すると主張している。これはアドオンではなく、プログラム作成中に思考を表明する過程で自然に成長するものである。[10]結果として得られるドキュメンテーションにより、作成者は後からいつでも自分の思考プロセスを再開することができ、他のプログラマーはプログラムの構成をより容易に理解することができる。これは、コンパイラが課した順序に従ったソースコードを提示され、コードとそれに関連するコメントからプログラムの背後にある思考プロセスを解読しなければならない従来のドキュメンテーションとは異なる。文芸的プログラミングのメタ言語機能は、思考を容易にし、コードをより俯瞰的に捉え、脳が記憶し処理できる概念の数を増やすとも主張されている。この概念が大規模なプログラミング、つまり商用レベルのプログラムに適用できることは、TeXコードを文芸プログラムとして編集することで証明されている。[8]
クヌースはまた、文芸的プログラミングによってソフトウェアを複数の環境に簡単に移植できるようになると主張し、TeXの実装を例として挙げている。[11]
リテラティブプログラミングは、ソースコードとコメントの両方を含む共通ファイルから生成されるフォーマットされたドキュメント(正しくはドキュメント生成)や、コードに含まれる膨大なコメントのみを指すと誤解されることが非常に多い[12]。これはリテラティブプログラミングの逆である。適切にドキュメント化されたコード、あるいはコードから抽出されたドキュメントは、コードの構造に従い、ドキュメントはコードに埋め込まれる。一方、リテラティブプログラミングでは、コードはドキュメントに埋め込まれ、コードはドキュメントの構造に従う。
この誤解から、 Perl Plain Old DocumentationやJavaの Javadocシステムといったコメント抽出ツールは「文芸的プログラミングツール」であるという主張が生まれています。しかし、これらのツールは自然言語マクロシステムの背後に隠れた「抽象概念の網」を実装しておらず、ソースコードの順序を機械が強制する順序から人間の思考にとって都合の良い順序に変更する機能も提供していないため、クヌースが意図した意味での文芸的プログラミングツールと呼ぶのは適切ではありません。[12] [13]
リテラルプログラミングの実装は、次の 2 つのステップで構成されます。
織りと絡みは、互いに一貫性を保つために同じソースで行われます。
リテラティブプログラミングの典型的な例として、標準的なUnix 単語カウントプログラムのリテラティブ実装が挙げられますwc。Knuthは、著書『リテラティブプログラミング』の第12章で、この例のCWEB版を発表しました。この例は後に、nowebというリテラティブプログラミングツール用に書き直されました。[14]この例は、リテラティブプログラミングの基本要素をよく表しています。
以下のwc文芸プログラム[14]の断片は、自然言語の任意の記述句が文芸プログラムにおいてどのように用いられ、マクロを作成するかを示しています。マクロは文芸プログラミング言語において新たな「演算子」として機能し、コードチャンクや他のマクロを隠蔽します。マークアップ記法は、<<...>>マクロを示す二重山括弧( )で構成されています。noweb@ファイルでは、記号 はドキュメントチャンクの開始を示します。記号 は<<*>>「ルート」、つまり文芸プログラミングツールがマクロのウェブ展開を開始する最上位ノードを表します。実際には、展開されたソースコードの書き出しは、任意のセクションまたはサブセクション(つまり<<name of the chunk>>=、等号で と指定されたコード片)から行うことができます。そのため、1つの文芸プログラムファイルに、マシンソースコードを含む複数のファイルを含めることができます。
wcの目的は、ファイルリスト内の行数、単語数、文字数をカウントすることです。ファイル内の行数は........ /続きは説明/
次に、nowebプログラムwc . nwによって定義されるファイルwc . cの概要を示します。<< * >> = <<インクルードするヘッダーファイル>> <<定義>> <<グローバル変数>> <<関数>> <<メインプログラム>> @
フォーマットされた出力をstdoutとstderrに送信するため、標準I / O定義をインクルードする必要があります。<<インクルードするヘッダーファイル>> = #include <stdio.h> @
チャンクの展開は、文芸的プログラム テキスト ファイル内の任意の場所で実行できます。必ずしも、囲んでいるチャンク内での順序どおりではなく、プログラム全体を囲む説明テキストに反映されたロジックによって要求される順序で実行できます。
マクロは、標準的なドキュメントにおける「セクション名」とは異なります。文芸プログラミングのマクロは、その背後に実際のコードを隠蔽し、低水準機械語演算子、特にif、while、 などの論理演算子内で使用できますcase。これは、以下のwc文芸プログラムに示されています。[14]
カウントを行う現在のチャンクは、実のところ最も簡単に記述できるものの一つです。各文字を見て、それが単語の始まりか終わりかを判断し、状態を変更します。
<<ファイルをスキャン>>= while ( 1 ) { <<バッファが空の場合はバッファを埋める;ファイルの終わりで中断する>> c = * ptr ++ ; if ( c > ' ' && c < 0177 ) { /* 表示可能な ASCII コード */ if ( ! in_word ) { word_count ++ ; in_word = 1 ; } continue ; } if ( c == '\n' ) line_count ++ ; else if ( c != ' ' && c != '\t' ) continue ; in_word = 0 ; /* c は改行、スペース、またはタブ */ } @
マクロはコードの塊や他のマクロを表し、トップダウンやボトムアップの「チャンキング」やサブセクション化よりも汎用的です。ドナルド・クヌースは、このことに気づいたとき、プログラムを様々なパーツの網として考えるようになったと述べています。[1]
noweb 対応プログラムでは、マクロの背後にあるチャンクは、その説明順序が自由であることに加え、 で導入されると<<...>>=、次のスニペットが示すように、単に内容を記述して追加するだけで、ファイル内の任意の場所で拡張できます<<name of the chunk>>=(+はドキュメントフォーマッタによって読みやすくするために追加されており、コード内には はありません)。[14]
プログラムの開始時に総計をゼロに初期化する必要があります。
これらの変数をmainにローカルにした場合、この初期化を行う必要があります。
明示的にはゼロに設定されますが、Cのグローバル変数は自動的にゼロに設定されます。(というか、「静的に
ゼロになりました。(分かりますか?)
<<グローバル変数>>+=
long tot_word_count, tot_line_count,
合計文字数;
/* total number of words, lines, chars */
@
リテラティブ・プログラムのドキュメントは、プログラム作成の一環として作成されます。ソースコードの補足として提供されるコメントの代わりに、リテラティブ・プログラムには各レベルの概念の説明が含まれており、低レベルの概念は適切な場所に委ねられています。これにより、思考をより効果的に伝達できます。上記のリテラティブ・プログラムのスニペットは、プログラムの説明とソースコードがどのように織り交ぜられているかを示しています。このようなアイデアの展開は、文学作品のような思考の流れを生み出します。クヌースは、インタラクティブ・フィクション・ゲーム「Colossal Cave Adventure」wcのコードを解説した「小説」を執筆しました。[15]
最初に公開された文芸的プログラミング環境はWEBであり、1981年にKnuthがTeX組版システム用に導入した。WEBは基礎となるプログラミング言語としてPascalを使用し、ドキュメントの組版にはTeXを使用している。コメント付きの完全なTeXソースコードは、Knuthの著書『 Computers and Typesetting 』全5巻の第2巻『TeX: The program』で公開されている。Knuthは1979年という早い時期にDOCと呼ばれる文芸的プログラミングシステムを使用していた。彼はピエール=アルヌール・ド・マルネフのアイデアに触発された。[16] KnuthとSilvio Levyが作成した無料のCWEBは、 CとC++に適合したWEBであり、ほとんどのオペレーティングシステムで実行でき、TeXとPDFのドキュメントを生成できる。
文芸的プログラミングの概念には、以下に示すように様々な実装があります。これらの新しいものの多くはマクロを備えておらず、人間の論理的順序の原則に準拠していないため、「半文芸的」ツールと言えるかもしれません。しかし、これらのツールはコードのセル実行を可能にするため、探索的プログラミングツールに近いと言えます。
その他の便利なツールは次のとおりです。
.hsは.lhs文芸的Haskellを表します。
リテラル スクリプトは完全な LaTeX ソース テキストであると同時に、変更を加えることなくコンパイルできます。これは、インタープリターがコード環境でテキストをコンパイルするだけだからです。次に例を示します。
% ここで関数を説明するテキスト:
\begin { code }
fact 0 = 1 fact ( n + 1 ) = ( n + 1 ) * fact n \end { code }
続きはこちら
コードは、リチャード バード スタイルでマークすることもできます。つまり、各行の先頭に大なり記号とスペースを入れ、コードの前後に空白行を入れます。
LaTeXパッケージは、ソースコードを装飾するために使用できる環境をlistings提供します。この環境を使用して、Haskell内でシンボルを次のように印刷するための環境を定義できます。
lstlistingcode
\newenvironment {コード}{ \lstlistings [言語=Haskell] }{ \endlstlistings }
\begin {コード}
comp :: (ベータ->ガンマ) -> (アルファ->ベータ) -> (アルファ->ガンマ) ( g ` comp ` f ) x = g ( f x ) \end {コード}
これは次のように設定できます:
トップダウンとボトムアップは、どちらか一方がプログラムの説明に適しており、もう一方がプログラムの作成に適しているという、相反する手法だと考えていました。しかし、WEBの経験を積むうちに、トップダウンとボトムアップのどちらかを一概に決める必要はないことに気づきました。プログラムはツリーではなくウェブとして捉えるのが最適だからです。階層構造は存在しますが、プログラムにおいて最も重要なのは、その構造的な関係性です。複雑なソフトウェアは、単純なパーツとパーツ間の単純な関係性で構成されています。プログラマーの役割は、それらのパーツと関係性を、トップダウンやボトムアップといった厳密に決められた順序ではなく、人間の理解に最適な順序で記述することです。
— ドナルド・E・クヌース、リテラシープログラミング[1]
WEBのマクロは最大1つのパラメータしか持てません。繰り返しますが、これは簡潔さを優先するためです。複数のパラメータを使うほとんどの応用は、実際には1つのパラメータに簡略化できることに気づいたからです。例えば、[例を省略] ... のようなマクロを定義したいとします。つまり、あるマクロの名前を別のマクロのパラメータとして利用できるのです。
— ドナルド・E・クヌース、リテラシープログラミング[1]
TeX
プロジェクトから生まれた最も重要な成果であることは間違いありません
。リテラテ・プログラミングは、プログラムをこれまで以上に高速かつ確実に作成・保守することを可能にし、1980年代以来、私の最大の喜びの一つとなってきただけでなく、時にはなくてはならない存在でもありました。MMIXメタシミュレータのような私の主要なプログラムのいくつかは、私がこれまで聞いたことのある他のいかなる手法でも決して書けなかったでしょう。その複雑さは、私の限られた脳では到底扱えませんでした。リテラテ・プログラミングがなければ、このプロジェクト全体が惨めに失敗していたでしょう。…リテラテ・プログラミングは、並外れた達成レベルを超越するために必要なものです。
WEBを使い始めてから気づいたもう一つの驚くべきことは、従来のプログラミング言語を使うと、自分が何をしているのか気づいていなかったにもかかわらず、質の低いプログラムを書いてしまうことに気付いたことです。当初、WEBは単なるドキュメント作成ツールとして考えていましたが、実際にはWEBで書いたプログラムの方が他の言語で書いたプログラムよりも優れていることに気づきました。
— ドナルド・E・クヌース、リテラシープログラミング[1]
このように、WEB言語はプログラムを「意識の流れ」の順序で表現することを可能にします。TANGLEは、PASCALコンパイラが要求する構成にすべてを組み込むことができます。WEBのこの機能はおそらく最大の強みでしょう。WEBで書かれたプログラムは、PASCALだけで書かれた同じプログラムよりもはるかに読みやすくなります。たとえ後者のプログラムに適切なコメントが付けられていたとしてもです。そして、プログラマーが大規模なプログラムを心理的に正しい順序で探索できるウェブとして捉えることができるようになったため、トップダウンかボトムアップかという問題にこだわる必要がなくなったという事実は、私が最近の経験から得た最大の教訓と言えるでしょう。
— ドナルド・E・クヌース、リテラシープログラミング[1]
WEBという名前を選んだのは、それが当時まだコンピューターに使われていなかった数少ない3文字の英語の一つだったからという理由もあります。しかし、時が経つにつれ、この名前に非常に満足するようになりました。複雑なソフトウェアは、単純な素材を繊細に組み合わせた網として捉えるのが最も適切だと考えているからです。複雑なシステムを理解するには、その単純な構成要素を理解し、それらの構成要素と隣接する構成要素との単純な関係を理解する必要があります。プログラムをアイデアの網として表現すれば、その構造的特性を自然かつ納得のいく形で強調することができます。
— ドナルド・E・クヌース、リテラシープログラミング[1]