Monorepo for Aesthetic.Computer
aesthetic.computer
1% !TEX program = xelatex
2\documentclass[10pt,letterpaper,twocolumn]{article}
3
4% === GEOMETRY ===
5\usepackage[top=0.75in, bottom=0.75in, left=0.75in, right=0.75in]{geometry}
6
7% === FONTS ===
8\usepackage{fontspec}
9\usepackage{unicode-math}
10\usepackage{xeCJK}
11\setCJKmainfont{Droid Sans Japanese}
12\setmainfont{Latin Modern Roman}
13\setsansfont{Latin Modern Sans}
14\setmonofont{Latin Modern Mono}[Scale=0.85]
15\newfontfamily\acbold{ywft-processing-bold}[
16 Path=../../system/public/type/webfonts/,
17 Extension=.ttf
18]
19\newfontfamily\aclight{ywft-processing-light}[
20 Path=../../system/public/type/webfonts/,
21 Extension=.ttf
22]
23
24% === PACKAGES ===
25\usepackage{xcolor}
26\usepackage{titlesec}
27\usepackage{enumitem}
28\usepackage{booktabs}
29\usepackage{tabularx}
30\usepackage{fancyhdr}
31\usepackage{hyperref}
32\usepackage{graphicx}
33\usepackage{ragged2e}
34\usepackage{listings}
35\usepackage{natbib}
36\usepackage[colorspec=0.92]{draftwatermark}
37
38% === COLORS ===
39\definecolor{acpink}{RGB}{180,72,135}
40\definecolor{acpurple}{RGB}{120,80,180}
41\definecolor{acdark}{RGB}{64,56,74}
42\definecolor{acgray}{RGB}{119,119,119}
43\definecolor{draftcolor}{RGB}{180,72,135}
44
45% === DRAFT WATERMARK ===
46\DraftwatermarkOptions{
47 text=WORKING DRAFT,
48 fontsize=3cm,
49 color=draftcolor!18,
50 angle=45,
51 pos={0.5\paperwidth, 0.5\paperheight}
52}
53
54% === JS SYNTAX COLORS ===
55\definecolor{jskw}{RGB}{119,51,170}
56\definecolor{jsfn}{RGB}{0,136,170}
57\definecolor{jsstr}{RGB}{170,120,0}
58\definecolor{jsnum}{RGB}{204,0,102}
59\definecolor{jscmt}{RGB}{102,102,102}
60
61% === PROCESSING SYNTAX COLORS ===
62\definecolor{pjkw}{RGB}{204,102,0}
63\definecolor{pjfn}{RGB}{0,102,153}
64\definecolor{pjcmt}{RGB}{102,102,102}
65
66% === HYPERREF ===
67\hypersetup{
68 colorlinks=true,
69 linkcolor=acpurple,
70 urlcolor=acpurple,
71 citecolor=acpurple,
72 pdfauthor={@jeffrey},
73 pdftitle={setup()からboot()へ:ピースAPIの核心におけるProcessingの継承},
74}
75
76% === SECTION FORMATTING ===
77\titleformat{\section}
78 {\normalfont\bfseries\normalsize\uppercase}
79 {\thesection.}
80 {0.5em}
81 {}
82\titlespacing{\section}{0pt}{1.2em}{0.3em}
83
84\titleformat{\subsection}
85 {\normalfont\bfseries\small}
86 {\thesubsection}
87 {0.5em}
88 {}
89\titlespacing{\subsection}{0pt}{0.8em}{0.2em}
90
91\titleformat{\subsubsection}
92 {\normalfont\itshape\small}
93 {\thesubsubsection}
94 {0.5em}
95 {}
96\titlespacing{\subsubsection}{0pt}{0.6em}{0.1em}
97
98% === HEADER/FOOTER ===
99\pagestyle{fancy}
100\fancyhf{}
101\renewcommand{\headrulewidth}{0pt}
102\fancyhead[C]{\footnotesize\color{draftcolor}\textit{作業草稿 --- 引用不可}}
103\fancyfoot[C]{\footnotesize\thepage}
104
105% === LIST SETTINGS ===
106\setlist[itemize]{nosep, leftmargin=1.2em, itemsep=0.1em}
107\setlist[enumerate]{nosep, leftmargin=1.2em}
108
109% === COLUMN SEPARATION ===
110\setlength{\columnsep}{1.8em}
111
112% === PARAGRAPH SETTINGS ===
113\setlength{\parindent}{1em}
114\setlength{\parskip}{0.3em}
115
116% Hyphenation for narrow two-column layout
117\tolerance=800
118\emergencystretch=1em
119\hyphenpenalty=50
120
121% === LISTINGS ===
122\lstdefinelanguage{processing}{
123 morekeywords=[1]{void,int,float,boolean,color,String,class,new,if,else,for,while,return,public,private,extends,import},
124 morekeywords=[2]{setup,draw,mousePressed,mouseDragged,keyPressed,size,background,stroke,noStroke,fill,noFill,line,rect,ellipse,point,triangle,beginShape,endShape,vertex,translate,rotate,scale,pushMatrix,popMatrix,frameRate,width,height,mouseX,mouseY,pmouseX,pmouseY,key,keyCode,mouseButton,frameCount},
125 sensitive=true,
126 morecomment=[l]{//},
127 morecomment=[s]{/*}{*/},
128 morestring=[b]",
129}
130
131\lstdefinelanguage{p5js}{
132 morekeywords=[1]{function,let,const,var,if,else,for,while,return,new,class,export},
133 morekeywords=[2]{setup,draw,mousePressed,mouseDragged,keyPressed,createCanvas,background,stroke,noStroke,fill,noFill,line,rect,ellipse,point,triangle,beginShape,endShape,vertex,translate,rotate,scale,push,pop,frameRate,width,height,mouseX,mouseY,pmouseX,pmouseY,key,keyCode,mouseButton,frameCount,createGraphics,random,noise,map,constrain,dist,lerp},
134 sensitive=true,
135 morecomment=[l]{//},
136 morestring=[b]",
137 morestring=[b]',
138 morestring=[b]`,
139}
140
141\lstdefinelanguage{acjs}{
142 morekeywords=[1]{function,export,const,let,var,return,if,else,new,async,await,import,from,for},
143 morekeywords=[2]{wipe,ink,line,box,circle,write,screen,params,colon,jump,send,store,net,sound,speaker,pen,event,boot,paint,act,sim,leave,paste,plot,poly,flood,form,cursor,handle,num,geo,ui},
144 sensitive=true,
145 morecomment=[l]{//},
146 morestring=[b]",
147 morestring=[b]',
148 morestring=[b]`,
149}
150
151\lstdefinestyle{processingstyle}{
152 language=processing,
153 keywordstyle=[1]\color{pjkw}\bfseries,
154 keywordstyle=[2]\color{pjfn}\bfseries,
155 commentstyle=\color{pjcmt}\itshape,
156 stringstyle=\color{jsstr},
157}
158
159\lstdefinestyle{p5style}{
160 language=p5js,
161 keywordstyle=[1]\color{jskw}\bfseries,
162 keywordstyle=[2]\color{pjfn}\bfseries,
163 commentstyle=\color{jscmt}\itshape,
164 stringstyle=\color{jsstr},
165}
166
167\lstdefinestyle{acjsstyle}{
168 language=acjs,
169 keywordstyle=[1]\color{jskw}\bfseries,
170 keywordstyle=[2]\color{jsfn}\bfseries,
171 commentstyle=\color{jscmt}\itshape,
172 stringstyle=\color{jsstr},
173}
174
175\lstset{
176 basicstyle=\ttfamily\small,
177 breaklines=true,
178 frame=single,
179 rulecolor=\color{acgray!30},
180 backgroundcolor=\color{acgray!5},
181 xleftmargin=0.5em,
182 xrightmargin=0.5em,
183 aboveskip=0.5em,
184 belowskip=0.5em,
185 numbers=none,
186 tabsize=2,
187}
188
189\newcommand{\acdot}{{\color{acpink}.}}
190\newcommand{\ac}{\textsc{Aesthetic.Computer}}
191
192\begin{document}
193
194% ============ TITLE BLOCK ============
195
196\twocolumn[{%
197\begin{center}
198{\acbold\fontsize{22pt}{26pt}\selectfont\color{acdark} \texttt{setup()} から \texttt{boot()} へ}\par
199\vspace{0.2em}
200{\aclight\fontsize{11pt}{13pt}\selectfont\color{acpink} ピースAPIの核心におけるProcessingの継承}\par
201\vspace{0.6em}
202{\normalsize @jeffrey}\par
203{\small\color{acgray} Aesthetic.Computer}\par
204{\small\color{acgray} ORCID: \href{https://orcid.org/0009-0007-4460-4913}{0009-0007-4460-4913}}\par
205\vspace{0.3em}
206{\small\color{acpurple} \url{https://aesthetic.computer}}\par
207\vspace{0.6em}
208\rule{\textwidth}{1.5pt}
209\vspace{0.5em}
210\end{center}
211
212\begin{center}
213{\small\color{draftcolor}\textbf{[ 作業草稿 --- 引用不可 ]}}
214\end{center}
215\vspace{0.3em}
216
217\begin{quote}
218\small\noindent\textbf{概要。}
219すべてのクリエイティブコーディングプラットフォームはコアAPIを定義する——プログラムが世界を感知し、その上に描画するための基本関数のセットである。Processingは2001年に\texttt{setup()}/\texttt{draw()}とグローバル描画プリミティブ(\texttt{background()}、\texttt{stroke()}、\texttt{ellipse()})によるパターンを確立し、このパターンは20年にわたるクリエイティブコーディングツールに影響を与えた。p5.jsは2014年にこのモデルをブラウザに持ち込み、JavaScriptとDOMに適応させながらAPIサーフェスを維持した。\ac{}(AC)は2021年に開始され、その核心においてProcessingの思想を継承しつつ、複数の構造的次元で拡張している:2関数ライフサイクルを5つ(\texttt{boot}、\texttt{paint}、\texttt{act}、\texttt{sim}、\texttt{leave})に拡張し、グローバル状態をデストラクチャリングによるAPI注入に置き換え、シミュレーションとレンダリングを異なる周波数で分離し、各プログラムをビルドステップなしでURLアドレス可能にしている。本稿では、Processingの理念がACピースAPIにどのように存在しているかを追跡し、Design By Numbers、Processing、p5.js、ACのライフサイクルモデル、描画プリミティブ、入力処理、状態管理戦略を比較する。ACのAPI設計——Processingの即時モードグラフィックスモデルを基盤として——が\emph{スケッチブック}の比喩(書く、実行する、捨てる)を\emph{楽器}の比喩(起動する、演奏する、練習する、戻る)へと拡張することを論じる。
220\end{quote}
221\vspace{0.5em}
222}]
223
224% ============ 1. INTRODUCTION ============
225
226\section{はじめに}
227
228クリエイティブコーディングAPIの歴史は、プログラマーが最初に何を言うべきかを決定する歴史である。Design By Numbers~\citep{maeda2001dbn}では、最初のステートメントは座標とグレースケール値だった:\texttt{Paper 50}。Processing~\citep{reas2003processing}では、\texttt{setup()}内の\texttt{size(200, 200)}だった。p5.js~\citep{mccarthy2015p5js}では、\texttt{createCanvas(400, 400)}だった。\ac{}では、プログラマーはキャンバスを宣言する必要が一切ない——ランタイムが\texttt{screen.width}と\texttt{screen.height}を既成事実として提供し、最初の意味のあるステートメントは通常\texttt{wipe()}——描画を開始するための画面クリア——である。
229
230これらは恣意的な違いではない。それぞれがプラットフォームの前提とプログラマーが指定すべきものとの間の決定を反映しており、これらの決定が蓄積されることで、著者とマシンの間に根本的に異なる関係が形成される。本稿ではProcessingからp5.jsを経てACへのAPI系譜を追跡し、各遷移を一連の設計決定として捉える:何が保持され、何が変更され、その変更が何を意味するか。
231
232本稿の貢献は3つある:(1)Processing、p5.js、ACのライフサイクルモデル、描画API、入力システム、状態管理戦略の詳細な技術比較、(2)ACがProcessingモデルから逸脱した背景にある設計思想の分析、(3)ACピースAPIがスケッチブックの比喩から\emph{楽器の比喩}と呼ぶものへの移行を体現しているという議論——プログラマーとプログラムの関係が、探索的で使い捨てのものではなく、継続的で、パフォーマティブで、練習に基づくものであるモデル。
233
234% ============ 2. THE PROCESSING MODEL ============
235
236\section{Processingモデル(2001年)}
237\label{sec:processing}
238
239Processing~\citep{reas2007processing}はビジュアルアーティストのための「ソフトウェアスケッチブック」として設計された。そのAPIは2つのライフサイクル関数とグローバル描画プリミティブのセットを中心としている。
240
241\subsection{ライフサイクル:\texttt{setup()}と\texttt{draw()}}
242
243\begin{lstlisting}[style=processingstyle,caption={最小限のProcessingスケッチ。}]
244void setup() {
245 size(400, 400);
246 background(0);
247}
248
249void draw() {
250 stroke(255);
251 ellipse(mouseX, mouseY, 20, 20);
252}
253\end{lstlisting}
254
255\texttt{setup()}は1回実行され、\texttt{draw()}はデフォルト60fpsの頻度で毎フレーム実行される。この2関数モデルはProcessingの最も影響力のある設計決定である。アニメーションの認知的オーバーヘッドを、レンダリングループの管理から2つの空欄を埋めることに削減した:「1回だけ起こることは何か?」と「毎フレーム起こることは何か?」
256
257このモデルは意図的に最小限に保たれている。明示的な\texttt{input()}関数はなく、マウスとキーボードの状態は自動更新されるグローバル変数(\texttt{mouseX}、\texttt{mouseY}、\texttt{key}、\texttt{keyCode})として利用可能である。イベントコールバック(\texttt{mousePressed()}、\texttt{keyPressed()})は存在するが、必須のエントリポイントではなくオプションの補助である。
258
259\subsection{描画プリミティブ}
260
261Processingの描画APIはPostScriptとOpenGLから継承した\emph{ステートフルパイプライン}モデルを採用している:状態設定呼び出し(\texttt{stroke()}、\texttt{fill()}、\texttt{strokeWeight()})が永続的なグラフィックスコンテキストを変更し、形状呼び出し(\texttt{ellipse()}、\texttt{rect()}、\texttt{line()})がそのコンテキストを使用してレンダリングする。コンテキストは明示的にリセットされない限りフレーム間で持続する。
262
263\begin{lstlisting}[style=processingstyle,caption={ステートフル描画コンテキスト。}]
264void draw() {
265 fill(255, 0, 0); // Set fill: red
266 stroke(0); // Set stroke: black
267 strokeWeight(3); // Set weight: 3px
268 ellipse(100, 100, 50, 50); // Uses above
269 rect(200, 100, 50, 50); // Also uses above
270 // State persists into next frame
271}
272\end{lstlisting}
273
274この状態の持続性は強力(統一されたスタイルに必要なコードが少ない)であると同時にエラーを招きやすい(忘れられた状態がフレーム間でリークする)。Processingは\texttt{pushStyle()}/\texttt{popStyle()}と\texttt{pushMatrix()}/\texttt{popMatrix()}で対処しているが、これらは上級者向けツールである。
275
276\subsection{グローバルスコープ}
277
278すべてのProcessingプログラムは単一のグローバル名前空間を共有する。\texttt{setup()}と\texttt{draw()}の外部で宣言された変数はどこからでもアクセス可能である。描画関数(\texttt{line()}、\texttt{ellipse()}、\texttt{background()})はグローバルである。入力変数(\texttt{mouseX}、\texttt{mouseY})はグローバルである。これによりスコープ、インポート、依存性注入の理解が不要になる——初心者にとって極めて重要——が、プログラムを組み合わせたり分離したりすることが不可能になる。
279
280% ============ 3. THE P5.JS TRANSITION ============
281
282\section{p5.jsへの移行(2014年)}
283\label{sec:p5js}
284
285p5.js~\citep{mccarthy2015p5js}はProcessingのJavaScript再実装である。主要な貢献はProcessingモデルをブラウザに持ち込んだことだが、移植にはいくつかの適応が必要だった。
286
287\subsection{ライフサイクルの維持}
288
289\begin{lstlisting}[style=p5style,caption={最小限のp5.jsスケッチ。}]
290function setup() {
291 createCanvas(400, 400);
292}
293
294function draw() {
295 background(220);
296 ellipse(mouseX, mouseY, 50, 50);
297}
298\end{lstlisting}
299
300\texttt{setup()}/\texttt{draw()}モデルはそのまま維持された。認知モデルは同一:2つの関数、グローバル描画プリミティブ、自動アニメーションループ。この連続性は意図的であった——p5.jsはWeb上のProcessingであることを目指しており、新しい言語ではなかった。
301
302\subsection{キャンバス作成}
303
304最も明白な変更は\texttt{createCanvas()}が\texttt{size()}を置き換えたことである。これは表面的な変更ではない:Processingでは\texttt{size()}がアプリケーションウィンドウを構成するが、p5.jsでは\texttt{createCanvas()}がDOM内にHTML \texttt{<canvas>}要素を作成する。スケッチは表示領域全体を占有するのではなく、既存のページと折り合いを付けなければならない。
305
306\subsection{インスタンスモード}
307
308p5.jsはグローバル名前空間からの重要な脱出口を導入した:\emph{インスタンスモード}。
309
310\begin{lstlisting}[style=p5style,caption={p5.jsインスタンスモード。}]
311const sketch = (p) => {
312 p.setup = () => {
313 p.createCanvas(400, 400);
314 };
315 p.draw = () => {
316 p.background(220);
317 p.ellipse(p.mouseX, p.mouseY, 50, 50);
318 };
319};
320new p5(sketch);
321\end{lstlisting}
322
323インスタンスモードはすべてのAPI関数を名前空間(\texttt{p.})の後ろにラップし、1つのページ上に複数のスケッチを配置でき、グローバル汚染を回避できる。しかし、ほとんどのp5.jsコードはグローバルモードで書かれ、インスタンスモードはスケッチをより大きなアプリケーションに埋め込むときにのみ使用される。プレフィックス記法(\texttt{p.ellipse}対\texttt{ellipse})は冗長性を増し、Processingを魅力的にした「直接書く」品質を低下させる。
324
325\subsection{変わったものと変わらなかったもの}
326
327p5.jsが維持したもの:2関数ライフサイクル、グローバル描画プリミティブ、ステートフルグラフィックスコンテキスト、フレームベースアニメーション、「スケッチ」のアイデンティティ。適応したもの:DOM向けキャンバス作成、レンダラー選択(2D/WebGL)、ブラウザイベント向けイベント処理、組み合わせ用インスタンスモードの追加。解決しなかったもの:シミュレーションとレンダリングの混同、構造化された入力処理の欠如、単一ファイル分離の問題。
328
329% ============ 4. THE AC PIECE API ============
330
331\section{ACピースAPI(2021年--)}
332\label{sec:ac}
333
334\ac{}のピースAPI~\citep{scudder2026ac}はProcessingの核心的な洞察——即時モードグラフィックス、単一ファイルプログラム、ライフサイクル関数——の上に構築され、2つではなく5つの関心事を中心に拡張している。
335
336\subsection{5つのライフサイクル関数}
337
338\begin{lstlisting}[style=acjsstyle,caption={最小限のACピース。}]
339function boot({ screen, params }) {
340 // Runs once on load
341}
342
343function paint({ wipe, ink, line, screen }) {
344 wipe("navy");
345 ink("pink").circle(
346 screen.width / 2,
347 screen.height / 2,
348 50
349 );
350}
351
352function act({ event: e }) {
353 if (e.is("keyboard:down:space")) {
354 // Handle spacebar
355 }
356}
357
358function sim() {
359 // Update state at 120fps
360}
361
362export { boot, paint, act, sim };
363\end{lstlisting}
364
3655つの関数は:
366
367\begin{itemize}
368 \item \texttt{boot(\$api)} --- ピースのロード時に1回実行される。Processingの\texttt{setup()}を拡張し、プログラマーが構成するのではなくランタイムが画面を提供する。
369 \item \texttt{paint(\$api)} --- レンダリングが必要なフレームごとに実行される。\texttt{draw()}の即時モードモデルを継承するが、純粋にビジュアル:慣例としてロジックを含まず、状態を変更しない。
370 \item \texttt{act(\$api)} --- 各入力イベントにつき1回呼び出される。Processingのイベントコールバック(\texttt{mousePressed()}、\texttt{keyPressed()})を単一の統一エントリポイントに統合する。
371 \item \texttt{sim(\$api)} --- 固定120Hzで実行され、各レンダリングフレーム中に複数回実行される可能性がある。Processingに等価物はない;最も近い類似物は固定タイムステップゲームループ~\citep{nystrom2014game}である。
372 \item \texttt{leave(\$api)} --- 終了時のクリーンアップ。Processingに等価物はなく、スケッチは単純に終了する。
373\end{itemize}
374
375各関数はオプションである。\texttt{paint}のみをエクスポートするピースも有効で実行可能なプログラムである。
376
377\subsection{デストラクチャリングによるAPI注入}
378
379Processingモデルに対する最も構造的に重要な拡張は、\textbf{グローバルスコープにAPI関数が一切存在しない}ことである。ピースが使用するすべての関数はパラメータとして受け取る:
380
381\begin{lstlisting}[style=acjsstyle,caption={ACにおけるAPIデストラクチャリング。}]
382function paint({ wipe, ink, line, box,
383 circle, screen, num }) {
384 wipe(0, 0, 30);
385 ink(255, 100, 180);
386 const cx = num.lerp(0, screen.width, 0.5);
387 circle(cx, screen.height / 2, 40);
388}
389\end{lstlisting}
390
391この設計にはいくつかの帰結がある:
392
393\begin{enumerate}
394 \item \textbf{グローバル汚染なし。}モジュールレベルの変数はピースの状態であり、API関数はパラメータである。衝突しうる環境名前空間は存在しない。
395 \item \textbf{自己文書化するインポート。}各関数の先頭にあるデストラクチャリングパターンが、その関数が使用するAPIサーフェスを正確に宣言し、インライン依存性マニフェストとして機能する。
396 \item \textbf{組み合わせ可能性。}複数のピースがAPI衝突なしに同一のJavaScriptコンテキスト内で共存でき、プラットフォームのピース切り替えと埋め込みメカニズムを実現する。
397 \item \textbf{発見可能性。}エディタの自動補完がデストラクチャリングされたパラメータオブジェクトに対して動作し、APIを探索する自然な方法を提供する。
398\end{enumerate}
399
400これはp5.jsのインスタンスモードパターンを結論まで推し進めたものである:プログラマーは各呼び出しの前に\texttt{p.}をプレフィックスする代わりに、関数シグネチャで必要な関数のみをデストラクチャリングし、1回で済ませる。
401
402\subsection{シミュレーションとレンダリングの分離}
403\label{sec:simsep}
404
405Processingの\texttt{draw()}は2つの関心事を混同している:状態の更新とピクセルのレンダリング。これは単純なスケッチでは機能するが、複雑さが増すと問題が生じる:物理シミュレーションがフレームレートに束縛される、入力遅延がレンダリングコストに結合する、「何が起こったか」と「どう見えるか」の分離が困難になる。
406
407ACはこれらを明示的に分離する:
408
409\begin{itemize}
410 \item \texttt{sim()}は表示リフレッシュレートに関係なく固定120Hzで実行される。60Hzディスプレイでは\texttt{sim()}は各\texttt{paint()}呼び出しごとに2回実行される。144Hzディスプレイでは比率が相応に調整される。
411 \item \texttt{paint()}はディスプレイのリフレッシュレート(上限約165fps)で実行され、現在の状態のレンダリングのみを担当する。
412 \item \texttt{act()}はイベント到着時に即座に実行され、各入力イベントにつき1回。
413\end{itemize}
414
415この3方向の分離は現代のゲームエンジンアーキテクチャ~\citep{nystrom2014game}を反映している:決定論的ロジックのための固定更新レート、滑らかな表示のための可変レンダリングレート、入力のためのイベントキュー。違いは、ACがこのアーキテクチャをフレームワークの背後に隠すのではなく、第一級APIとして公開していることである。
416
417\subsection{統一されたイベント処理}
418
419Processingは入力処理をグローバル変数とオプションのコールバックに分散させている:
420
421\begin{lstlisting}[style=processingstyle]
422// Processing: scattered input model
423void draw() {
424 if (mousePressed) { /* poll state */ }
425}
426void mousePressed() { /* callback */ }
427void keyPressed() { /* callback */ }
428void mouseDragged() { /* callback */ }
429\end{lstlisting}
430
431ACは文字列ベースのイベントマッチングシステムにより、すべての入力を\texttt{act()}に統合する:
432
433\begin{lstlisting}[style=acjsstyle]
434function act({ event: e, pen }) {
435 if (e.is("touch")) { }
436 if (e.is("draw")) { }
437 if (e.is("lift")) { }
438 if (e.is("keyboard:down:a")) { }
439 if (e.is("keyboard:down:space")){ }
440 if (e.is("gamepad:a")) { }
441 if (e.is("reframed")) { }
442}
443\end{lstlisting}
444
445\texttt{event.is()}パターンは、入力モダリティ(タッチ、マウス、キーボード、ゲームパッド、MIDI、ハンドトラッキング)を横断する統一インターフェースを単一の関数で提供する。イベント文字列は階層的(\texttt{keyboard:down:a})であり、任意の特異性レベルでマッチングできる。これはProcessingコールバックの組み合わせ爆発を、単一のフィルタ可能なストリームに置き換える。
446
447\subsection{描画プリミティブ:デフォルトでステートレス}
448
449Processingとp5.jsは、\texttt{fill()}、\texttt{stroke()}、変換呼び出しが明示的に変更されるまで持続するステートフルグラフィックスコンテキストを使用する。ACはこれを反転する:\texttt{ink()}関数は\emph{直後の}描画呼び出しのために色を設定し、チェーン呼び出しをサポートするAPIオブジェクトを返す:
450
451\begin{lstlisting}[style=acjsstyle]
452function paint({ wipe, ink, line, circle }) {
453 wipe("black");
454 ink("red").circle(50, 50, 20);
455 ink("blue").line(0, 0, 100, 100);
456 // No state leaks between calls
457}
458\end{lstlisting}
459
460\texttt{ink()}の戻り値チェーンパターンにより、色-形状のペアが視覚的にアトミックになる:各描画操作はコンテキスト変更のシーケンスではなく、自己完結した式である。これにより、あるカテゴリのバグが排除される:前のフレーム(または前の関数)から忘れられた\texttt{fill()}や\texttt{stroke()}呼び出しが無関係な描画操作に漏れ出すことがなくなる。
461
462\texttt{wipe()}関数はProcessingの\texttt{background()}を置き換え、より短く能動的な動詞を使用している。この命名は意図的である:「wipe」(拭く)は属性設定ではなく物理的動作(表面を拭く)を暗示する。
463
464\subsection{キャンバス構成不要}
465
466Processingでは\texttt{setup()}の最初の行は通常\texttt{size(w, h)}である。p5.jsでは\texttt{createCanvas(w, h)}である。ACでは等価の呼び出しがない。ランタイムがデバイスのネイティブ解像度でキャンバスを提供し、ピースは読み取り専用プロパティ\texttt{screen.width}と\texttt{screen.height}を通じて受け取る。
467
468これはモバイルファーストの設計思想を反映している:スマートフォンとタブレットでは「正しい」キャンバスサイズはデバイスの画面である。プログラマーにサイズを指定させると、固定キャンバスと可変ビューポートの間にミスマッチが生じる。ACはキャンバスをデフォルトでアダプティブにすることで、このミスマッチを排除する。
469
470% ============ 5. API SURFACE COMPARISON ============
471
472\section{APIサーフェス比較}
473\label{sec:comparison}
474
475表~\ref{tab:lifecycle}はライフサイクルモデルを比較する。表~\ref{tab:drawing}は描画プリミティブを比較する。
476
477\begin{table}[h]
478\small
479\centering
480\begin{tabularx}{\columnwidth}{lXXX}
481\toprule
482 & \textbf{Processing} & \textbf{p5.js} & \textbf{AC} \\
483\midrule
484初期化 & \texttt{setup()} & \texttt{setup()} & \texttt{boot(\$)} \\
485レンダリング & \texttt{draw()} & \texttt{draw()} & \texttt{paint(\$)} \\
486ロジック & (draw内) & (draw内) & \texttt{sim(\$)} \\
487入力 & コールバック & コールバック & \texttt{act(\$)} \\
488クリーンアップ & --- & \texttt{remove()} & \texttt{leave(\$)} \\
489\midrule
490レンダリング周波数 & 60fps & 60fps & ディスプレイHz \\
491ロジック周波数 & 60fps & 60fps & 120fps固定 \\
492スコープ & グローバル & グローバル/インスタンス & 注入 \\
493\bottomrule
494\end{tabularx}
495\caption{ライフサイクル比較。\texttt{\$}はデストラクチャリングによるAPI注入を示す。}
496\label{tab:lifecycle}
497\end{table}
498
499\begin{table}[h]
500\small
501\centering
502\begin{tabularx}{\columnwidth}{lXX}
503\toprule
504\textbf{Processing/p5} & \textbf{AC} & \textbf{備考} \\
505\midrule
506\texttt{background()} & \texttt{wipe()} & 動詞、属性ではない \\
507\texttt{fill() + stroke()} & \texttt{ink()} & 統合、チェーン可能 \\
508\texttt{ellipse()} & \texttt{circle()} & 形状で命名 \\
509\texttt{rect()} & \texttt{box()} & より短い名前 \\
510\texttt{line()} & \texttt{line()} & 変更なし \\
511\texttt{point()} & \texttt{plot()} & グラフィックスの比喩 \\
512\texttt{text()} & \texttt{write()} & 能動的動詞 \\
513--- & \texttt{flood()} & 領域塗りつぶし \\
514--- & \texttt{paste()} & バッファ合成 \\
515--- & \texttt{form()} & 3Dレンダリング \\
516\bottomrule
517\end{tabularx}
518\caption{描画プリミティブ比較。}
519\label{tab:drawing}
520\end{table}
521
522\subsection{命名哲学}
523
524ProcessingのAPI名は記述的な名詞と形容詞である:\texttt{background}、\texttt{ellipse}、\texttt{rect}、\texttt{stroke}、\texttt{fill}。設定または描画される\emph{もの}を記述する。ACの名前は能動的な動詞である:\texttt{wipe}、\texttt{ink}、\texttt{plot}、\texttt{write}、\texttt{flood}、\texttt{paste}。\emph{プログラマーが何をしているか}——表面に対して行う物理的動作——を記述する。
525
526記述的命名から命令的命名への移行は楽器の比喩と一致する:楽器のインターフェースは動詞(押す、吹く、叩く、弾く)で理解されるのであり、名詞ではない。AC APIは一連の動作として読める:「画面を拭く、ピンクのインクを付ける、円を描く、テキストを書く。」
527
528\subsection{カラーモデル}
529
530Processingは独立した\texttt{fill()}と\texttt{stroke()}呼び出しを使用し、それぞれがRGB、HSB、16進値を受け取る。fill/strokeの区別はベクターグラフィックス(SVG、PostScript)にマッピングされ、形状が内部色と境界色を持つ。
531
532ACは単一の\texttt{ink()}呼び出しを使用し、後続のすべての操作の色を設定する。fill/strokeの区別はない:\texttt{circle()}がフィルかストロークかは環境コンテキストではなく引数に依存する。\texttt{ink()}関数は以下を受け取る:
533
534\begin{itemize}
535 \item RGB値:\texttt{ink(255, 100, 50)}
536 \item 名前付き色:\texttt{ink("pink")}、\texttt{ink("navy")}
537 \item グレースケール:\texttt{ink(128)}
538 \item アルファ:\texttt{ink(255, 0, 0, 128)}
539\end{itemize}
540
541名前付き色は初心者にとって重要なユーザビリティの選択である。Processingがピンクを得るために\texttt{fill(255, 192, 203)}を必要とするところ、ACは\texttt{ink("pink")}を受け付ける。名前付き色のボキャブラリーは意図的に小さく喚起力に富み、パレットよりも絵具箱に近い。
542
543% ============ 6. STATE MANAGEMENT ============
544
545\section{状態管理}
546\label{sec:state}
547
548\subsection{Processing:グローバル変数}
549
550\begin{lstlisting}[style=processingstyle]
551int x = 100;
552int y = 100;
553
554void draw() {
555 background(0);
556 x += 1;
557 ellipse(x, y, 20, 20);
558}
559\end{lstlisting}
560
561Processingにおける状態はグローバル変数に存在する。これはシンプルだが、よく知られた問題がある:すべての状態がどこからでも変更可能で、カプセル化がなく、プログラム状態とAPI状態が区別できない。
562
563\subsection{AC:モジュールレベルクロージャ}
564
565\begin{lstlisting}[style=acjsstyle]
566let x = 100;
567let y = 100;
568
569function sim() {
570 x += 1;
571}
572
573function paint({ wipe, ink, circle }) {
574 wipe(0);
575 ink(255).circle(x, y, 20);
576}
577
578export { sim, paint };
579\end{lstlisting}
580
581ACピースはESモジュールである。モジュールスコープで宣言された変数はピースにプライベートであり、ランタイム、他のピース、グローバルスコープからは見えない。\texttt{export}文はライフサイクル関数のみを可視にする。これはドキュメントで強制される慣例ではなく、JavaScriptモジュールシステムによる保証である。
582
583状態の変更(\texttt{sim})と状態のレンダリング(\texttt{paint})の分離は、\texttt{paint}がモジュール状態の純粋関数であるという規律を促進する——変数を読み取り描画するが、変更しない。これは強制されないが、API構造がそれを自然なパターンにする。
584
585% ============ 7. THE GENEALOGY ============
586
587\section{系譜}
588\label{sec:genealogy}
589
590\subsection{Design By Numbers(1999年)}
591
592MaedaのDesign By Numbers~\citep{maeda2001dbn}は核心的な洞察を導入した:最もシンプルなAPIを持つビジュアル出力のためのプログラミング環境。DBNにはアニメーションループがなく、プログラムは上から下へ1回実行される。プリミティブセットは最小限:\texttt{Paper}(背景)、\texttt{Pen}(線の太さ)、\texttt{Line}、\texttt{Set}(ピクセル)、および制御フロー。言語全体が午後のうちに学べる。
593
594ACはDBNの命名のミニマリズム(短い能動的動詞)と、APIは網羅的に学習可能であるべきだという確信を継承している。
595
596\subsection{Processing(2001年)}
597
598Processing~\citep{reas2003processing}はDBNに欠けていたものを追加した:アニメーション(\texttt{draw()}ループ)、インタラクション(\texttt{mouseX/Y})、より豊富なプリミティブセット。またDBNが意図的に避けたものも追加した:状態(グラフィックスコンテキスト)、標準ライブラリ(数学、タイポグラフィ、画像読み込み)、コンパイルステップ(Java)。Processingの最大のイノベーションは個々の関数ではなく、\texttt{setup()}/\texttt{draw()}のペア:インタラクティブアニメーションの最も単純な表現である。
599
600ACはライフサイクル関数モデルを継承するが、\texttt{draw()}を3つの関心事(\texttt{paint}、\texttt{sim}、\texttt{act})に分割する。
601
602\subsection{p5.js(2014年)}
603
604p5.js~\citep{mccarthy2015p5js}はProcessingをブラウザに持ち込み、スケッチをURL経由で即座に共有可能にした。これはACの前提条件:クリエイティブプラットフォームとしてのブラウザ。p5.jsはまたインスタンスモードを導入し、ACのAPI注入パターンを先取りした。
605
606ACはブラウザネイティブの前提と共有可能性の原則(すべてのピースがURL)を継承するが、ページ内ライブラリモデルを完全なランタイムに置き換えた:ピースは\texttt{<script>}タグを含まず、プラットフォームによってロードされる。
607
608\subsection{openFrameworks(2005年)}
609
610openFrameworks~\citep{openframeworks2005}は類似のライフサイクル(\texttt{setup()}、\texttt{update()}、\texttt{draw()})を使用するが、C++であり、更新ロジックとレンダリングを分離している。ACの\texttt{sim()}/\texttt{paint()}分離はProcessingの統合\texttt{draw()}よりもこのモデルに近い。
611
612\subsection{楽器への転回}
613
614系譜は一連の分離として要約できる:
615
616\begin{enumerate}
617 \item \textbf{DBN}:1回の実行(アニメーションループなし)。
618 \item \textbf{Processing}:初期化 + レンダリング(\texttt{setup} + \texttt{draw})。
619 \item \textbf{openFrameworks}:初期化 + 更新 + レンダリング。
620 \item \textbf{AC}:初期化 + 入力 + 更新 + レンダリング + クリーンアップ(\texttt{boot} + \texttt{act} + \texttt{sim} + \texttt{paint} + \texttt{leave})。
621\end{enumerate}
622
623各ステップが以前混同されていた関心事を分離する。ACの5関数モデルはインタラクティブプログラムのライフサイクルの最も完全な分解であり、名前付きの単一責任エントリポイントに帰着する。結果は身体化認知の知覚-行動サイクル~\citep{varela1991embodied}に類似する:知覚(\texttt{act})、思考(\texttt{sim})、行動(\texttt{paint})、そして誕生(\texttt{boot})と死(\texttt{leave})の2つの追加端点を伴う。
624
625% ============ 8. WORKED EXAMPLE ============
626
627\section{実例:バウンシングボール}
628\label{sec:example}
629
630比較を具体化するため、3つのシステムでバウンシングボールを実装する。
631
632\subsection{Processing}
633
634\begin{lstlisting}[style=processingstyle]
635float x = 200, y = 200;
636float vx = 3, vy = 2;
637
638void setup() {
639 size(400, 400);
640}
641
642void draw() {
643 background(0);
644 x += vx; y += vy;
645 if (x < 0 || x > width) vx *= -1;
646 if (y < 0 || y > height) vy *= -1;
647 fill(255, 100, 180);
648 noStroke();
649 ellipse(x, y, 30, 30);
650}
651\end{lstlisting}
652
653ロジックとレンダリングが\texttt{draw()}内で絡み合っている。状態の変更(\texttt{x += vx})、境界チェック、描画が1つの関数を共有している。
654
655\subsection{p5.js}
656
657\begin{lstlisting}[style=p5style]
658let x = 200, y = 200;
659let vx = 3, vy = 2;
660
661function setup() {
662 createCanvas(400, 400);
663}
664
665function draw() {
666 background(0);
667 x += vx; y += vy;
668 if (x < 0 || x > width) vx *= -1;
669 if (y < 0 || y > height) vy *= -1;
670 fill(255, 100, 180);
671 noStroke();
672 ellipse(x, y, 30, 30);
673}
674\end{lstlisting}
675
676構造はProcessingと同一。唯一の変更は構文的:\texttt{let}対\texttt{float}、\texttt{createCanvas}対\texttt{size}。
677
678\subsection{AC}
679
680\begin{lstlisting}[style=acjsstyle]
681let x, y, vx = 3, vy = 2;
682
683function boot({ screen }) {
684 x = screen.width / 2;
685 y = screen.height / 2;
686}
687
688function sim({ screen }) {
689 x += vx; y += vy;
690 if (x < 0 || x > screen.width) vx *= -1;
691 if (y < 0 || y > screen.height) vy *= -1;
692}
693
694function paint({ wipe, ink, circle }) {
695 wipe(0);
696 ink(255, 100, 180).circle(x, y, 15);
697}
698
699export { boot, sim, paint };
700\end{lstlisting}
701
702関心事が分離されている:\texttt{boot}は実際の画面に基づいて状態を初期化し、\texttt{sim}は120Hzで物理を更新し(ディスプレイリフレッシュレートに関係なく一貫した動作を保証)、\texttt{paint}は状態を変更せずにレンダリングする。\texttt{ink().circle()}チェーンが3行のコード(\texttt{fill}、\texttt{noStroke}、\texttt{ellipse})を置き換える。
703
704% ============ 9. DESIGN RATIONALE ============
705
706\section{設計根拠}
707\label{sec:rationale}
708
709\subsection{なぜ5つの関数か?}
710
7115関数モデルはソフトウェアエンジニアリングの厳密さ(教条としての「関心事の分離」)からではなく、楽器の比喩から生まれた。楽器には異なる段階がある:手に取る(boot)、聴いて応答する(act)、次に何をするか考える(sim)、演奏する(paint)、そして最後に置く(leave)。これらは交換可能な瞬間ではない——演奏中にチューニングはしないし、楽器をしまうときに演奏はしない。ライフサイクル関数はこれらの区別を形式化する。
712
713\subsection{なぜAPI注入か?}
714
715グローバルAPIは初心者に便利だが、プラットフォームへの暗黙の依存関係を作り出す。\texttt{ellipse()}がユーザー関数ではなくProcessing関数であることを知らなければ、Processingスケッチを理解できない。ACのデストラクチャリングパターンは依存関係を明示的にする:\texttt{circle}が関数本体に現れれば、それは関数シグネチャにも現れる。これはESモジュールのインポートと同じ設計原則を関数レベルで適用したものである。
716
717実用的なメリットはホットリロードである:ピースがグローバル参照をキャプチャしないため、ランタイムはリロード間でAPIオブジェクトを置き換えても、ピースのクロージャを無効にしない。
718
719\subsection{なぜ120Hzシミュレーションか?}
720
721Processingの\texttt{draw()}はディスプレイ周波数(通常60fps)で実行される。これは物理シミュレーション、アニメーションタイミング、入力処理がすべてピクセル出力と同じ頻度で実行されることを意味する。144HzディスプレイではProcessingスケッチは2.4倍速く実行され、30Hzディスプレイでは半分の速度になる。
722
723ACは\texttt{sim()}を固定120Hzで実行することにより、シミュレーションとディスプレイを分離する。これにより決定論的な動作が保証される:バウンシングボールはディスプレイリフレッシュレートに関係なく同じ速度で動く。120Hzの頻度は一般的なディスプレイ周波数(60、120)の倍数であり、入力応答性の合理的な上限として選ばれた。
724
725\subsection{なぜキャンバスサイズがないのか?}
726
727\texttt{size()}や\texttt{createCanvas()}を要求することは、プログラマーが出力解像度を知っている(そして気にしている)ことを前提とする。デスクトップではこれは合理的である。モバイル——ACの主要ターゲット——ではこれは摩擦源となる:「正しい」サイズはデバイス、向き、ピクセル密度に依存し、これらすべてをプログラマーが管理する必要はないはずである。ACは画面を既成事実として提供する——すでに張られ下地が塗られたキャンバスのように。
728
729% ============ 10. ADDITIONAL LIFECYCLE ============
730
731\section{拡張ライフサイクル}
732\label{sec:extended}
733
734コアの5関数に加え、ACピースは追加のライフサイクルフックをエクスポートできる:
735
736\begin{itemize}
737 \item \texttt{beat(\$api)} --- メトロノームの各ティックで呼び出される。BPMは\texttt{sound.bpm}で設定。Processingに等価物はない;ACの音楽アプリケーションへの志向を反映している。
738 \item \texttt{preview(\$api)} --- ピースの静的サムネイルをレンダリングする。ピースリストとソーシャル共有に使用。
739 \item \texttt{icon(\$api)} --- ブラウザタブのfaviconをレンダリングする。
740 \item \texttt{meta()} --- Open Graphタグ用の\texttt{\{title, desc\}}メタデータを返す。
741 \item \texttt{receive(event)} --- 他のピースやシステムからのメッセージを処理し、ピース間通信を実現する。
742\end{itemize}
743
744\texttt{beat()}関数は特筆に値する。これはリズミックタイミングを、プログラマーが実装しなければならない機能(Processingでの\texttt{millis()}による)から第一級ライフサイクルイベントに昇格させる。これはAPIレベルでの、音楽とリズムが付加機能ではなくコアユースケースであるという宣言である。
745
746% ============ 11. CONCLUSION ============
747
748\section{結論}
749\label{sec:conclusion}
750
751Processingのコア洞察——クリエイティブワーク向けのプログラミング環境は単なる言語ではなくライフサイクルを提供すべきである——はすべてのACピースの核心に存在する。\texttt{setup()}/\texttt{draw()}から\texttt{boot()}/\texttt{paint()}/\texttt{act()}/\texttt{sim()}/\texttt{leave()}への道筋はProcessingからの離脱ではなく、Processingモデルがさらに拡張されたときの能力の限界についての論証である。
752
753Processingは\texttt{setup()} + \texttt{draw()}がアニメーションをアクセス可能にするのに十分であることを証明した。ACピースAPIは、同じ即時モードのライフサイクル駆動アプローチが——2つではなく5つの関数に分解されたとき——スケッチだけでなく\emph{練習}もサポートできることを論じている:同じピースに繰り返し戻り、洗練し、それで演奏し、時間をかけて流暢さを構築すること。
754
755スケッチブックの比喩(書く、実行する、捨てる)と楽器の比喩(起動する、演奏する、練習する、戻る)は対立するものではない。同じ連続体上の点である。Processingはその連続体の存在を示した。ACは想像以上に遠くまで伸びていることを論じている——\texttt{setup()} + \texttt{draw()}は、その完全な形態が\texttt{boot} + \texttt{act} + \texttt{sim} + \texttt{paint} + \texttt{leave}を必要とする理念の始まりなのである。
756
757APIとは楽器である。Processingはその核心にある。APIがプログラミング行為をどのように分解するかが、何を創造できるかを決定する。
758
759\vspace{0.5em}
760\noindent\textit{英語原版からの翻訳。原版は \url{https://papers.aesthetic.computer} を参照。}
761
762\bibliographystyle{plainnat}
763\bibliography{references}
764
765\end{document}