2. 文芸的プログラミング
本日の話題
文芸的プログラミング
マークアップ言語
マクロプログラミング
テキスト整形システム
Scrapboxでプログラムを動かす
自分のScrapboxアカウントの用意
受講にはScrapboxのアカウントが必要
レポート提出などに利用
Googleアカウントを利用
GMailのアカウントまたはkeio.jpアカウント
Scrapbox上に自分の「プロジェクト」を作成
CNSログインID (SFCのメールアドレスのID)を利用
CNSログインIDがs12345tmの番号
sfc-pm2020-s12345tmという名前のプロジェクト
Unixターミナルの用意
Terminal.app (Mac)
WSL (Windows Subsystem for Linux)
これらが動くようにしておく
Terminal.app
/System/Applications/Utilities/Terminal.app
https://gyazo.com/9ebd4d8beb7b74e636c78d5ef0bc707d
https://gyazo.com/518a5832dab0f40e8129bcc4244c69f4
文芸的プログラミング
「Literate Programming」
1980年代にDonald Knuthが提唱
プログラムコードと解説文書を同じファイルに書く
マニュアル、ヘルプなども書いて良い
プログラムコードを文芸作品として扱う
プリティプリンティング
Literate programming 本
https://upload.wikimedia.org/wikipedia/en/6/62/Literate_Programming_book_cover.jpg
文芸的プログラミング
https://www.amazon.co.jp/dp/4756101909 https://gyazo.com/b510326c45607336aaa15e74e4052213
Donald E. Knuth
計算機科学で有名な人物
チューリング賞受賞
スタンフォード大学
様々なアルゴリズムを発明
計算機科学の著書多数
$ \TeXの作者
TeX
METAFONT
Donald E. Knuth
https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/KnuthAtOpenContentAlliance.jpg/192px-KnuthAtOpenContentAlliance.jpg
Donald E. Knuth
http://gyazo.com/9f7e6185fadd5589d903fe47cb45e4f9.png
TeX
1980年ごろKnuthが開発
マクロプログラミング言語
テキスト整形のためのマークアップ言語
code:test.tex
\def\name{増井}
My name is \name.
The TeX Book (1984)
http://gyazo.com/84e7403307e75b2f6487c832dc59e14e.png
数多くの論文が$ \TeXで書かれてきた
マクロプログラミング
「マクロプロセッサ」で文字列を置換
e.g. C言語の #define
ターミナルで実行
sample.c
code:sample.c
max(func(a),func(b))
cc -E sample.c
Cのマクロプロセッサ(cpp)を適用
code:cc
# 1 "sample.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "sample.c"
((func(a))>(func(b))?(func(a)):(func(b)))
sample.html
code:sample.html
<html>
<head>
<title>__system__について</title>
</head>
<body>
__system__というシステムについて解説します。
<br>
__system__は、2013年に...
</body>
</html>
cc -D__system__=ABC -E samplehtml.c
code:sample.c
# 1 "samplehtml.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "samplehtml.c"
<html>
<html>
<head>
<title>ABCについて</title>
</head>
<body>
ABCというシステムについて解説します。
<br>
ABCは、2013年に...
</body>
</html>
m4: 汎用のマクロプロセッサ
Software tools
Brian Kernighan氏の本
https://www.amazon.co.jp/dp/020103669X https://gyazo.com/86e65ec2faeeb2f21fe23065e69d2860
ソフトウエア作法
https://www.amazon.co.jp/dp/4320021428 https://gyazo.com/98646fc7b1e1d9f57cdcf73e68af4f5a
Brian Kernighan
“Kernighan and Ritchie” 本で有名
ベル研究所
プリンストン大学
https://gyazo.com/86bb924daea1483c1ee9e9c343e89669
Kermighan and Ritchie
https://gyazo.com/9bc29621f68c92ed34dd4e61542f52d0 https://gyazo.com/9bc29621f68c92ed34dd4e61542f52d0
カーニハン氏の新著
https://www.amazon.co.jp/dp/4822288730 https://gyazo.com/49f9a646c2249923acd4ba47c9b33fd0
m4 example (1)
code:m4.txt
% cat sample1.m4
define(name,Masui)
My name is name.
My `name' is name.
%
m4 example (2)
code:sample2.m4
define(a,100)
define(b,200)
aはbとifelse(a,b,等しい,異なる)
%
m4 example (2)
code:sampl2.m4
% cat sample2.m4
define(a,100)
define(b,200)
aはbとifelse(a,b,等しい,異なる)
%sample2.m4
100は200と異なる
%
m4 example(3)
code:sample3.m4
% cat sample3.m4
define(eq,$1は$2とifelse($1,$2,等しい,異なる))
eq(100,100)
eq(100,200)
%
m4 example (3)
code:sample3.m4
% cat sample3.m4
define(eq,$1は$2とifelse($1,$2,等しい,異なる))
eq(100,100)
eq(100,200)
% m4 sample3.m4
100は100と異なる
100は200と異なる
%
m4 example (4)
code:sample4.m4
% cat sample4.m4
define(eq2,$1は$2と`ifelse($1,$2,等しい,異なる)')
eq2(100,100)
eq2(100,200)
%
m4 example (4)
code:sample4.m4
% cat sample4.m4
define(eq2,$1は$2と`ifelse($1,$2,等しい,異なる)')
eq2(100,100)
eq2(100,200)
% m4 sample4.m4
100は100と等しい
100は200と異なる
%
m4 example (5)
code:sample5.m4
% cat sample5.m4
define(times2,`ifelse($1,$2,$3,
`times2(incr($1),$2,$3)$3')')
define(times,`times2(1,$1,$2)')
times(4,`<br>')
%
m4 example (5)
code:sample5.m4
% cat sample5.m4
define(times2,`ifelse($1,$2,$3,
`times2(incr($1),$2,$3)$3')')
define(times,`times2(1,$1,$2)')
times(4,`<br>')
% sample5.m4
<br><br><br><br>
%
m4を使ってみる
Unixのシェルでm4 コマンドを使う
Macの "Terminal.app" を使う
% m4
動かない場合は % brew install m4
何かテキストを入力して改行を入力
define(a,1) と入力してからaと入力
マークアップ言語
テキスト中に整形指令を書く
TeX, HTML, etc.
特殊なタグを利用
<b>text</b>
\bf{text}
The TeX Book (1984)
http://gyazo.com/84e7403307e75b2f6487c832dc59e14e.png
TeX の例
code:sample1.tex
% cat sample1.tex
Hello, world!
\end
% tex sample1.tex
This is TeX, Version 3.141592 (Web2C 7.5.4)
Output written on sample1.dvi (1 page, 228 bytes).
Transcript written on sample1.log.
%
生成されたPDF
https://gyazo.com/6308eb57737babf793e9c06f42c2b7d0
マクロ利用の例
code:sample2.tex
% cat sample2.tex
\def\name{Masui}
Hello, \name!
\end
% tex sample2.tex
This is TeX, Version 3.141592 (Web2C 7.5.4)
Output written on sample2.dvi (1 page, 224 bytes).
Transcript written on sample2.log.
%
生成されたPDF
https://gyazo.com/67c9f11132a18de1ea8823f7ee5b8c6e
整形指令の例
code:sample3.tex
% cat sample3.tex
This is \TeX.
\par
\centerline{$-b \pm \sqrt{b^2 - 4ac} \over 2a
\par
\font\helv=Helvetica scaled \magstep 5 \relax
\helv
This is \TeX.
\end
%
生成されたPDF
http://gyazo.com/a16220b1db81c22585964bf2ace15803.png
LaTeXの例
code:sample4.tex
% cat sample4.tex
\documentclass{article}
\begin{document}
\LARGE
abcde
\begin{quotation}
quoted string
\end{quotation}
\end{document}
% latex sample4
This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4)
entering extended mode
(./sample4.tex
...
Output written on sample4.dvi (1 page, 292 bytes).
Transcript written on sample4.log.
%
生成されたPDF
https://gyazo.com/33a42df4f5acd1804843ca8b7970205c
TeXの練習
サンプルTeXファイル
code:sample.tex
\documentclass{article}
\begin{document}
\LARGE
abcde
\begin{quotation}
quoted string
\end{quotation}
\end{document}
TeX実行
% tex sample.tex
% dvipdfm sample
% open sample.pdf
その他のマークアップ言語
Scribe
roff
RTF
HTML
MarkDown
1980年代はCMU(カーネギーメロン大学)で広く利用されていた
論文、テクニカルレポートなど
現在はほぼ絶滅状態
http://gyazo.com/6febaa039e718d9d3cf4941c73d7909b.png
Scribe表記
http://gyazo.com/2e9f49c5d0530b4d33576a9b1dfb4e12.png
Scribe表記
http://gyazo.com/038e5a90cac8236632cb23f5cee3f15f.png
Scribeの名残り
BibTeX 表記
code:sample.bibtex
@BOOK{Lamport:LaTeX,
AUTHOR = "Leslie Lamport",
TITLE = "LaTeX User's Guide and Document Reference Manual",
PUBLISHER = "Addison-Wesley Publishing Company",
ADDRESS = "Reading, Massachusetts",
YEAR = "1986" }
Brian Reid vs Google事件
IPO(上場)寸前にクビにされたらしい
Roff / Runoff
Unixで利用されている(いた)テキスト整形システム
マニュアル記述では現在も現役
nroff, troff
/usr/share/man/man1/man.1
code:man.1
.SH DESCRIPTION
.B man
formats and displays the on-line manual pages. If you specify
.IR section ,
.B man
only looks in that section of the manual.
.I name
is normally the name of the manual page, which is typically the name
of a command, function, or file.
However, if
.I name
contains a slash
.RB ( / )
then
.B man
interprets it as a file specification, so that you can do
.B "man ./foo.5"
or even
.B "man /cd/foo/bar.1.gz\fR.\fP"
.PP
Troff 実行
% groff -man man.1 > man.ps
http://gyazo.com/32cab038afc431a0ea7f65af650f06a2.png
RTF (Rich Text Format)
Wordなどで利用できるテキスト整形記述
TeXに表記が類似
人間が読むのは困難
code:sample.rtf
{\rtf1\ansi\ansicpg932\cocoartf949\cocoasubrtf430
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\paperw11900\paperh16840\margl1440\margr1440\vieww9000\viewh8400\viewkind0
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102
\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\f0\i\fs50 \cf0 abc}
HTML
HyperText Markup Language
現在世界で最も広く利用されている
Markdown
HTMLの簡易記法
近年エンジニアに人気
GitHubなどで利用されている
<h1>abc</h1> のかわりに# abc と書ける
https://gyazo.com/8a9c46863a1c6bef25cd8764dbe64b5a
リンクや画像を貼るのは大変
Donald Knuthが作成したフォント定義システム
「ペン」の移動でフォントを記述
アウトラインでの記述も可能
METAFONT記述例
http://gyazo.com/bdbfdd820ea582d55c427c46209375f8.png
code:sample.metafont
beginchar(65,10pt#,10pt#,0pt#);
pickup pencircle xscaled 1.2pt yscaled 0.5pt rotated 120;
z1=(0.1w,0.75h);
z2-z1=whatever*(8,1);
x2=0.9w;
z3=(0.8w,0.1h);
draw z1--z2{z1-z2}..{z2-z1}z3;
labels(1,2,3);
endchar;
end.
METAFONTの現状
ほぼ利用者なし
日本語フォントが存在しない
研究されていたこともあったがうまくいかなかった
フォントの歴史
フォント会社が配布
ビットマップフォント
アウトラインフォント
これらの組み合わせ
アンチエイリアシング
ClearType
文芸的プログラミングの思想
プログラムコードと文書を統合
すべてまとめて文書とする
WEB: Knuthによる文芸的プログラミングシステム
Weave: 文書をTeXファイルに変換
索引、目次なども自動生成
Tangle: 文書からプログラムコードを抽出
WeaveとTangle
https://gyazo.com/95535222ca0d8a2185279b902c0755b8
The TeX Book (1984)
http://gyazo.com/84e7403307e75b2f6487c832dc59e14e.png
文芸的プログラミングのメリット
ソースコードの記述場所が柔軟
言語処理系による制約がなくなる
文書とコードが常に一致する
内容が違っていると気持ち悪いはずだから
文書を書くことはコードだけ書くより満足感ある
WEB文書に含まれるべきテキスト
ソースコード
アルゴリズム解説
文書に含まれるべきもの
ソースコード
アルゴリズム解説
作者情報
作成時刻
バージョン番号
ライセンス
テスト環境
ビルド環境
ヘルプ文書
各種動画
ソースコード至上主義
すべてはソースコードに書かれているはず
ソースコードが適切に記述されていれば文書など要らない
ソースコード至上主義の問題点
コードだけからは理解できないものも多い
図が欲しいことも多い
これは何?
code:root.rb
v = 3.141592
100.times {
v = (v + 2.0/v) / 2.0
}
puts v
これは何?
code:sample.rb
v = 3.141592
100.times {
v = (v + 2.0/v) / 2.0
}
puts v
$ \sqrt{2}を計算するアルゴリズムだった!
これは何?
code:shift.c
int foo(int b)
{
int n;
n = (b >> 1) & 03333333333;
n = b - n - ((n >> 1) & 03333333333);
n = ((n + (n >> 3)) & 0707070707) % 077;
return n;
}
code:what.c
int foo(int b)
{
int n;
n = (b >> 1) & 03333333333;
n = b - n - ((n >> 1) & 03333333333);
n = ((n + (n >> 3)) & 0707070707) % 077;
return n;
}
2進数の1の数を数えるプログラム
e.g. foo(10) = $ foo_2(1010) = 2
プログラム中で図を利用したい
状態遷移図
幾何的な問題
GUIプログラミング
プリティプリンティング
プログラムを格好良く表示
いろいろなフォント/字体/色を使う
http://cdn-ak.f.st-hatena.com/images/fotolife/m/metanest/20141014/20141014123812.png
プリティプリンティング
美しい出力
読みやすい
最近何故か流行らない
誰もコードを印刷しない?
人々がCourierフォントが好き?
sample.web
code:sample.web
\centerline{\bf Hello World}
\vskip .5cm
This is a very simple example of the WEB system.
@ First, we define a text to be displayed.
@<Content to print@>=
'Hello, Literate Programming!'
@ This is the mainprogram of the Pascal program.
An expression surrounded by $\langle$ and $\rangle$
is substituted by its definition.
@p
Program HelloWorld(output);
begin
@<Do something inside a program@>
end.
@ You can define an identifier after reference in WEB language.
@<Do something inside a program@>=
writeLn( @<Content to print@> )
Weaveを適用
TeXファイルが生成される
code:sample.tex
\input webmac
\centerline{\bf Hello World}
\vskip .5cm
This is a very simple example of the WEB system.
\M1. First, we define a text to be displayed.
\Y\P$\4\X1:Content to print\X\S$\6
\.{\'Hello,\ Literate\ Programming!\'}\par
\U3.\fi
\M2. This is the mainprogram of the Pascal program.
An expression surrounded by $\langle$ and $\rangle$
is substituted by its definition.
\Y\P$\\{Program}\\{HelloWorld}(\\{output})$;\6
\&{begin} \37\X3:Do something inside a program\X\6
\&{end}.\par
\fi
\M3. You can define an identifier after reference in WEB language.
\Y\P$\4\X3:Do something inside a program\X\S$\6
$\\{writeLn}(\X1:Content to print\X)$\par
\U2.\fi
\inx
\:\\{HelloWorld}, 2.
\:\\{output}, 2.
\:\\{Program}, 2.
\:\\{writeLn}, 3.
\fin
\:\X1:Content to print\X
\U3.
\:\X3:Do something inside a program\X
\U2.
\con
生成された文書
http://gyazo.com/eb861108fe4d51892b5f3d665a24be47.png
Tangleの適用
sample.p が生成される
行番号はもともとのものが利用される
code:sample.p
{2:}Program HelloWorld(output);
begin{3:}writeLn({1:}'Hello, Literate Programming!'{:1}){:3}end.{:2}
WEBの問題点
TeXの限界
e.g. 図を表示しにくい
プログラム言語の制約
TeXとPascalの組み合わせのみ
Cが利用できるものもある
解決法
WEBでなくHTMLを利用
任意の言語を利用可能に
WEBえなくHTMLを利用
wtangle コマンドでプログラムを抽出
https://gyazo.com/50dbf12646b15a68b88928c407aa7ea7
Simple WEBのソース
code:test.web
<h3>初期化処理</h3>
<a href="#prologue"><code>prologue()</code></a>では変数の初期化などを行なう。
<code>%SIG<code>に関数名を指定しておくと、
signalが発生したときに<code>$SIG{シグナル名}</code>の関数が呼ばれる。
ここではSIGINTなどを受け取った時に
<a href="#finish"><;code>finish()</code></a>が呼ばれるようにしている。
<a name="prologue"></a>
<pre file=wtangle>
sub prologue {
require 'cacheout.pl'; # <a name=cacheout>複数ファイル出力ライブラリ</a>
if($#ARGV < 0){
print STDERR "wtangle --- Web Tangle\n";
print STDERR "Usage: wtangle documentfiles\n";
exit 0;
}
$SIG{'INT'} = $SIG{'TERM'} =
$SIG{'QUIT'} = $SIG{'HUP'} = 'finish';
}
</pre>
<h3>メインルーチン</h3>
Simple WEBの機能
Weaveが不要
HTMLベースなので公開が簡単
文芸的プログラミングの問題点
便利さが足りない
デバッグ中に文書を編集したりしない
デバッグが終了した後で文書は書かない
意識の高さが必要
Wikiベースの文芸的プログラミング
どこでもプログラミング
様々な情報をリンク
画像や動画の利用
複数人の協調
世界発のWiki
300行のPerlコード
Wikiの上にWikiプログラムが記述されていた
Wiki Wiki
https://cdn-ak.f.st-hatena.com/images/fotolife/n/nakamura_bokushi/20111029/20111029143521.jpg
GyazzというWiki上に記述
http://gyazo.com/310d6680c8c2dbdff5d86ed33d12eaaf.png
ソースコードとその他のリソース
http://gyazz.com/HelloIME/ http://gyazo.com/79ff4a880b0ca1b3ae2fc92bfb2146ab.png
Scrapbox上でのプログラミング
Scrapboxページの上でプログラムを記述
Scrapboxでプログラミングしたい?
https://gyazo.com/665de6321c943a060d5c9586bd6df908
平方根を計算
$ \sqrt{2}を計算
code:sqrt.js
v = 3.141592; // dummy initial value
for(var i=0;i<100;i++){
v = (v + 2.0/v) / 2.0;
}
alert(v);
ランダムウォーク
code:random.js
setup = function(){
posx = 200, posy = 200
createCanvas(400, 400)
strokeWeight(0)
}
draw = function(){
fill('yellow')
rect(0,0,400,400)
posx += random(-2,2)
posy += random(-2,2)
fill('blue')
rect(posx,posy,4,4)
}
ランダム値を加算
code:randomadd.js
function setup(){
createCanvas(400,400)
histogram = []
for(i=0;i<100;i++) histogrami = 0 strokeWeight(0)
}
function draw(){
val = 0
for(i=0;i<10;i++) val += random(1/10)
fill('yellow')
rect(0,0,400,400)
fill('blue')
for(i=0;i<100;i++)
rect(i*4,400-histogrami,4,histogrami) }
どういう方針が良いか?
説明や図を書く
その後でコードを書く
c.f. 論文を書いてからシステムを作るという流儀