[obsidian] vault backup: 2025-11-30 14:02:18[
All checks were successful
Build / build (push) Successful in 10m16s

This commit is contained in:
2025-11-30 14:02:18 +09:00
parent da47f87b9f
commit 46b79948f0
2 changed files with 97 additions and 10 deletions

View File

@@ -28,7 +28,7 @@ Faust[@Orlarey2009]やMaxのGen、のように、サンプル単位レベルで
こうした特徴をまとめると、音楽プログラミング言語の設計には記述できる信号処理の最小単位を小さくしていくほど、コードの動的変更に対応することが難しくなるトレードオフがあるといえる。 こうした特徴をまとめると、音楽プログラミング言語の設計には記述できる信号処理の最小単位を小さくしていくほど、コードの動的変更に対応することが難しくなるトレードオフがあるといえる。
こうした課題に対し、Reachは関数型のUnit Generatorを組み合わせて信号処理を記述する言語で、ソースコードの変更差分を解析して信号処理の内部状態を可能な限り保持する仕組み:**Incremental Functional Reactive Programming**(以下本稿ではIcFRPと呼ぶ)を提案している[@reachIncrementalFunctionalReactive2013]。この仕組みは、SuperColliderのJITLibのようなシステムと比べるとユーザーが現在の信号処理インスタンスに対して削除や追加などの命令を行うのではなく、常にその時のソースコードに望む信号処理を書けば必要な状態の更新はランタイム側が自動で担ってくれるという点で、ユーザーの演奏中の思考モデルが大きく異なると言える。 こうした課題に対し、Reachは関数型のUnit Generatorを組み合わせて信号処理を記述する言語で、ソースコードの変更差分を解析して信号処理の内部状態を可能な限り保持する仕組み:**Incremental Functional Reactive Programming**(以下本稿ではIcFRPと呼ぶ)を提案している[@reach_incremental_2013]。この仕組みは、SuperColliderのJITLibのようなシステムと比べるとユーザーが現在の信号処理インスタンスに対して削除や追加などの命令を行うのではなく、常にその時のソースコードに望む信号処理を書けば必要な状態の更新はランタイム側が自動で担ってくれるという点で、ユーザーの演奏中の思考モデルが大きく異なると言える。
ただ、Reachによる実装としては、ソースコードの単なるテキスト差分の解析では、複数の変更のパターンの可能性を絞り込めないため、テキストエディタEmacsの拡張機能として、切り取りや貼り付けといった操作の履歴を取得することで実装している。 ただ、Reachによる実装としては、ソースコードの単なるテキスト差分の解析では、複数の変更のパターンの可能性を絞り込めないため、テキストエディタEmacsの拡張機能として、切り取りや貼り付けといった操作の履歴を取得することで実装している。
@@ -41,7 +41,7 @@ Faust[@Orlarey2009]やMaxのGen、のように、サンプル単位レベルで
## mimium and lambda-mmm ## mimium and lambda-mmm
mimiumは、Rustに近いシンタックスを持った関数型の音楽信号処理をターゲットドメインにしたプログラミング言語である[@matsuura_mimium_2021]。現在の内部実行モデルとして、値呼び単純型付きラムダ計算を拡張し、最小限の内部状態を持つプリミティブ操作ディレイとフィードバックを加えたLambda-mmm[@matsuuraLambdammmIntermediateRepresentation2024]という計算体系を持っている。 mimiumは、Rustに近いシンタックスを持った関数型の音楽信号処理をターゲットドメインにしたプログラミング言語である[@matsuura_mimium_2021]。現在の内部実行モデルとして、値呼び単純型付きラムダ計算を拡張し、最小限の内部状態を持つプリミティブ操作ディレイとフィードバックを加えたLambda-mmm[@matsuura_lambda-mmm_2024]という計算体系を持っている。
mimiumはコードを専用のVMバイトコードへコンパイルし実行する。実行モデルは、一般的なレジスタマシンの命令セットに、内部状態操作用の操作が加わったものとなる。ディレイやフィードバックで用いられる内部状態は、状態ストレージという1次元の配列領域と単一の読み出し位置ポインタを組み合わせたデータ領域に保存される。 mimiumはコードを専用のVMバイトコードへコンパイルし実行する。実行モデルは、一般的なレジスタマシンの命令セットに、内部状態操作用の操作が加わったものとなる。ディレイやフィードバックで用いられる内部状態は、状態ストレージという1次元の配列領域と単一の読み出し位置ポインタを組み合わせたデータ領域に保存される。
@@ -59,7 +59,7 @@ mimiumはコードを専用のVMバイトコードへコンパイルし実行す
## 多段階計算 ## 多段階計算
多段階計算は、型付きラムダ計算に対して、計算のステージを複数段階に分割する明示的なシンタックスを導入するものである。Lisp系言語のquote/splice機能[@lisp]のように、部分的に計算したコード片を埋め込むようなものを想定しているが、不正な値が埋め込まれないことを型システムとして保証することが特徴である逆に、通常マクロに期待される型システムの範囲を超えたメタ操作を行うことは許されない。実用的な例では、Scala 3でのマクロや、関数型組版処理エンジンSaTysFi[@suwaMLStyleModuleSystem2024]のように、言語内DSLを型安全にライブラリとして実装することを想定しているものがある。mimiumにおいては、多段階計算はコンパイル時に行う計算シグナルグラフのルーティングの決定と、ランタイム時に行う計算実際のオーディオ処理を区別するのに用いている。 多段階計算は、型付きラムダ計算に対して、計算のステージを複数段階に分割する明示的なシンタックスを導入するものである。Lisp系言語のquote/splice機能[@lisp]のように、部分的に計算したコード片を埋め込むようなものを想定しているが、不正な値が埋め込まれないことを型システムとして保証することが特徴である逆に、通常マクロに期待される型システムの範囲を超えたメタ操作を行うことは許されない。実用的な例では、Scala 3でのマクロや、関数型組版処理エンジンSaTysFi[@suwa2024]のように、言語内DSLを型安全にライブラリとして実装することを想定しているものがある。mimiumにおいては、多段階計算はコンパイル時に行う計算シグナルグラフのルーティングの決定と、ランタイム時に行う計算実際のオーディオ処理を区別するのに用いている。
### シンタックスの拡張 ### シンタックスの拡張
@@ -72,7 +72,8 @@ $$
\tau ::= \tau ::=
&\quad R \quad &\\ &\quad R \quad &\\
|&\quad I_n \quad &n \in \mathbb{N} \\ |&\quad I_n \quad &n \in \mathbb{N} \\
|&\quad \tau → \tau &\\ |&\quad \tau_1 → \tau_2 &\\
|&\quad (\tau_1,\tau_2,...) &\\
|&\quad \langle \tau \rangle |&\quad \langle \tau \rangle
\end{align} \end{align}
$$ $$
@@ -81,15 +82,18 @@ $$
$$ $$
\begin{align} \begin{align}
e ::= e ::=
&\quad R & R \in \mathbb{R} [number]&\\ &\quad R & R \in \mathbb{R}\ [number]&\\
|&\quad e \ e \quad& [app]&\\ |&\quad x & [var] \\
|&\quad e_1 \ e_2 \quad& [app]&\\
|&\quad (e_1,e_2,...) \quad& [tuple]&\\
|&\quad e.n \quad& n \in \mathbb{N}\ [proj]&\\
|&\quad \lambda x.e& [abs]&\\ |&\quad \lambda x.e& [abs]&\\
|&\quad let\; x\; =\; e\; in\; e& [let]&\\ |&\quad let\; x\; =\; e_1\; in\; e_2& [let]&\\
|&\quad delay(x,e_{time},v_{bound})&[delay]&\\ |&\quad delay(x,e_{time},v_{bound})&[delay]&\\
|&\quad mem(e) &[mem]&\\ |&\quad mem(e) &[mem]&\\
|&\quad feed\ x.e &[feed]&\\ |&\quad feed\ x.e &[feed]&\\
|&\quad `(e) &[quote]&\\ |&\quad `e &[quote]&\\
|&\quad $(e) &[splice]& |&\quad $e &[splice]&
\end{align} \end{align}
$$ $$
@@ -98,7 +102,7 @@ $$
v ::= v ::=
|&\quad R & R \in \mathbb{R} [number]&\\ |&\quad R & R \in \mathbb{R} [number]&\\
|&\quad cls(e,E) &[closure]&\\ |&\quad cls(e,E) &[closure]&\\
|&\quad \langle v \rangle &[code]&\\ |&\quad \langle e \rangle &[code]&\\
\end{align} \end{align}
$$ $$
@@ -107,6 +111,8 @@ $$
操作的意味論 操作的意味論
グローバルな関数呼び出しとそれ以外の呼び出しの区別。式に自由変数があるかないかを区別する必要がある。それを表示的意味論に落とし込めるのか
### シンタックスシュガー ### シンタックスシュガー
@@ -163,6 +169,17 @@ fn dsp(){
``` ```
## コールツリーの解析 ## コールツリーの解析
```rust
enum WordSize(u64);
enum MaxTime(u64);
enum StateTree{
Feed(WordSize),
Mem(WordSize),
Delay(MaxTime),
DirectFnCall(Vec<StateTree>)
}
```
- クロージャ - クロージャ
- 関数定義内でグローバルでもローカルでもない変数を参照している場合。 - 関数定義内でグローバルでもローカルでもない変数を参照している場合。