Clojure

理念

客戶和利害關係人對業界標準平台(如 JVM)的效能、安全性與穩定性有大量的投資,且感到滿意。雖然 Java 開發人員可能羨慕動態語言的簡潔性、彈性和生產力,但他們對於在客戶認可的基礎架構上執行、存取現有的程式碼庫和函式庫,以及效能方面感到憂心。此外,他們在使用原生執行緒和鎖定時,面臨持續的並行處理問題。Clojure 是在這種情況下,以務實的動態語言設計為努力目標。它致力於成為一種通用語言,適用於 Java 適用的領域。它反映了這樣的現實:對於並行程式設計的未來,普遍且不受約束的變異必須消失。

Clojure 達到其目標的方法:採用業界標準的開放平台 - JVM;現代化一種古老的語言 - Lisp;透過不變的持久資料結構促進函數式程式設計;並透過軟體交易記憶體和非同步代理提供內建的並行支援。結果是強健、實用且快速。

Clojure 有一種獨特的方法來處理 狀態和身分

為什麼選擇 Clojure?

為什麼我要再寫一種程式語言?基本上是因為我想要

  • 一種 Lisp

  • 用於函數式程式設計

  • 與既有平台共生

  • 專為並行設計

而且找不到一種。以下是 Clojure 背後一些激勵人心的想法大綱。

Lisp 是一件好事

  • 經常被模仿/剽竊,但仍未被複製

  • Lambda 演算產生極小的核心

  • 幾乎沒有語法

  • 核心優勢仍然是程式碼即資料和語法抽象

  • 標準 Lisp(Common Lisp 和 Scheme)呢?

    • 標準化後創新速度慢/沒有創新

    • 核心資料結構可變,不可擴充

    • 規格中沒有並行

    • 已經有針對 JVM 的良好實作(ABCL、Kawa、SISC 等)

    • 標準 Lisp 是它們自己的平台

  • Clojure 是一種不受後向相容性約束的 Lisp

    • 將程式碼即資料範例擴充到映射和向量

    • 預設為不可變

    • 核心資料結構是可擴充的抽象

    • 採用一個平台(JVM)

函數式程式設計是一件好事

  • 不可變資料 + 一等函數

  • 透過紀律/慣例,始終可以在 Lisp 中完成

    • 但如果資料結構可以被變異,假設它不會被變異是很危險的

    • 在傳統 Lisp 中,只有清單資料結構是結構遞迴的

  • 純函數式語言傾向於強靜態類型

    • 並不適合所有人或所有任務

  • Clojure 是一種強調動態的函數式語言

    • 所有資料結構都是不可變且持久的,支援遞迴

    • 異質集合、回傳類型

    • 動態多型

語言和平台

  • VM,而不是作業系統,是未來的平台,提供

    • 類型系統

      • 動態執行和安全性

    • 函式庫

      • 抽象作業系統

      • 龐大的設施集

      • 內建和第三方

    • 記憶體和其他資源管理

      • GC 是平台,而不是語言,設施

    • 位元組碼 + JIT 編譯

      • 抽象化硬體

  • 語言作為平台與語言 + 平台

    • 舊方法 - 每種語言定義自己的執行時間

      • GC、位元組碼、類型系統、函式庫等

    • 新方法 (JVM、.Net)

      • 通用執行時間不依賴於語言

  • 為平台建構的語言與移植到平台的語言

    • 許多新語言仍採用「語言作為平台」的方法

    • 移植時,會有平台對平台的問題

      • 記憶體管理、類型系統、執行緒問題

      • 函式庫重複

      • 如果原始語言基於 C,某些以 C 編寫的擴充函式庫無法移植

  • 平台由客戶決定

    • 「必須在 JVM 上執行」或 .Net 與「必須在 Unix 上執行」或 Windows

    • JVM 已建立良好的記錄和信任度

      • 現在也開放原始碼

    • 需要與其他程式碼互操作

      • C 連結在現今已不足夠

  • Java/JVM 語言 + 平台

    • 並非原始故事,但其他 JVM 語言一直存在,現在受到 Sun 採用

    • Java 可能很繁瑣,表達力不足

      • 缺乏一級函式、沒有類型推論等

    • 呼叫/使用 Java 的能力至關重要

  • Clojure 是語言,JVM 是平台

物件導向被高估了

  • 源自模擬,現在用於所有事物,即使不適當

    • 由於 Java/C# 缺乏對其他任何事物的(慣用語法)支援,因此在所有情況下都受到鼓勵

  • 可變狀態物件是新的義大利麵條程式碼

    • 難以理解、測試、推理

    • 並發災害

  • 繼承並非實作多型性的唯一方法

  • 「讓 100 個函式對一個資料結構進行操作,比讓 10 個函式對 10 個資料結構進行操作更好。」- Alan J. Perlis

  • Clojure 將其資料結構建模為由介面表示的不變物件,否則不提供自己的類別系統。

  • 許多函式定義在幾個主要資料結構上(seq、map、vector、set)。

  • 在 Java 中撰寫 Java,從 Clojure 使用和擴充 Java。

多型性是一件好事

  • switch 陳述式、結構性比對等會產生脆弱的系統

  • 多型性會產生可擴充、彈性的系統

  • Clojure 多重方法將多型性與 OO 和類型分離

    • 支援多重分類

    • 透過靜態、動態或外部屬性、元資料等進行調度

並行處理和多核心未來

  • 不可變性解決了大部分問題

    • 在執行緒之間自由分享

  • 但改變狀態是模擬和程式中外部世界的代理的現實

  • 鎖定太難一次又一次地正確執行

  • Clojure 的軟體交易記憶體和代理系統執行困難的部分

簡而言之,我認為 Clojure 佔據了一個獨特的利基,作為一個具有強大並行處理支援的 JVM 函數式 Lisp。查看一些 功能開始使用 Clojure