diff --git a/src/main.tex b/src/main.tex index 9b15c1f..7e5ea43 100755 --- a/src/main.tex +++ b/src/main.tex @@ -35,7 +35,7 @@ 音楽のためのプログラミング言語・環境は、Cycling'74 MaxやPure Data、CSound、SuperCollider、ChucKといった言語を代表として様々なものが開発されてきている\cite{roads2001,Lazzarini2013,Nishino2016,Dannenberg2018}。こうした言語の多くは歴史を遡ると1950年代にベル研究所でマックス・マシューズらが開発したMUSICシリーズに遡ることができる\cite{mathews1963,park2009}。MUSICシリーズは音圧波形を時間・音圧の2次元で離散化・量子化した数列として表すことで、計算によって任意の波形を生成することが可能になるパルス符号変調という理論に基づいて計算機で音を出した最初の事例である。 CやC++といった汎用プログラミング言語で音声合成を行う場合も、基本的にPCMの理論に基づいてプログラミングを行うことになるが、こうした汎用の言語はメモリ管理や並行処理といったハードウェアに近い処理への理解を要求されるため、一般に音楽の記述を行う場合にはより抽象化されたライブラリや、専用のドメイン固有言語を利用するのが普通である。 - +% todo MUSICがUGENパラダイムを導入したという接続を入れる そうしたライブラリや言語では、Unit Generator(UGen)と呼ばれる、オシレーターやフィルターといった基礎的な処理単位を、モジュラーシンセサイザーの様に組み合わせていくことで処理を行う。\footnote{モジュラーシンセサイザーとUnit Generatorは実際には同時期に現れたコンセプトではあるが、音楽プログラミング言語は積極的にビジュアル的なメタファーを物理的なシンセサイザーから取り入れてきている。} 2000年代以降では、Sonic Pi\cite{Aaron2013}やTidalCycles\cite{McLean2014}に代表される、メロディやリズムパターンをソースコードから生成し、リアルタイムでソースコードを書き換えることで演奏を行うライブコーディング環境が開発されてきたが、これらの言語は信号処理をSuperColliderなどのUGenベースの言語に任せ、それらの言語ランタイムへ命令を送信をするクライアントとして実装されている。そして、多くの言語でUGen自体の実装にはC++などの低級言語が用いられ、動的ロードライブラリの形で提供される。 @@ -50,13 +50,13 @@ CやC++といった汎用プログラミング言語で音声合成を行う場 Unit Generatorコンセプトに基づく言語の問題点は、既存の音楽プログラミング言語の多くが実装に依存しており、言語としての意味論が形式化されているものがほとんど無い、とも言い換えられる。 -この観点で、実用的に使われている音楽プログラミング言語の中では、例外的に強く形式化された言語としてFaust\cite{Orlarey2004}が挙げられるFaustは、入出力を持つブロックを、並列、直列、分岐、合流、再帰の5つの合成子を用いて組み合わせる。基本的な算術演算、条件分岐、遅延をプリミティブなブロックとして提供することで、ほぼあらゆる種類の信号処理を記述することができる。また後の拡張では、項書き換え系に基づくマクロを導入することで、ユーザーによる任意の数の入出力を持つブロックの抽象化を可能にした\cite{graf2010}。 +この観点で、実用的に使われている音楽プログラミング言語の中では、Faust\cite{Orlarey2004}が例外的に強く形式化された言語として挙げられる。Faustは、入出力を持つブロックを、並列、直列、分岐、合流、再帰の5つの合成子を用いて組み合わせていくブロックダイアグラム代数(Block Diagram Algebra-BDA)という体系を基礎に置く。バイパス、カット、基本的な算術演算、条件分岐、遅延をプリミティブなブロックとして提供することで、複雑な信号処理グラフを記述することができる。また後の拡張では、項書き換え系に基づくマクロを導入することで、任意の数の入出力を持つブロックの抽象化を可能にした\cite{graf2010}。 -この形式化を通じた強力な抽象化能力により、FaustはC、C++、Rust、LLVM IRなどの様々なバックエンドにコンパイルでき、あらかじめ用意されたアーキテクチャファイルと呼ばれるボイラープレートコードと組み合わせることで、MaxやSuperColliderのUGenとしてエクスポートすることも可能になっている。その一方、Faustの理論的基盤であるブロックダイアグラム代数(Block Diagram Algebra-BDA)は、一般的なプログラミング言語との理論的・実用的な互換性に欠ける。Faustでは外部のC関数を呼び出すことは可能だが、ポインタや参照を扱えないのでホストの内部状態をFaust側から制御することは難しい。 +この形式化を通じた強力な抽象化能力により、FaustはC、C++、Rust、LLVM IRなどの様々なバックエンドにコンパイルでき、あらかじめ用意されたアーキテクチャファイルと呼ばれるボイラープレートコードと組み合わせることで、MaxやSuperColliderのUGenとしてエクスポートすることも可能になっている。その一方、Faustの理論的基盤であるBDAは、一般的なプログラミング言語との理論的・実用的な互換性に欠ける。Faustでは外部のC関数を呼び出すことは可能だが、ポインタや参照を扱えないのでホストの内部状態をFaust側から制御することは難しい。 また、Faustのマクロは、パターンマッチに基づいてBDAを生成する独立した項書き換え系である。そのため、パターンマッチングのための数値引数は暗黙のうちに整数であることが要求され、BDA上では整数と実数の方の区分けは存在しないにもかかわらず、コンパイル時エラーを起こすことある。この暗黙の型付けルールは、初学者のユーザーにとっては直感的なものとは言い難い。 -ラムダ計算のような、より汎用的な計算モデルに基づく信号処理の計算モデルを提案することは、さまざまな汎用言語間の相互運用を可能にするほか、既存の最適化手法の流用や、コンパイラやランタイムの実装を容易にする可能性をもつ\footnote{これまで、BDAはモナドの高位抽象化であるアローとしてラムダ計算ベースの汎用関数型言語に変換可能なことが証明されてはいる[3]。ただ、汎用関数型言語の内部DSLとして信号処理を範疇に入れた音楽プログラミング言語を実装するには、多くの言語では動的なメモリ割り当て・解放のタイミングがユーザー側で制御できないなど、ハードリアルタイム処理に適さないという問題が残る。}。 +ラムダ計算のような、より汎用的な計算モデルに基づく信号処理の計算モデルを提案することは、さまざまな汎用言語との相互運用を促進しうるほか、既存の最適化手法の流用や、コンパイラやランタイムの実装を容易にする可能性をもつ\footnote{これまで、BDAはモナドの高位抽象化であるアローとしてラムダ計算ベースの汎用関数型言語に変換可能なことが証明されてはいる[3]。ただ、汎用関数型言語の内部DSLとして信号処理を範疇に入れた音楽プログラミング言語を実装するには、多くの言語では動的なメモリ割り当て・解放のタイミングがユーザー側で制御できないなど、ハードリアルタイム処理に適さないという問題が残る。}。 Kronos\cite{norilo2015}とW-calculus\cite{arias2021}は、それぞれFaustに影響を受けたラムダ計算ベースの抽象化の例である。Kronosは理論的基盤としてSystem-$F\omega$ というラムダ計算のバリエーションに基づいており、型を入力として受け取り、新しい型を返す関数を定義することができる。Kronosでは、型レベルの計算が信号処理グラフの生成に対応し、値の計算が実際の処理に対応する。Kronosにおいては遅延だけが唯一の特殊なプリミティブ演算であり、フィードバックを伴うルーティングは型計算における再帰的関数適用として表現される。ただし、意味論の厳密な形式化はなされていない。 @@ -66,6 +66,7 @@ W-calculusは、変数の過去の値にアクセスする機能(すなわち 本稿では、W-calculusの2つの制限(非線形システムと高階関数)を緩和する形で設計された、mimiumの中間表現となる計算モデル$\lambda_{mmm}$を提案する\footnote{本稿の内容は、2024年11月に行われたInternational Faust Conference 2024での筆者の発表\cite{matsuura2024}を、対象読者として日本語話者かつ言語設計コミュニティを想定し大幅に改稿したものである。}。以降の節では、まず第2節で$\lambda_{mmm}$のシンタックスと型付け規則、ナイーブな操作的意味論を簡単に紹介する。この操作的意味論は現実的に直接リアルタイム実行することが難しいため、実際のmimiumの実行環境では、$\lambda_{mmm}$を実際に実行するための仮想機械(VM)とその命令セットを持つ。第3章ではこのVMおよび命令セットの設計について概説する。第4節では、現状の$\lambda_{mmm}$を下敷きにしたmimiumの設計の今後の課題および展望を3つの視点で議論する。1つ目は、計算がグローバル環境の評価時に発生するのか、実際の信号処理中に発生するのかをユーザーが区別しなければならないという問題である。2つ目は、if式による部分的な内部状態更新を許すかどうかが信号処理の表現できる範囲およびユーザー体験に大きな影響を与えるという点である。3つ目は、$\lambda_{mmm}$の中間表現を取り入れることで外部関数の呼び出しが容易になるという点である。 +% todo: githubへのリンク \section{音楽のためのプログラミング言語mimiumの仕様} @@ -110,7 +111,9 @@ let\ & onepole = \\ 典型的な単純型付きラムダ計算に追加される $\lambda_{mmm}$ の型付け規則を図\ref{fig:typing}に示す。プリミティブ型には、ほとんどの信号処理で使われる実数型と、ディレイの添字などに使われる自然数型がある。$\lambda_{mmm}$ の設計に直接影響を与えたW-calculusでは、関数型は実数のタプルを取り、実数のタプルを返すことしかできない。これはすなわち高階関数の定義を制限していることを意味する。高階関数は実行時にクロージャのような動的メモリ割り当てに依存するデータ構造を必要とするので、この制約は信号処理言語として合理的でな一方で、ラムダ計算の汎用性を失わせてしまってもいる。 -$\lambda_{mmm}$ では、クロージャのメモリ割り当ての問題はランタイム側の設計と実装に先送りすることで(\ref{sec:vm}を参照)、高階関数の使用を許している。しかし、$feed$の抽象化では、関数型を含まない型\footnote{タプルを含む合成型を扱う場合、単純な関数型のみならずメンバに関数型を1つも含まない型を意味する。}のみを許す。$feed$抽象で関数型を許可するということは、例えば1サンプル前の関数から現在の時刻に使用する関数を合成する、といった記述を可能にすることになる。しかしこれを可能にすると、クロージャによる動的メモリ割り当ての問題に加えて、時間経過ごとに新しいクロージャが過去のクロージャを参照し続けることで使用するメモリサイズが肥大化する空間漏洩(space leak)という更なる問題が発生する。このため、現在mimiumでは専ら実装を簡易化するという理由で関数型を含む型を$feed$の項では取れないようにしている。 +$\lambda_{mmm}$ では、クロージャのメモリ割り当ての問題はランタイム側の設計と実装に先送りすることで(第\ref{sec:vm}節を参照)、高階関数の使用を許している。しかし、$feed$の抽象化では、関数型を含まない型\footnote{タプルを含む合成型を扱う場合、単純な関数型のみならずメンバに関数型を1つも含まない型を意味する。}のみを許す。$feed$抽象で関数型を許可するということは、例えば1サンプル前の関数から現在の時刻に使用する関数を合成する、といった記述を可能にすることになる。しかしこれを可能にすると、クロージャによる動的メモリ割り当ての問題に加えて、時間経過ごとに新しいクロージャが過去のクロージャを参照し続けることで使用するメモリサイズが肥大化する空間漏洩(space leak)という更なる問題が発生する。このため、現在mimiumでは専ら実装を簡易化するという理由で関数型を含む型を$feed$の項では取れないようにしている。 + +% todo:frpとの関連について補足 \subsection{ナイーブな操作的意味論} \label{sec:semantics} @@ -119,7 +122,7 @@ $\lambda_{mmm}$ では、クロージャのメモリ割り当ての問題はラ 図\ref{fig:semantics}に $\lambda_{mmm}$ のビッグステップ(評価の中間過程を考えず、最終的な評価結果のみを考える)操作的意味論の抜粋を示す。この意味論では各時刻にごとに評価環境が用意され、現在時刻が $n$ における、 $t$ サンプル過去の評価環境を $E^{n-t}$ と呼ぶ。0より小さい時刻の評価環境が参照された場合は、どの項もその型のデフォルト値(数値型の場合は0)として評価される。 -当然ながら、この意味論を直接実行しようとすると、各サンプルごとに時刻0から現在時刻までを再計算し、各ステップですべての変数環境を保存する必要がある。しかし実際には、 $delay$ と $feed$ が使用する内部メモリ空間を考慮した仮想マシンが定義され、項は実行前にこのマシン用の命令にコンパイルされる。 +この意味論で$\lambda_{mmm}$ を実際の計算機上で評価しようとすると、各サンプルごとに時刻0から現在時刻までを再計算し、各ステップですべての変数環境を保存する必要がある。しかし実際には、 $delay$ と $feed$ が使用する内部メモリ空間を考慮した仮想マシンが定義され、項は実行前にこのマシン用の命令にコンパイルされる。 @@ -205,9 +208,9 @@ fn onepole(x,g) state_size:1 \caption{\label{fig:bytecode_onepole}{図\ref{fig:onepole-code}の単極フィルターのコードをVM命令にコンパイルした際の例。}} \end{figure} -図\ref{fig:bytecodes_onepole}は図\ref{fig:onepole-code}で示したmimiumでの単極フィルターのコードをVMの命令列にコンパイルした結果の例である。\texttt{self}が参照されると、\texttt{GETSTATE}命令で値を取得し、\texttt{SETSTATE}命令で戻り値を格納して内部状態を更新してから、\texttt{RETURN}命令で値を返す。この場合、実際の戻り値は2番目の \texttt{GETSTATE} 命令を使用して取得され、時刻0の時にはデフォルトの値(数値型なら0)を返すようになる。 +図\ref{fig:bytecode_onepole}は図\ref{fig:onepole-code}で示したmimiumでの単極フィルターのコードをVMの命令列にコンパイルした結果の例である。\texttt{self}が参照されると、\texttt{GETSTATE}命令で値を取得し、\texttt{SETSTATE}命令で戻り値を格納して内部状態を更新してから、\texttt{RETURN}命令で値を返す。この場合、実際の戻り値は2番目の \texttt{GETSTATE} 命令を使用して取得され、時刻0の時にはデフォルトの値(数値型なら0)を返すようになる。 -例えば、$\lambda_{mmm}$ でサンプル単位の時刻カウンタを $feed x. x+1$ と書いたとき、時刻 = 0 のときの戻り値を 0 にするか 1 にするかは、コンパイラの設計次第である。もしコンパイラが時刻=0で1を返すような設計にする場合、2番目の\texttt{GETSTATE}命令は省略でき、\texttt{RETURN}命令の値は\texttt{R(2)}となる(これは厳密には図\texttt{fig:semantics}のE-FEEDの意味論に反する)。 +例えば、$\lambda_{mmm}$ でサンプル単位の時刻カウンタを $feed x. x+1$ と書いたとき、時刻 = 0 のときの戻り値を 0 にするか 1 にするかは、コンパイラの設計次第である。もしコンパイラが時刻=0で1を返すような設計にする場合、2番目の\texttt{GETSTATE}命令は省略でき、\texttt{RETURN}命令の値は\texttt{R(2)}となる(これは厳密には図\ref{fig:semantics}のE-FEEDの意味論に反する)。 \begin{figure}[ht] \centering @@ -447,11 +450,11 @@ fn dsp(){ また本論文では、VMの動作を記述する擬似コードとに加えて、mimiumでのコードの例とそれに対応するバイトコードの例を示すことでコンパイル過程を説明したのみである。より正式な意味論と詳細なコンパイル過程の提示は、今後多段階計算の導入も踏まえ検討する必要がある。 -この研究が、デジタル/コンピュータ上での音・音楽のより一般的な表現に貢献し、音楽のための言語理論とプログラミング言語理論のより広範な分野との間のより深いつながりを促進することを期待する。 +この研究が、コンピュータ上での音・音楽のより一般的な表現に貢献し、音楽のための言語理論とプログラミング言語理論のより広範な分野との間のより深いつながりを促進することを期待する。 \begin{acknowledgment} -mimiumの開発は、2019年度未踏IT人材発掘・育成事業の支援の元開発された。また本研究は、日本学術振興会科研費若手研究「音楽と工学の相互批評的実践としての「音楽土木工学」の研究 」(23K12059)の助成を受けている.ここに感謝の意を表する。 +mimiumの初期開発は、2019年度未踏IT人材発掘・育成事業の支援の元行われたほか、オープンソースソフトウェアとして様々な方からコントリビューションを受けている。また本研究は、日本学術振興会科研費若手研究『音楽と工学の相互批評的実践としての「音楽土木工学」の研究 』(23K12059)の助成を受けている。ここに感謝の意を表する。 \end{acknowledgment} % BibTeX を使用する場合 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/ref_bibtex.bib b/src/ref_bibtex.bib index e98f419..d48877c 100644 --- a/src/ref_bibtex.bib +++ b/src/ref_bibtex.bib @@ -168,17 +168,16 @@ file = {/Users/tomoya/Zotero/storage/ERG4LFIZ/Matsuura and Jo - 2021 - mimium A Self-Extensible Programming Language for.pdf;/Users/tomoya/Zotero/storage/TDBLJQTL/Matsuura and Jo - 2021 - mimium a self-extensible programming language for.pdf} } -@misc{matsuura2024, +@inproceedings{matsuura2024, title = {Lambda-Mmm: The {{Intermediate Representation}} for {{Synchronous Signal Processing Language Based}} on {{Lambda Calculus}}}, shorttitle = {Lambda-Mmm}, author = {Matsuura, Tomoya}, + booktitle = {Proceedings of International Faust Conference 2024}, year = {2024}, - month = sep, - publisher = {Zenodo}, - doi = {10.5281/zenodo.13855343}, + month = nov, + address = {Torino, Italy}, urldate = {2024-10-01}, abstract = {This paper proposes Lambda-mmm, a call-by-value, simply typed lambda calculus-based intermediate representation for a music programming language that handles synchronous signal processing and introduces a virtual machine and instruction set to execute Lambda-mmm. Digital signal processing is represented by a syntax that incorporates the internal states of delay and feedback into the lambda calculus. Lambda-mmm extends the lambda calculus, allowing users to construct generative signal processing graphs and execute them with consistent semantics. However, a challenge arises when handling higher-order functions because users must determine whether execution occurs within the global environment or during DSP execution. This issue can potentially be resolved through multi-stage computation.}, - archiveprefix = {Zenodo}, language = {eng}, keywords = {Computer Music,Programming Language}, file = {/Users/tomoya/Zotero/storage/UMC6L4S5/Matsuura - 2024 - Lambda-mmm the Intermediate Representation for Sy.pdf} diff --git a/src/syntax.tex b/src/syntax.tex index 171e9e3..95370c8 100644 --- a/src/syntax.tex +++ b/src/syntax.tex @@ -13,7 +13,7 @@ % |&\quad \langle \tau \rangle \end{aligned} \end{equation*} - \textrm{Types} + \textrm{型} \end{minipage}& \begin{minipage}[b]{0.4\hsize} @@ -30,7 +30,7 @@ %%|& \quad \textasciitilde e \quad & [escape] \end{aligned} \end{equation*} - \textrm{Values} + \textrm{値} \end{minipage}\\ \multicolumn{2}{l}{ \begin{minipage}[t]{0.4\hsize} @@ -53,6 +53,6 @@ \end{minipage} } \end{tabular} -\centering \textrm{Terms} %置き方おかしいけどこれで上手くレイアウトされてるのでこのまま +\centering \textrm{項} %置き方おかしいけどこれで上手くレイアウトされてるのでこのまま \caption{\label{fig:syntax_v}{\it$\lambda_{mmm}$の値、型、項の定義の抜粋。基本演算などは省略した。}} \end{figure} \ No newline at end of file