Sunday, February 18, 2018

讀 kibit static code analyzer

Clojure 的 kibit static code analyzer 可以掃瞄你寫的程式碼,並且做比對,如果發現有更好的寫法,它就會提供你做為參考。很多初學者容易寫的「冗餘表達法」,都會被 kibit 抓出來。

比方說:
(= 0 x)  就會被 kibit 建議改成  (zero? x)

我一時興起,下載了 kibit 的 source code 來研究之後,腦子裡立刻充滿了一大堆問號。經過歸納之後,我把這些自己問自己的問題,歸納了一下。首要的問題,當然是「kibit 是如何實現的?」

這個問題可以拆解成下列的幾個問題:
(1) 我們寫的程式碼,是如何被 kibit 讀入,以什麼樣的資料型態儲存?
     clojure 的 source code 被 kibit 讀入之後,刻意以 unevaluated form 的形式,視為是 list 的 data structure ,而不是字串。之後,就用 tree-seq 將 list expression 拆解成「子樹」,即 sub form 。

(2) kibit 裡的 rules 是怎麼呈現的?
      kibit 裡的 rules 可以寫成 vector 的形式。比如: [(= 0 ?x) (zero? ?x)]
      其中, ?x 的部分,是可以用來做 binding 的部分。   

(3) 用什麼 library 來做「模式比對」?
      使用 core.logic 這個 library 來做 unification
      就我個人的看法,其實沒有使用 core.logic 大部分的功能,所以如果改寫的話,說不定可以用 core.unify 來替代掉。

這邊一句話簡單介紹一下 core.unify 這個 library 主要的功能: unification 
Unification is the process of taking two expressions and substituting all of the variables with matching concrete expressions.

範例:
(unify/unify '(= 0 aa) '(= 0 ?x))
;; => {?x aa}

Friday, February 9, 2018

Http API 使用 query string / header 來傳送 json

公司的一隻 http API 的設計是這樣子:
(1) 會接受 http POST
(2) http body 是 xml
(3) 其它的 meta data 是透過 query string 來傳遞。

meta data 的參數有一些是字串、有一些是整數。然而,API 端將這些 query string 解析出來的時候,資料型別的資訊卻早已不復存在,全都變成了字串。這是因為 http query string 並沒有支援資料型別的表示法。

那…是否可以把資料先用 json 來表示,再將 json 塞進其中一個 query string 又或是 http header 呢?如此發送端就可以把資料的型別也一併送到接收端了。

查了 stackoverflow 之後,這些問題也有人討論了,建議的解法如下:
(a) 如果 json 要放入 http header 的話,json 先做 base64 編碼,再放入 http header 。JSON web token 就是使用 base64
(b) 如果 json 要放入 query string 的話,json 先做 URLencode ,再收入 query string 。但是,必須要注意 URL 長度限制的問題。