Skip to content

Commit efd2e30

Browse files
committed
update
1 parent 2d21d3e commit efd2e30

3 files changed

Lines changed: 48 additions & 88 deletions

File tree

_site/0-book/unit-5/section-3/3-bind.md

Lines changed: 24 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,7 @@ This allows us to build dynamic systems where the wiring of the dependency graph
1717
##### F#: `bind: ('a -> Timeline<'b>) -> Timeline<'a> -> Timeline<'b>`
1818

1919
##### TS: `.bind<B>(monadf: (value: A) => Timeline<B>): Timeline<B>`
20-
Enumerating objects: 33, done.Enumerating objects: 33, done.
21-
Counting objects: 100% (33/33), done.
22-
Delta compression using up to 16 threads
23-
Compressing objects: 100% (17/17), done.
24-
Writing objects: 100% (18/18), 1.37 KiB | 1.37 MiB/s, done.
25-
Total 18 (delta 14), reused 0 (delta 0), pack-reused 0 (from 0)
26-
remote: Resolving deltas: 100% (14/14), completed with 12 local objects.
27-
To https://github.com/ken-okabe/ken-okabe.github.io
28-
675ec98..04b62da main -> main
29-
Counting objects: 100% (33/33), done.
30-
Delta compression using up to 16 threads
31-
Compressing objects: 100% (17/17), done.
32-
Writing objects: 100% (18/18), 1.37 KiB | 1.37 MiB/s, done.
33-
Total 18 (delta 14), reused 0 (delta 0), pack-reused 0 (from 0)
34-
remote: Resolving deltas: 100% (14/14), completed with 12 local objects.
35-
To https://github.com/ken-okabe/ken-okabe.github.io
36-
675ec98..04b62da main -> main
20+
3721
The crucial difference from `.map()` is that the function it takes (`monadf`) accepts a value `A` and returns a **new `Timeline<B>`**.
3822

3923
## What is the use of `bind` or the Monad algebraic structure in a FRP library like Timeline?
@@ -47,15 +31,7 @@ Therefore, I would like to present a clear answer here and now.
4731
## The Diamond Problem in FRP Libraries—Atomic Update
4832

4933
### 1. Definition of the Diamond Problem
50-
Enumerating objects: 33, done.
51-
Counting objects: 100% (33/33), done.
52-
Delta compression using up to 16 threads
53-
Compressing objects: 100% (17/17), done.
54-
Writing objects: 100% (18/18), 1.37 KiB | 1.37 MiB/s, done.
55-
Total 18 (delta 14), reused 0 (delta 0), pack-reused 0 (from 0)
56-
remote: Resolving deltas: 100% (14/14), completed with 12 local objects.
57-
To https://github.com/ken-okabe/ken-okabe.github.io
58-
675ec98..04b62da main -> main
34+
5935
The diamond problem in Functional Reactive Programming (FRP) refers to issues of glitches and inefficiency that arise when a dependency graph forms a diamond shape. Specifically, it occurs when a timeline `D` depends on two other timelines, `B` and `C`, both of which depend on a common source, `A`.
6036

6137
```
@@ -206,6 +182,7 @@ How is this dynamic switching of dependencies achieved? The answer lies in the h
206182
The dynamic switching of dependencies brought about by `.bind()` is a manifestation of a deeper, more powerful concept in the library's design. To understand it, let's first organize the different levels of "mutability" in `map` and `bind`.
207183

208184
- **Level 1 Mutability (The world of `map`/`link`)**: In a static dependency, the `Timeline` object itself is an immutable entity. The only thing that is "mutable" is the internal value **`_last`**, which is updated as the `Now` viewpoint moves. This can be called the minimal unit of **illusion**, the "current value" in the block universe.
185+
209186
- **Level 2 Mutability (The world of `bind`)**: When `.bind()` is introduced, this concept of mutability is **extended**. It's no longer just the `_last` value that gets replaced. The `innerTimeline` object returned by `.bind()` is swapped out entirely according to the source's value. This means that the **`Timeline` itself, which defines the "truth" of a given moment, becomes a temporary, replaceable entity**.
210187

211188
This "structural" level of mutability is the essence of the `Illusion` concept.
@@ -271,7 +248,13 @@ console.log("Switched user posts:", currentUserPostsTimeline.at(Now));
271248
// > Switched user posts: ["post3", "post4"]
272249
```
273250

274-
This code example brilliantly demonstrates two aspects of `bind`. First, the **theoretical aspect**: it describes the complex requirement of dynamically switching the UI state in a highly declarative way. Second, the **implementation aspect**: behind the scenes, `DependencyCore` reliably disposes of the old `innerTimeline` through the `Illusion` mechanism, so the developer does not need to be conscious of resource management. Thus, `bind` shows its true value only when a powerful theory and a robust implementation that supports it are combined.
251+
This code example brilliantly demonstrates two aspects of `bind`.
252+
253+
First, the **theoretical aspect**: it describes the complex requirement of dynamically switching the UI state in a highly declarative way.
254+
255+
Second, the **implementation aspect**: behind the scenes, `DependencyCore` reliably disposes of the old `innerTimeline` through the `Illusion` mechanism, so the developer does not need to be conscious of resource management.
256+
257+
Thus, `bind` shows its true value only when a powerful theory and a robust implementation that supports it are combined.
275258

276259
## Canvas Demo
277260

@@ -347,17 +330,7 @@ let B = A + 1; // 期待値: 11
347330
let C = A * 2; // 期待値: 20
348331
let D = B + C; // 期待値: 31
349332
```
350-
[main e684c6b] update
351-
2 files changed, 8 insertions(+)
352-
Enumerating objects: 7, done.
353-
Counting objects: 100% (7/7), done.
354-
Delta compression using up to 16 threads
355-
Compressing objects: 100% (4/4), done.
356-
Writing objects: 100% (4/4), 575 bytes | 575.00 KiB/s, done.
357-
Total 4 (delta 3), reused 0 (delta 0), pack-reused 0 (from 0)
358-
remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
359-
To https://github.com/ken-okabe/ken-okabe.github.io
360-
6660b97..e684c6b main -> main
333+
361334
しかし、更新の伝播順序によっては、グリッチが発生します。
362335

363336
1. `B` が先に更新されると、`D``B` の新しい値(`11`)と`C`の古い値(`10`)を使って計算されてしまいます。
@@ -469,20 +442,21 @@ const D = A.bind(a => {
469442

470443
`.bind()`がもたらす動的な依存関係の切り替えは、このライブラリの設計における、より深く、より強力な概念の現れです。それを理解するために、まず`map``bind`における「可変性」のレベルの違いを整理しましょう。
471444

472-
- **レベル1の可変性 (`map`/`link`の世界)**: 静的な依存関係では、`Timeline`オブジェクトそのものは不変の存在です。唯一「可変」なのは、`Now`という視点の移動に伴って更新される、内部の値 **`_last`** です。これは、ブロック宇宙における「現在の値」という、最小単位の**イリュージョン(幻想)**と言えます。
473-
- **レベル2の可変性 (`bind`の世界)**: `.bind()`を導入すると、この可変性の概念が**拡張**されます。もはや`_last`という値だけが入れ替わるのではありません。`.bind()`が返す`innerTimeline`オブジェクトそのものが、ソースの値に応じて、まるごと入れ替わります。つまり、ある瞬間の「真実」を定義している**`Timeline`自体が、一時的で、入れ替え可能な存在**になるのです。
445+
- **レベル1の可変性 (`map`/`link`の世界)**: 静的な依存関係では、`Timeline`オブジェクトそのものは不変の存在です。唯一「可変」なのは、`Now`という視点の移動に伴って更新される、内部の値 **`_last`** です。これは、ブロック宇宙における「現在の値」という、最小単位の **イリュージョン(幻想)** と言えます。
446+
447+
- **レベル2の可変性 (`bind`の世界)**: `.bind()`を導入すると、この可変性の概念が**拡張**されます。もはや`_last`という値だけが入れ替わるのではありません。`.bind()`が返す`innerTimeline`オブジェクトそのものが、ソースの値に応じて、まるごと入れ替わります。つまり、ある瞬間の「真実」を定義している **`Timeline`自体が、一時的で、入れ替え可能な存在** になるのです。
474448

475449
この「構造」レベルの可変性こそが、`Illusion`という概念の本質です。
476450

477451
概念的には、`bind`が返す結果の`Timeline`オブジェクト(例えば`currentUserPostsTimeline`)は、**最初に一度だけ生成される不変(Immutable)な存在**です。
478452

479453
しかし、我々の視点である`Now`が時間軸に沿って動く**可変な(Mutable)カーソル**であるのと全く同じ理由で、そのカーソルと常に同期している`innerTimeline`(例えば`"user123"`の投稿`Timeline``"user456"`の投稿`Timeline`)は、**可変でなければなりません**
480454

481-
`innerTimeline`が「破壊」されなければならない根本的な理由は、**`Now`カーソルの移動と同期して、依存グラフそのものが時間発展しており、それぞれの時間座標においてグラフの構造が異なる**からです。
455+
`innerTimeline`が「破壊」されなければならない根本的な理由は、**`Now`カーソルの移動と同期して、依存グラフそのものが時間発展しており、それぞれの時間座標においてグラフの構造が異なる** からです。
482456

483-
この、時間発展する依存グラフの「ある瞬間における状態」こそが**`Illusion`**です。そして、`Now`カーソルの移動と、この`Illusion`の書き換え(古いものの破棄と新しいものの生成)を同期させる作業を、`DependencyCore`が一括して命令的に管理しているのです。
457+
この、時間発展する依存グラフの「ある瞬間における状態」こそが **`Illusion`** です。そして、`Now`カーソルの移動と、この`Illusion`の書き換え(古いものの破棄と新しいものの生成)を同期させる作業を、`DependencyCore`が一括して命令的に管理しているのです。
484458

485-
つまり`Illusion`とは、`_last`という**「値レベルの可変性」を、`innerTimeline`という「構造レベルの可変性」へと拡張した概念**なのです。そして後続の章で`.using()`を導入する際には、この可変性の概念がさらに「外部リソースのライフサイクル」にまで拡張されていきます。
459+
つまり`Illusion`とは、`_last`という **「値レベルの可変性」を、`innerTimeline`という「構造レベルの可変性」へと拡張した概念** なのです。そして後続の章で`.using()`を導入する際には、この可変性の概念がさらに「外部リソースのライフサイクル」にまで拡張されていきます。
486460

487461
## 応用ケース:動的なUI構築
488462

@@ -535,7 +509,13 @@ console.log("Switched user posts:", currentUserPostsTimeline.at(Now));
535509
// > Switched user posts: ["post3", "post4"]
536510
```
537511

538-
このコード例は、`bind`の二つの側面を見事に示しています。第一に、**理論的な側面**として、UIの状態を動的に切り替えるという複雑な要求を、極めて宣言的に記述しています。第二に、**実装的な側面**として、その裏側では`DependencyCore``Illusion`の仕組みを通じて古い`innerTimeline`を確実に破棄しており、開発者はリソース管理を意識する必要がありません。このように、強力な理論とそれを支える堅牢な実装が両立して初めて、`bind`はその真価を発揮するのです。
512+
このコード例は、`bind`の二つの側面を見事に示しています。
513+
514+
第一に、**理論的な側面**として、UIの状態を動的に切り替えるという複雑な要求を、極めて宣言的に記述しています。
515+
516+
第二に、**実装的な側面**として、その裏側では`DependencyCore``Illusion`の仕組みを通じて古い`innerTimeline`を確実に破棄しており、開発者はリソース管理を意識する必要がありません。
517+
518+
このように、強力な理論とそれを支える堅牢な実装が両立して初めて、`bind`はその真価を発揮するのです。
539519

540520
## Canvasデモ
541521

src/content/docs/en/book/unit-5/section-3/3-bind.md

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,7 @@ This allows us to build dynamic systems where the wiring of the dependency graph
1919
##### F#: `bind: ('a -> Timeline<'b>) -> Timeline<'a> -> Timeline<'b>`
2020

2121
##### TS: `.bind<B>(monadf: (value: A) => Timeline<B>): Timeline<B>`
22-
Enumerating objects: 33, done.Enumerating objects: 33, done.
23-
Counting objects: 100% (33/33), done.
24-
Delta compression using up to 16 threads
25-
Compressing objects: 100% (17/17), done.
26-
Writing objects: 100% (18/18), 1.37 KiB | 1.37 MiB/s, done.
27-
Total 18 (delta 14), reused 0 (delta 0), pack-reused 0 (from 0)
28-
remote: Resolving deltas: 100% (14/14), completed with 12 local objects.
29-
To https://github.com/ken-okabe/ken-okabe.github.io
30-
675ec98..04b62da main -> main
31-
Counting objects: 100% (33/33), done.
32-
Delta compression using up to 16 threads
33-
Compressing objects: 100% (17/17), done.
34-
Writing objects: 100% (18/18), 1.37 KiB | 1.37 MiB/s, done.
35-
Total 18 (delta 14), reused 0 (delta 0), pack-reused 0 (from 0)
36-
remote: Resolving deltas: 100% (14/14), completed with 12 local objects.
37-
To https://github.com/ken-okabe/ken-okabe.github.io
38-
675ec98..04b62da main -> main
22+
3923
The crucial difference from `.map()` is that the function it takes (`monadf`) accepts a value `A` and returns a **new `Timeline<B>`**.
4024

4125
## What is the use of `bind` or the Monad algebraic structure in a FRP library like Timeline?
@@ -49,15 +33,7 @@ Therefore, I would like to present a clear answer here and now.
4933
## The Diamond Problem in FRP Libraries—Atomic Update
5034

5135
### 1. Definition of the Diamond Problem
52-
Enumerating objects: 33, done.
53-
Counting objects: 100% (33/33), done.
54-
Delta compression using up to 16 threads
55-
Compressing objects: 100% (17/17), done.
56-
Writing objects: 100% (18/18), 1.37 KiB | 1.37 MiB/s, done.
57-
Total 18 (delta 14), reused 0 (delta 0), pack-reused 0 (from 0)
58-
remote: Resolving deltas: 100% (14/14), completed with 12 local objects.
59-
To https://github.com/ken-okabe/ken-okabe.github.io
60-
675ec98..04b62da main -> main
36+
6137
The diamond problem in Functional Reactive Programming (FRP) refers to issues of glitches and inefficiency that arise when a dependency graph forms a diamond shape. Specifically, it occurs when a timeline `D` depends on two other timelines, `B` and `C`, both of which depend on a common source, `A`.
6238

6339
```
@@ -208,6 +184,7 @@ How is this dynamic switching of dependencies achieved? The answer lies in the h
208184
The dynamic switching of dependencies brought about by `.bind()` is a manifestation of a deeper, more powerful concept in the library's design. To understand it, let's first organize the different levels of "mutability" in `map` and `bind`.
209185

210186
- **Level 1 Mutability (The world of `map`/`link`)**: In a static dependency, the `Timeline` object itself is an immutable entity. The only thing that is "mutable" is the internal value **`_last`**, which is updated as the `Now` viewpoint moves. This can be called the minimal unit of **illusion**, the "current value" in the block universe.
187+
211188
- **Level 2 Mutability (The world of `bind`)**: When `.bind()` is introduced, this concept of mutability is **extended**. It's no longer just the `_last` value that gets replaced. The `innerTimeline` object returned by `.bind()` is swapped out entirely according to the source's value. This means that the **`Timeline` itself, which defines the "truth" of a given moment, becomes a temporary, replaceable entity**.
212189

213190
This "structural" level of mutability is the essence of the `Illusion` concept.
@@ -273,7 +250,13 @@ console.log("Switched user posts:", currentUserPostsTimeline.at(Now));
273250
// > Switched user posts: ["post3", "post4"]
274251
```
275252

276-
This code example brilliantly demonstrates two aspects of `bind`. First, the **theoretical aspect**: it describes the complex requirement of dynamically switching the UI state in a highly declarative way. Second, the **implementation aspect**: behind the scenes, `DependencyCore` reliably disposes of the old `innerTimeline` through the `Illusion` mechanism, so the developer does not need to be conscious of resource management. Thus, `bind` shows its true value only when a powerful theory and a robust implementation that supports it are combined.
253+
This code example brilliantly demonstrates two aspects of `bind`.
254+
255+
First, the **theoretical aspect**: it describes the complex requirement of dynamically switching the UI state in a highly declarative way.
256+
257+
Second, the **implementation aspect**: behind the scenes, `DependencyCore` reliably disposes of the old `innerTimeline` through the `Illusion` mechanism, so the developer does not need to be conscious of resource management.
258+
259+
Thus, `bind` shows its true value only when a powerful theory and a robust implementation that supports it are combined.
277260

278261
## Canvas Demo
279262

0 commit comments

Comments
 (0)