Side Effect
===
就 7 個英文字母...
## 啥
> In the presence of side effects, a program's behaviour may depend on history; that is, the order of evaluation matters. Understanding and debugging a function with side effects requires knowledge about the context and its possible histories.
>
> from [Why Functional Programming Matters](https://www.cs.utexas.edu/~shmat/courses/cs345/whyfp.pdf)
> [name=John Hughes]
> from [Functional Programming Languages](https://web.archive.org/web/20220806155136/https://www2.cs.arizona.edu/~collberg/Teaching/520/2005/Html/Html-24/index.html)
> [name=Christian Collberg]
我含有過去的那個我, 以及這個世界的歷史, 我的一小個動作牽動世界的運轉.
- [Use or change global variable (函數外的變數)](#Use-or-Change-Global-Variable)
- [Edit parameters](#Edit-Parameters)
- I/O 操作
- Read/Write file
- Standard Input/Output
- Network I/O
- HTTP request
- DataBase
> 如果撰寫的 function 有接觸到那條`六角形的紅線`, 它就含有 side effect
>
> [name=我自己]

### Use or Change Global Variable
```java
public static class Global {
public int 我是一個不知道我是誰的Value; // default: 0
}
public class SideEffectClass {
public int add(int a) {
return a + Global.我是一個不知道我是誰的Value;
}
public void 我不知道(int a) {
// 先不論做了啥
Global.我是一個不知道我是誰的Value = a;
// 也許又搞了很多事
}
}
public class PureFunctionalClass {
public int add(int a, int b) {
return a + b;
}
}
public class Main {
public static void main(String[] args) {
var sideEffectClass = new SideEffectClass();
// 受到 Global variable 影響 (同樣的 input, 不一樣的 output)
int addResult = sideEffectClass.add(1); // 1
// Global variable 改變了, 世界也變了
Global.我是一個不知道我是誰的Value = 5;
int addResultButꐦಠ皿ಠ = sideEffectClass.add(1); // 6
// 影響別人
sideEffectClass.我不知道(10);
// ---------------------------------------------
var pureFunctionalClass = new PureFunctionalClass();
// 一直都是 3
int pureAddResult = b.add(1, 2); // 3
Global.我是一個不知道我是誰的Value = 3;
int value = Global.我是一個不知道我是誰的Value;
// 看起來受 Global variable 影響,
// 但實際上 B.add 不存在 side effect,
// 其實是 main function 存在 side effect
int maybeImpureAddResult = b.add(1, value); // 4
}
}
```
### Edit Parameters
```java
public class RequestContext {
public string 我字串 = "就是字串, 怎麼了 ?";
public int 也許是個讓人驚奇的數字; // default: 0
}
public class Main {
public static void main(String[] args) {
var context = new RequestContext();
// 我還純潔
System.out.println(context.也許是個讓人驚奇的數字); // 0
// 我就髒
Main.做事啊();
// 前一個步驟呼叫了一個 function,
// context 裡面的 variable 被玷汙了
System.out.println(context.也許是個讓人驚奇的數字); // 2147483647
}
private static void 做事啊(RequestContext context) {
// 我最 pure, 我就棒
// Edit parameter
int 希望能讓大家嚇一跳 = Integer.MAX_VALUE;
context.也許是個讓人驚奇的數字 = 希望能讓大家嚇一跳;
// I/O 操作
System.out.println(context.我字串);
// 反正已經出事了, 乾脆就髒到底吧
}
}
```
## So What
> Referential Transparent: It can be replaced with its corresponding value (and vice-versa) without changing the program's behavior.
>
> from [Concepts in Programming Languages](https://books.google.com.tw/books?id=7Uh8XGfJbEIC&dq=referential+transparency&pg=PA78&redir_esc=y#v=onepage&q=referential%20transparency&f=false)
> [name=John C. Mitchell]
- Pure Function
- Explicit
- Referential Transparent
- Impure Function
- Implicit
## Why So
- [Unit Test](https://hackmd.io/al6qaV0LSdGMk2SgPtF2Bw)
## 理論與實踐
理論派就是知道原理
卻什麼都做不出來
實踐派就是做出結果
卻沒人知道為什麼
.
.
.
小弟身為一個理論派與實踐派的完美融合
既什麼都做不出來, 也沒人知道為什麼
## 工作上遇到困難
小弟我: 問個問題, 程式碼寫的太爛怎麼辦 ?
せんぱい: 能跑嗎 ?
せんぱい: 能跑就沒問題
.
.
.
小弟我: 能跑是指 `Code 能跑`還是`我人能跑` ?
せんぱい: 有一個能跑就行