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=我自己] ![](https://pica.zhimg.com/v2-2629549571cdedb42baba5bd0a53e2db_1440w.jpg?source=172ae18b) ### 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 能跑`還是`我人能跑` ? せんぱい: 有一個能跑就行