Monorepo for Aesthetic.Computer aesthetic.computer
at main 765 lines 45 kB view raw
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}