---
# System prepended metadata

title: Clean Architecture　第II部　第6章　関数型プログラミング　読書会#6
tags: [book]

---

# Clean Architecture　第II部　第6章　関数型プログラミング　読書会#6

###### tags `book`

## 概要
|項目|内容|
|-|-|
|開催日|2021/05/16|
|開始時間|13:30|
|終了時間|16:40|
|メンバー|nyx,niro|

***


## 関数型プログラミング

#### 感想・気づき・疑問

#### nothing
**着想**
1930年代に Alonzo Church が発明したラムダ計算に基づいて関数型プログラミングが発明された。
和表記 アロンゾ・チャーチ
R.I.P 1903年6月14日-1995年8月11日
Age 92
出身 アメリカ ワシントンD.C
研究分野 数学、論理学
![via https://en.wikipedia.org/wiki/Alonzo_Church](https://i.imgur.com/PBXNUsP.png)

**最初の関数型言語**
最初の関数型プログラミングはLispでした。[LINK](https://en.wikipedia.org/wiki/Functional_programming)
1950年代後半にマサチューセッツ工科大学（MIT）でジョンマッカーシーIBM700/7000シリーズの科学コンピューター用に開発されました。
英名:John McCarthy 
Field:Computer Scientist
R.I.P 1927年9月4日–2011年10月24日
Age 84
出身 アメリカ ボストン
![via https://en.wikipedia.org/wiki/John_McCarthy_(computer_scientist)](https://i.imgur.com/SjodstA.png)

***

### 整数の二乗

提示されたJavaコード
```java=
public class Squint{

  public static void main(String[] args){
  
  for(int i; i<25; i++)
    System.out.println*(i*i);
  }

}
```
提示されたLispコード
```clojure=
(prinln (take 25 (map (fn [x] (* x x)) (range))))
```
```clojure=
(prinln ; __________________________標準出力
    (take 25; ______________________25まで
    (map (fn [x] (* x x));__________2乗する
        (range))));_________________無限リストの生成
```

Java プログラムは**可変変数**（プログラムの実行中に変化させる変数）を使用する。
ex) ループの制御変数`i`
Clojure プログラムはxなどの変数は初期化されているが、そこから変更されることはない。
> Clojureには、変数が無い。

> 『関数型言語の変数は**変化しない**』

上手くいく。
```java=
var value = 1;//実質的ファイナル
final int value2 = 1;//ファイナル
Set<Integer> set =new HashSet();//良くない例
set.put(1);
CurrentSet<Integer> currentSet;//良い例
IntStream.map(i->i*i).peak(i->set.put(i)).foreach(System.out::println);
```

コンパイルエラー
```java=

private static final int C=9;

public void fun(){
  var value = 1;
  var value =+ value +1; //実質的ファイナルではない。
  IntStream.parallel()
  .map(i->this.run(i*value)
  .foreach(System.out::println);
}

```

***

### 不変性とアーキテクチャ

アーキテクトが変数の可変性に配慮すべき理由
**=> 競合状態・デッドロック状態・並行更新の問題の原因が、すべて変数にあるから**

**:memo:並行処理を安全に処理する性質をプログラムに簡単に与えることができるパラダイムととらえることができると思いました。これは、関数型プログラミングの値束縛の性質:不変性に基づいている。:memo:**

>**「不変性は実際に使えるのか」**
ストレージとプロセッサ速度が無限にあれば不変性を活用できるが、現実的にはリソースは有限な為、ある程度の妥協が必要になる。

***

### 可変性の分離

不変性に関する最も一般的な妥協点
> アプリケーションまたはアプリケーションのサービスを「可変性コンポーネント」と「不変性コンポーネント」に分離することである。

- 可変性コンポーネント
    - 変数の状態の変更を許可している（純粋に関数的にタスクを行わない）コンポーネント

- 不変性コンポーネント
    - 可変変数を使わずに、純粋に関数的にタスクを行う
    - １つ以上の可変性コンポーネントと通信する

> 状態の変更により、これらのコンポーネントは並行性の問題に遭遇する可能性がある。したがって、変更可能な変数を並行更新や競合状態から保護するために、トランザクショナルメモリを使用するのが一般的である。

コンパイルエラー
```java=

private static final int C=9;
private AtomicInteger counter= new AtomicInteger(BigDecimal.ZERO);
public void fun(){
  var value = 1;
  IntStream.range(0,10).parallel()
  .map(i->this.run(i*value)
  .foreach(System.out::println);
}

private run(int i){
  // ACID原則に従って整合性を担保できるようなメモリ空間のことをトランザクショナルメモリと言ってそう。
  return counter.addAndGet(i);
}

```

```java=
 private synchronized int someMethod() {
     // ここに来れるのは1スレッドだけ
    return counter.replace(counter.get()*i+c);
  }
```


- トランザクショナルメモリ
    - データベースがディスクのレコードを扱うのと同じように、メモリ内の変数を扱う
    - プロセス内部に複数のスレッド処理が走っている場合ので、トランザクショナルメモリとは「スレッドに対して横断的なメモリ空間」の事を指す

***

### イベントソーシング

イベントソーシングによるコマンドクエリ責任の分離
![via https://de.wikipedia.org/wiki/Event_Sourcing#/media/Datei:CQRS.svg](https://i.imgur.com/1i8q1v8.png)

イベントソーシング:Event Sourcing:memo:
アプリケーションを実行した際のステータスのすべての変更がマッピングされ、一連のイベントとして記録するプロセスをイベントソーシングという。[via wikipedia](https://de.wikipedia.org/wiki/Event_Sourcing)

> :memo: Bitcoin(ブロックチェーン)もイベントソーシングの考え方 :memo:

本文に乗っていた内容は、取引結果を保持するのではなく、取引イベントを保持することが記載されていた。
また、無限のイベントを記録することの限界を超える方法として取引を行う期間を指定して、期間の終わりに状態を固定することで計算資源のリセットを行う方法があることも示されていた。

***

### まとめ


> - 構造化プログラミングは、直接的な制御の以降に規律を課すものである
> - オブジェクト指向プログラミングは、間接的な制御の移行に規律を課すものである。
> - 関数型プログラミングは、代入に規律を課すものである。

> 過去半世紀かけて我々が学んだのは、**何をすべきではないか**である

著者はプログラムの本質は以下の4つで構成されていると述べている。
> - **順次**
> - **選択**
> - **反復**
> - **間接参照**


***

## ふりかえり

### YWT
#### Y: やったこと
 - 「第６章 関数型プログラミング」の読了
 - IFの分離が依存関係逆転が分離した箇所は、ライブラリの分割ができる起点である可能性を見出せることを共有した。 
#### W: わかったこと
 - 下記問題は可変変数に原因がある
     - 競合状態
     - デッドロック状態
     - 並行更新の問題
 - 関数型プログラミングには変数という概念がない
 - （リソースは有限なので）「可変性コンポーネント」と「不変性コンポーネント」に分離することで、関数型プログラミングを実現している。
 - プロセス内部に複数のスレッド処理が走っている場合ので、トランザクショナルメモリとは「スレッドに対して横断的なメモリ空間」の事を指す事がわかった。:100::rocket:
 - John McCarthy の誕生日がniroさんと同じということが分かった。
 - はじめの関数プログラミングはLispであることを知った。
 - BTCと同じであることを知らなかった。
 - イベントソーシングのイメージをしっかり持てて良かった。

#### T: 次にやること
 - 第Ⅲ部 設計の原則
 - 第７章SRP: 単一責任の原則

***

### KPT
#### Keep
- 事前に書いておくことは時短になり有効
  - 事前準備パライムの導入
    - 進行の秩序が生まれた。
- 分からないことは分からないので、文章から読み取れることの範囲で十分わかることを分かっていく姿勢
#### Probrem
- アーキテクチャの**境界**などの概念を現状放置している状態。
- プログラムをダイクストラにはなぜか証明できなかったのか？
- クラス、モジュール、コンポーネントあらゆるレベルで構造化プログラミングの制限しているがその制限のルールはどのようなものか？
- 眠いのはやめたい。 
#### Try
- 疑問点のリスト化をしてすぐにアクセスして解消できるような仕組み
- KPTを次に持ち越すことで一旦対応
- 運動します。

***

### Fun-Done-Leanrn
#### Fun:
- a

#### Done:
 - a

#### Learn:
 - a

速度 
満足度 
進め方 
