Sunday, November 22, 2020

研究 Monad 的心得

學了 Clojure 再來學 monad ,彷彿像是學了英文之後,再來學日文。表達同樣的語意,但是,用不同的方式表達。

一 monad 用來幹嘛?

monad 用來夾帶 context 。什麼是 context ?基本的概念有點像是,本來是「值」語意,加上了 context 就變成了「向量」語意。


二 如何定義 monad

定義一個 monad 就是要定義兩個 operations
(1) unit 或是稱之為 return 。
     這個 op 接受一個 value ,傳回被 monad 修飾過的 value (monadic value)

(2) combine 或是稱之為 bind。
     這個 op 接受一個 monadic value 和一個可以接受 ordinary value 的函數。這個 op 的作用就是組合上述兩者,於是就可以得到一個可以處理 monadic value 的新函數。

三 常見的 monad 所處理的問題集合

(1) Maybe monad 
     在 Clojure 的世界裡,比較好的 modeling 沒有值的方式,並不是使用 nil 。 而是使用 vector 或是 hashmap 來 modeling 真實世界的 entity 。如果用 vector 或是 hashmap 來做 modeling 的話,有時候根本不用判定 nil ,也就是 Maybe monad 完全不需要。

(2) List monad
     處理 mapcat 可以處理的問題。

(3) Reader monad
      處理 dependency injection 可以處理的問題。 

Sunday, November 15, 2020

Some database-related quotes

* SQLite is not a replacement for PostgreSQL. SQLite is a replacement for fopen()


* We should call NoSQL databases as Postmodern Databases because they are:

  1. Absence of objective truth

  2. Queries return opinions rather than facts


* NoSQL databases that only have weak consistency are enforcing a broadly applied premature optimization on the entire system.

Tuesday, September 8, 2020

npm lockfile

話說,長久以來,我在開發 nodejs/javascript 的 project ,都有一個問題。到底需不需要把 package-lock.json 放進 source control 裡?

總是感覺需要,但是常常 npm install 的時候,這個  package-lock.json  就會大改。讓我覺得也滿困擾的。總覺得好像並沒有真的 lock 下來?

原來我少學了一個指令 npm ci

npm ci 的功能,就是可以嚴格地依賴 package-lock.json 來安裝套件。如果真的需要昇級才能裝的話,它就會丟出 error 。

Tuesday, August 11, 2020

讀書心得 --- 什麼才是經營最難的事

作者是安霍創投的經營者, Ben Horowitz 。書裡的內容,看起來,雖然也有引述許多經營管理書的論點,但是,最精采的部分,則是作者獨到的心得。對我來說,書中有一些點,是我不曾在其它書看到過的。以下列出幾點:

1. 人資的功能

長久以來,我也想不清楚,人資是用來幹嘛的?好像重要、又好像不重要。書裡給了一個簡單、清楚的概念:產品品質靠品保、管理品質靠人資。人資就是用來確保管理的品質的,是用來防止人事管理的環節,有任何一環嚴重出錯的功能。

2. 先管人、再管產品、最後才管利潤

作者主張要「必須」打造優良的工作環境。當公司的營運順利時,公司是否是依靠快樂的員工、優良的工作環境來達成利潤,也許沒有很明顯的差別。然而,當公司營運不順時,如果沒有優良的工作環境,優秀的員工就會快速離職,公司的營運會雪上加霜。而經營公司,一定會有營運不順的時刻。也因此,打造優良的工作環境,是目的而不是手段。

3. 員工訓練

Why?
有至少四個理由,應該實施「員工訓練」:生產力、產品品質、績效管理、員工留任。

績效管理是一般公司很容易欠下管理債的地方。在員工訓練時,就應該清楚設定好績效目標。等到真的需要開除員工時,就容易說清楚,為何沒有達成績效目標。

一般員工最常見的離職理由,除了經濟因素之外,往往不外乎兩個原因:
1. 討厭主管 - 主管不懂得帶人、不管屬下的職涯發展、不知道應該給予回饋。
2. 學不到東西
而員工訓練可以同時解決上述兩大問題。

How?
員工訓練應該要分成兩大主軸:職能訓練 (functional training) 與管理訓練。做得好的話,對於員工的士氣也極有幫助。

如何讓主管一定會落實員工訓練呢?最大的障礙往往是觀念問題,很多人覺得員工訓練太浪費時間。最有效的作法:要主管先訂出一套待聘人員的培訓計畫,否則遇缺不補。


Wednesday, July 8, 2020

Neovim + Conjure

友人推荐我試用看看 Neovim + Conjure 來取代 vim + fireplace 。我試了之後,覺得整體而言,算是又改進了一些些,這邊簡單記錄一下 Conjure 的用法。

主要會使用到的 Conjure 指令:
:ConjureEval [code]                類似 fireplace 的 cqp
<localleader> ee    // evaluate the form under the cursor.  (e 是 inner 的諧音)
<localleader> ece  // Evaluates the form under the cursor and displays the
                         result as a comment at the end of the line or below
                         the current line if you already have a comment there.
<localleader> er    //  evaluate the root form under the cursor. (r 是 outer 的諧音)
<localleader> e!     // evaluate the form under the cursor and replace it.  (! 意指 side effect)

類似 fireplace     :Require 的功能,重新載入整個檔案。
<localleader> eb   // evaluate the current buffer
<localleader> ef    // evaluate the current file from disk

快速檢查特定變數的『值』
<localleader> ew   // evaluate the current word
<localleader> ecw  // Evaluates the word under the cursor and displays the
                         result as a comment at the end of the line or below
                         the current line if you already have a comment there.

開啟 log buffer  的指令
<localleader> ls            // 水平開啟
<localleader> lv           //  垂直開啟
<localleader> lq           //  關閉


看文章、切換到定義
K                               //  Look up documentation for the word under the cursor.
<localleader> gd          //  跳轉到定義

貼上最後一次 evaluation 的結果。 ( 與 nvim register 的『組合功能』)
"cp                            // 上一次 evaluation 的結果會自動存放在 "c 這個 register 裡。
:reg                           // 可以顯示所有的 registers 的內容

對某一特定的 expression 遠端求值。 (與 nvim mark 的『組合功能』)
mf                               // 標記「位值」於 mark f 
<localleader> emf          // 對 mark f 的 expression 做求值。

對被反白的區塊 expression 做求值。 (與 nvim 反白選取的『組合功能』)
<localleader>E              // evaluate visual selection 

應用於 ClojureScript + shadow-cljs
:ConjureShadowSelect [build-id]        // 啟動 cljs repl ([build-id] 是 symbol 非 keyword)
:ConjureEval :cljs/quit                       // 關閉 cljs repl

Thursday, June 18, 2020

劃分 software components 的指導原則 -- From Clojure Applied

We separate our code into components for several reasons:

  1. reuse of generic components within an application
  2. dividing development within a team
  3. dividing development within a structure that allows us to think about only part of the problem at a time 

Guidelines to group code together to separate software components:

  1. the functions work on the same kind of data
  2. the data has a common scope or lifetime
  3. the likelihood of change from external requirements is similar
  4. the resources needed are similar

Friday, June 5, 2020

rules of abstraction

在開發軟體的過程中,總是會有幾回,一不小心失手,寫了失敗的 abstraction 。然後,日後再來痛苦地修正。比方說,把這個 abstraction 放棄掉,先變成大量、重複的程式碼,再來觀察規律,重新提鍊。

那有沒有什麼法則,可以用來提醒自己,做簡單的 checklist ,避免自己寫出糟糕的 abstraction 呢? 有的。

rule 1: Wait until the code is repeated three times before you extract it.
rule 2: If you can't think of a good name for your abstraction, it is probably not a thing.
rule 3: Understandable and reusable abstraction is usually less than 10 lines.

法則 1:重複三次才提鍊
法則 2:想出好名字才提鍊
法則 3:一個容易理解、可以重用的抽象,往往少於 10 行。


仔細想想,為什麼寫好 function 是如此的困難呢? 大概是因為我們同時做了三件事吧:

  • invent a new purpose
  • invent a new implementation
  • name it