## 現代網頁前端與型別系統 ### caasih --- ## 型別系統讓我們可以⋯⋯ ---- ## a + b ```javascript= const add = (a, b) => a + b; ``` ```typescript= const add : (a: number, b: number) => number = (a, b) => a + b; ``` ---- ## a + b (callback) ```javascript= const add = (a, b, cb) => cb(a + b); ``` ```typescript= const add : (a: number, b: number, cb: (c: number) => void) => void = (a, b, cb) => cb(a + b); ``` continuation passing style ---- ## a + b (callback and currying) ```typescript= const add : (a: number) => (b: number) => (cb: (c: number) => void) => void = a => b => cb => cb(a + b); ``` ---- ## `Cont<number>` ```typescript= type Cont<T> = (cb: (x: T) => void) => void; const add : (a: number) => (b: number) => Cont<number> = a => b => cb => cb(a + b); ``` ---- ## adding different things ```typescript // XXX: type error const result = add(add(3, 4), add(5, 6)); ``` 我要怎麼 `add` 其他 `add` 的結果? ---- ## adding `Cont<number>`s ```typescript= const pure : <T>(x: T) => Cont<T> = x => cb => cb(x); const add : (a: Cont<number>) => (b: Cont<number>) => Cont<number> = a => b => cb => a(x => b(y => cb(x + y))); const result = add( add(pure(3), pure(4)), add(pure(5), pure(6)), ); ``` ---- ## adding `Promise<number>`s ```typescript= const add : (a: Promise<number>, b: Promise<number>) => Promise<number> = (a, b) => a.then(x => b.then(y => x + y)); ``` ---- ## `Anime<T>` ```typescript= type Anime<T> = (time: number) => T; const three: Anime<number> = (time) => 3; const twice: Anime<number> = (time) => 2 * time; const add : (ax: Anime<number>) => (ay: Anime<number>) => Anime<number> = ax => ay => time => ax(time) + ay(time); ``` ---- ## 用熟悉的方式處理新資料 --- ## ECMAScript 6 讓我們可以⋯⋯ ---- ### 巢狀的 `Promise` ```typescript= const a = Promise.resolve(3); const b = Promise.resolve(4); const c = a.then(x => b.then(y => x + y)); ``` ---- ### async/await - 語言層級的 CPS 變換 ```typescript= const a = Promise.resolve(3); const b = Promise.resolve(4); const c = await a + await b; ``` ---- ### React Hooks - UI lib 層級的 CPS 變換 ```typescript= const [a = 0] = usePromise(Promise.resolve(3)); const [b = 0] = usePromise(Promise.resolve(4)); const c = a + b; ``` ---- ## 讓巢狀的程式碼變好讀 --- ## 過度簡化的 React, Redux 歷史 ---- ### Functional Reactive Programming * [Functional reactive animation][frp](Conal Elliott & Paul Hudak, 1997) * 把事件流轉換成畫面流 * 描述怎麼組裝它們 * [Arrows, Robots, and Functional Reactive Programming][arrowized-frp](Yale Haskell Group, 2002) * 用更好懂的方式組裝它們 [frp]: https://dl.acm.org/doi/10.1145/258949.258973 [arrowized-frp]: http://www.cs.yale.edu/homes/hudak/CS429F04/AFPLectureNotes.pdf ---- ## React * [Flux][flux] - 單向資料流 * [Om][om] - immutable value 的好處 * [Elm][elm] - 用 FRP 做網站 * [Redux][redux] - Elm 的 JS 複製品? [flux]: https://facebook.github.io/flux/ [om]: https://github.com/omcljs/om [elm]: https://elm-lang.org/ [redux]: https://redux.js.org/ --- ## 現代網頁前端的工作流程 * 空間 * UX design * [storybook][storybook] - 可互動的文件 * 時間 * 描述行為 - [redux-thunk][redux-thunk], [redux-saga][redux-saga], [redux-observable][redux-observable] * 描述資料變化 - redux reducer, [XState][xstate] * 循序漸進,避免引入額外的複雜度 [storybook]: https://storybook.js.org/ [redux-thunk]: https://github.com/reduxjs/redux-thunk [redux-saga]: https://redux-saga.js.org/ [redux-observable]: https://redux-observable.js.org/ [xstate]: https://xstate.js.org/ --- ### 用像 DSL 的結構來描述應用程式行為 ---- ### redux-thunk ```typescript= type ThunkAction<Args extends any[], U> = (d: Dispatch, s: GetState) => (...args: Args) => Promise<U> ``` ---- ### redux-saga ```typescript= type Saga<Args extends any[] = any[]> = (...args: Args) => IterableIterator<any> ``` ---- ### redux-observable ```typescript= interface Epic< Input extends Action = any, Output extends Input = Input, State = any, Dependencies = any > { ( action$: Observable<Input>, state$: StateObservable<State>, dependencies: Dependencies ): Observable<Output>; } ``` --- ## 半路出家的侷限 ---- * 程式語言理論?可以吃嗎? * 不懂編譯器、直譯器 * 沒有系統化地比較過不同的程式設計典範 --- ## 未來? 上述技術都過時了 :( ---- * transpile to JavaScript * WebAssembly --- ## 過去? ---- * Server-side MVC (Model2) 很好 * 以元件為單位分工 * 留下升級空間 --- ## 謝謝大家 --- ## 一起寫 web --- ## Q&A --- ## What are React Hooks anyway? * Algebraic Effects * call with current continuation * [Why coroutines won’t work on the web][no-coroutines] [no-coroutines]: http://calculist.org/blog/2011/12/14/why-coroutines-wont-work-on-the-web/ --- ## 更多 FRP * [The Essence and Origins of Functional Reactive Programming](https://www.youtube.com/watch?v=j3Q32brCUAI)(Conal Elliott)
{"metaMigratedAt":"2023-06-15T10:09:08.164Z","metaMigratedFrom":"YAML","title":"現代網頁前端與型別系統","breaks":true,"contributors":"[{\"id\":\"7827bd06-2a37-46be-9f5c-7d5256d3702e\",\"add\":14123,\"del\":9444}]"}
    353 views