iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 1
2
Big Data

資料科學:使用 Clojure系列 第 1

Day 01 - Clojure 基礎知識(一)

Clojure 是一種動態的、強類型、執行在 Java 虛擬機(JVM)上的 Lisp 方言。目前算是函數式編程(functional programming)領域內一個挺熱門的語言選擇。這個系列的目的是通過介紹 Clojure 高表達力的語言風格、先進的庫(library)、及無縫使用 Java/JVM 生態系豐富的類庫來展示 Clojure 在大數據領域的優勢。

Clojure 長甚麼模樣?

在《Programming Clojure》簡體中文翻譯的譯序中,作者提到了 Java code 跟 Clojure code 的差別。關於原問題請見淘宝面试题:如何充分利用多核CPU,计算很大的List中所有整数的和,而 Clojure code 則在這篇回文中被提出几行代码解决淘宝面试题之 Clojure 版,解答程式碼長的如下:

(defn mysum2 [coll  n]
    (let [sub-colls   (partition n n [0] coll)
          result-coll (map #(future (reduce + 0 %)) sub-colls)] 
         (reduce #(+ %1 @%2) 0 result-coll))) 

使用了 map / reduce 以及併發函數,輕易的把這題解決!這就是 Clojure。

參考讀物

  • 基礎知識部分:主要是一份網路上免費的教材《Clojure for the Brave and True》的摘要。這份教材可以幫助我們迅速打好 Clojure 的基礎,並且讓我們有信心操作 Incanter 庫及更進階的工具。這部分有五章。
  • 主體部分:《Clojure for Data Science》,我會利用二十個章節將這本書看完。
  • 最後五章則會介紹:
    1. 生態圈與社群介紹
    2. 《Clojure Data Science Cookbook》 概觀
    3. 在量化金融內的 Clojure 應用
    4. Clojure 的參考資源
    5. Clojure 學習查核表

執行環境

  • Windows
    • 首先安裝 JDK 環境:到 Oracle 官網 下載 Java SE Developmnet Kit.
    • 接著到 Leiningen.org 下載 Windows Lein 安裝程式
    • 接著就有完整的 Clojure 管理器可用了!
  • macOS 及 Linux
    • 一樣是通過系統的指定方法安裝 JDK。Linux 有些自帶 OpenJDK 那也可以。
    • Leiningen.org 參考只是把 script 放到 $PATH
  • 開啟終端環境,輸入 lein help 就會開始下載 Clojure 的 jar 檔案及其他必要基礎檔案了!

Leiningen

Leiningen,簡稱 Lein,是一個用以管理 Clojure 套件版本的程式。對應的 Java 工具是 Maven。如果專案中有用到 Java 的函式庫,也可以使用 Lein 來管理!

  • lein new <project name> <template name>:專案起手式。template name 非必須,不過有人會把特定類型軟體的專案結構及必要庫包裝成專案檔,例如用來寫 web app 的 ring 或者一些資料庫軟體應用。
    • 專案建立後,存在有一個 project.clj,裡面有依賴的庫、編譯參數設定、專案 metadata 等。
    • 沒有寫在 project.clj 中的庫,是沒辦法 include 的喔!這點跟 Javascript 有像。
    • Lein 的另一替代方案是 Boot
  • 專案建立後,需要使用 lein deps 來更新專案所依賴的 Clojure 及庫。注意:Clojure 其實不是一個安裝檔,而是一個 Java 程式及一大堆 Java class!所以,每次建立專案後,可以選擇合適的 Clojure,例如穩定的 1.6、1.7 或者是 beta 中的版本號。
  • lein repl 會開啟一個本專案專屬的 REPL,可以從該 REPL 中快速存取 src 資料夾中的程式碼及函式庫。
  • lein run 如果有寫好編譯方式,會通過此程式將專案執行起來。例如,專案是 web app 則會啟動 server。

《Clojure for the Brave and True》

提示各章節重點,接下來各章也是以提示加重點筆記為主,不做書摘

  1. 第一章
    1. 基本語法:這邊要掌握基本的 S-expression 寫法
    2. 資料結構:在應用上,最常使用的資料結構是方便好用的 map
    3. 函數
      1. 重要的函數定義:(defn func-name [argv] (body))
      2. 解構參數的方法(destructuring)及函數重載的方法。
      3. 函數式編程的重要工具 mapreduce 函數
      4. 兩種匿名函數的寫法。比較實用的短寫法是 (#(func % ...) argv)
    4. let 如何通過它建立局部變量環境
    5. Clojure 中的正則表達式(regular expression)
    6. recur 的語法:用遞迴的寫法寫出能被傳換為讓 JVM 以迴圈執行的 bytecode。
  2. 第二章
    1. 抽象的內部結構(sequence)以及 Clojure 是如何用這種結構表達四大類資料結構
    2. 強化版的 car/cdrtake, drop
    3. 用來過濾資料:filtertake-whiledrop-while
    4. 惰性序列(lazy sequences)及無窮序列(infinite sequences)
    5. 資料操作函數:intoconj
    6. 函數操作函數:applypartial

函數重載(arity overloading)

函數可以根據參數種類選定不同的函數實體進行運算。最初步的用途就是可以大幅單純化函數結構,而不用輸入一個 list 再判斷數量,套用到複雜的 if 結構中。

(defn multi-arity
  ([f-arg s-arg t-arg] (do-thing f-arg s-arg t-arg))
  ([f-arg s-arg] (do-thing f-arg s-arg))
  ([f-arg] (do-thing f-arg)))

正則表達式

Clojure 的正則是直接呼叫 Java 的核心函式庫。

(defn matching-part
  [part]
  {:name (clojure.string/replace (:name part) #"^left-" "right-")
   :size (:size part)})

(matching-part {:name "left-eye" :size 1})
; => {:name "right-eye" :size 1}

take-while

可以用來做複雜的遍歷、篩選器。或者直接使用

(take-while #(< (:month %) 4)
  (drop-while #(< (:month %) 2) food-journal))

下一篇
Day 02 - Clojure 基礎知識(二)
系列文
資料科學:使用 Clojure30

尚未有邦友留言

立即登入留言