コンテンツにスキップ

Chapter 2: I/OとTimeline — linkによる依存関係の定義

Chapter 1では、.map()Timeline派生させることで、静的な依存関係を定義する方法を見ました。この章では、それとは異なるアプローチで、外部の世界とのやり取り(I/O)をシステムに統合する方法を探ります。

その鍵は、最初から独立して存在する2つのTimelineを、.link() APIを使って接続し、新たな依存関係を定義することです。

console.log("Hello")というI/O操作は、ブロック宇宙モデルの視点では、世界を「変化」させるアクションではありません。

  • 時間座標t1における宇宙の状態:「コンソールに”Hello”は表示されていない」

  • 時間座標t2における宇宙の状態:「コンソールに”Hello”が表示されている」

console.logは、これら2つの異なる時間座標における、異なるが共に不変である宇宙の状態の間の関係を記述しているに過ぎません。

I/Oを責務としてカプセル化する

Section titled “I/Oを責務としてカプセル化する”

この哲学に基づき、我々は命令的なconsole.logを直接扱うのではなく、その「ルール」をカプセル化した、宣言的なTimelineを定義します。

ブロック宇宙には命令的なI/Oは存在しません。我々が定義するlogTimelineという宣言的な存在があるだけです。

TypeScript

// ヘルパーとして、任意の型の値をログに出力する関数を定義
const log = <A>(value: A): void => {
// このライブラリの哲学に従い、nullは特別扱いする
if (value !== null) {
console.log(`[LOG]:`, value);
}
};
// 「値をコンソールに出力する」という責務だけを持つ、宣言的なlogTimelineを定義する
const logTimeline = Timeline<any>(null);
// その振る舞いを.map()で定義する
logTimeline.map(log);
Section titled “.link() — 2つのTimelineを接続する”

.link()は、すでに存在する2つのTimeline の間に、値を一方的に同期させるという、最もシンプルな依存関係を定義します。

Section titled “F#: link: Timeline<'a> -> Timeline<'a> -> unit”
TS: .link(targetTimeline: Timeline<A>): void
Section titled “TS: .link(targetTimeline: Timeline<A>): void”

実践例:scoreTimelinelogTimelineの依存関係定義

Section titled “実践例:scoreTimelineとlogTimelineの依存関係定義”

アプリケーション内のscoreTimelineの値を、先ほど定義したlogTimelineに接続してみましょう。

TypeScript

const scoreTimeline = Timeline(100);
// scoreTimelineからlogTimelineへの依存関係を.link()で定義する
scoreTimeline.link(logTimeline);
// > [LOG]: 100 (依存関係が定義された瞬間に初期値が伝播し、ログが出力される)
// scoreTimelineの値が更新されると...
scoreTimeline.define(Now, 150);
// > [LOG]: 150 (...定義された依存関係に従い、更新がlogTimelineに伝播し、再度ログが出力される)

このパターンでは、scoreTimelineは自身の値の管理に専念し、ロギングのことは一切関知しません。.link()は、これら責務が分離された2つの宣言的なエンティティの間に、依存関係を定義する役割を果たします。

ここで重要なのは、Chapter 1の.map()と同様に、.link()もまた静的な依存グラフを定義する、という点です。

  • .map(): 1つのソースから新しいTimelineを派生させることで、静的な依存関係を定義した。

  • .link(): 2つの既存のTimelineを接続することで、静的な依存関係を定義した。

プロセスの開始点は異なりますが、どちらも一度定義されると変わることのない、予測可能で安定した関係性をシステム内に構築するという点で、本質的に同じ役割を担っています。

(ここに.link()の動作を視覚的に示すインタラクティブなデモが配置されます。)