Lambda Calculus

楔子 這是一個在計算機歷史用數學演化的方式,具有代表性的規律。 Lambda (λ) Calculus Function Abstraction 能夠用簡單的方式來呈現函數 λx.x^2 + 1 用 js 來表示 let res = x => x * x + 1 Function Application 何謂 β-reduction(beta reduction) ? 就是把「值」代入取得最後的計算結果 let res = (x => x * x + 1)(3) 但有些情況不符合 curry 的表示法 λxy.x*y 就應該轉換成 (λx.(λy.x*y)) 但其實 ( ) 是可以被簡化的 λx.λy.x*y 如果先代入一個數值 5 (λx.(λy.x*y)) (5) = (λy.5*y) 再代入 7 (λy.5*y)(7) = 35 用 javascript 來表示 function product(x, y) { return x * y; } product(5, 7) //retuns 35 // curry function product (x) { return function (y) { return x * y; } } 參考資料...

May 21, 2022

寫給想跳坑的 JS 新手(Part II): coding style

楔子 上一篇提到了 map filter reduce,這三個是最常見的也是最常用的使用方法,為了讓「程式碼」易讀,可以改造一下長相方便讓人看的懂在做什麼,至於怎做的就交給專業的人去優化改善就好。 所以先至少讓別人看的懂自已在寫的東西優先,試想看看,如果你是看 code 的人,「看的懂」vs 「要花一點點時間去細看」這二種,哪一種比較好讀? 先做到至少菜端出來看起來想吃,至於好不好吃就再說囉。嘿嘿嘿 程式碼的味道 用個最簡單的例子,把一個數字 x3 之後再 +1,但當數字是 5時就返回原值 f(1) = 1 * 3 + 1 f(5) = 5 來寫出這個 f 但我們用不同的長相來看看 撒尿牛丸全部攪在一起 這個應該是大部份的程式羅輯,就是把資料拆開來一個一個處理。 function f(x) { if(x !== 5) { return 3 * x + 1 } else { return x } } 點點點到天邊 這個 coding-style 就像你打開一個箱子把東西拿出來,「動作」後再放回去,依序處理。 let box = x => ({f: f => box(f(x)), x}) box(1) .f(multi3) .f(add1) // {f: ƒ f(), x: 4} box(5) ....

May 20, 2022

寫給想跳坑的 JS 新手(Part I): map filter reduce

楔子 身邊有些朋友有不少會想試著寫寫程式,常常坊間書翻一翻看到物件的東西,很快的就把書放下了,慢慢的也就失去興趣了。 但其實怎讓這些朋友開始可以有些動手做也能跑出一些結果,那種成就感會讓人慢慢的親近寫程式(coding),不可否認物件導向語言統治了軟體界,但光要先學會這個觀念可能就讓人却步了。 以前有部電影「張三峰」有句台詞,怎「張無忌」問,怎學會這部武功?「張三峰」說:「忘掉就好了」。 其實函數式語言的「入門」蠻簡單的,就像小時候的數學,函數吃一些變數,跑出來一個結果,用這個方式寫寫東西就可以做一些小實務的作品,也很有成就感。 就讓我們試試吧.. Declarative 宣告式 vs. Imperative 命令式 命令式(Imperative)白話文就是要用電腦的角度去思考,怎把答案做出來。 如果相要把一連串的資料去掉一些特定值(前提條件就要知道何謂 for-loop),示範的程式碼大概會長成下面的樣子 function filter(array) { let newArray = [] for (let index = 0; index < array.length; index++) { const element = array[index] if (element !== null && element !== undefined) { newArray[newArray.length] = element } } return newArray } // use case: filter([0, 1, undefined, 2, null, 3, 'four', '']) // [0, 1, 2, 3, 'four', ''] 但如果是所謂的宣告(Declarative)式,就是使用 filter 函數(知道 map/filter/reduce....

May 19, 2022

Monad Compose

楔子 今天再來進階一下改寫 Monad compose Monad 特徵 of: a => M(a) 也有人叫 lift 或 type lift map: map 的 f :: a => M(b) 會變成 M(M(b)) flatten: M(M(b)) => M(b) Monad 有 flapMap 的概念 flatMap = Map + flatten : f(a).flatMap(g) => M(b) const MyMonad = value => ({ flatMap: f => f(value), map (f) { return this.flatMap(a => Monad.of(f(a))), }, }) Monad.of = x => Monad(x) Monad(21).map( x => x * 2)....

May 18, 2022

Monad vs Promise

楔子 來試著說明何謂 monad 這其實是數學的一個名稱,但撇開那些艱深的道理,試試來用 Promise 的例子來說明看看。 Function Compose 最原始的 compose 的觀念就是把多個 function 做組合 const x = 20 const f = n => n * 2 const arr = Array.of(x) const result = arr.map(f) 例如 echo 就是吃二個參數回傳一個 function const echo = n => x => Array.from({length: n}).fill(x) console.log( [1,2,3].map( echo(3) ) ) 例如 flatMap 就是吃二個參數回傳一個 function const flatMap = (f, arr) => [].concat(...arr.map(f)) const echo = n => x => Array.from({length: n})....

May 17, 2022

lens laws

楔子 在 functional programming 中要進行對 store 的設定時,可以用 lens 的方式來進行設定,如果就像一個吸管直接定位來改變值,進行值也可以用函數來取代。 lens laws laws view(lens, set(lens, store, a)) = a 如果你改變了 store 某個值之後再立刻利用 lens 來取 store 的值,二個會相等(白話的意思就是你改變了 store 的值再拿出來看就是那個值) set(lens, b, set(lens, store, a)) = set(lens, b, store) 如果你改變了 store 的值為 a 又立馬改變值為 b,等同於直接改變值為 b(白話的意思就是你把一個值設了二次,最後的結果是第二次的值) set(lens, view(lens, store), store) = store 如果你用 lens 拿了某個值出來再同時 set 在 store 的 lens 位置的值,store 和原來的一致(白話文就是你取個 lens 的值拿出來的值再設到同一個 lens,該 store 維持不變) const view = (lens, store) => lens....

May 15, 2022

function mixins

楔子 在公司的專案開發中,程式總會愈長愈大,會慢慢的到了一個程度難以理解,在開發的過程中也慢慢開始把程式做一些模組化的動作。 在程式的抽像化過程中,應該有二大派系很當使用,就是物件導向 & 函數式編程。通常會蠻常出現二個關鍵字 繼承(inheritance) 組合(composition) Mixins “Favor object composition over class inheritance” the Gang of Four, “Design Patterns: Elements of Reusable Object Oriented Software” 有一種說法所謂的 mixins 就是像冰淇淋甜筒一樣,想吃什麼挖什麼口味,只要甜筒有那個味道功能,甜筒就只是一個載具而以。 Object composition 在 javascript 內,物件可以塞 function ,這時就要利用到 Object.assign 這個方法。 const chocolate = { hasChocolate: () => true } const caramelSwirl = { hasCaramelSwirl: () => true } const pecans = { hasPecans: () => true } const iceCream = Object.assign( {}, chocolate, caramelSwirl, pecans ) console....

May 13, 2022

react rule of hook

楔子 React 改成 functional component 最方便用的方式,在整個 code syntax 也是簡潔,不過當新舊交換時,常常難免會有一些使用上的規範。 rule of hook 直接用 Tyler 的範例來標示 rule function Counter () { // 👍 from the top level function component const [count, setCount] = React.useState(0) if (count % 2 === 0) { // 👎 not from the top level React.useEffect(() => {}) } const handleIncrement = () => { setCount((c) => c + 1) // 👎 not from the top level React.useEffect(() => {}) } } function useAuthed() { // 👍 from the top level of a custom Hook const [authed, setAuthed] = React....

May 10, 2022

React.createElement vs ReactDOM.render

楔子 最近小夥伴問了,React 的 jsx 基本的結構長如何,是如何轉換的之類的,順便記錄一下網路大神的資料摘錄。 React 有一個 createElement 的方法可以把資料轉成 react 特殊的結構 React.createElement('div', props={}) 收到特殊的結構之後再由 ReactDOM.render 來進行放在 html 上的位置 ReactDOM.render(jsDOM, document.getElementById('root')) React Basic React vs ReactDOM 摘錄一些 Kent 的示範 code 來演示一下,element 1 ~ 3 就是各種 jsDOM 的寫法,比較特別的是 React.createElement 可以有 2 ~3 個輸入參數 第一個參數指的是 HTML 的 DOM 種類(eg. div span …) 第二個參數輸入的是該 DOM 的 props 第三個參數輸入的是 children const element1 = React.createElement('div', {className: 'container'}) const element2 = React.createElement('div', {className: 'container'}, 'Hello', '', 'World') const element3 = React....

May 9, 2022

callback promise async/await

楔子 同樣的 javascript 針對所謂的 async 有其發生的歷史變革,有興趣的可以去找找影片了解一下。 callback 一開始採用的方式就是使用一個 callback function,因為 javascript 可以把 function 當參數丟入另一個 function,就有了最原始的模式,基本的概念就是 function executeFunc(callbackFun) { // some async function call callbackFun() } 題型: 請使用 setTimeout 來寫一個 1秒後 console.log(100) 的 callback function case // step 1. define function to run function go(){ // step 2. use setTimeout callback function to run after 1 sec setTimeout(()=> { // step 3. write console 100 }, sec) } // step 4. run the function go() 比對一下結果…...

May 4, 2022