Clojure

维基百科,自由的百科全书
跳转至: 导航搜索
Clojure
Clojure-glyph.svg
编程范型 多范型函数式
发行时间 2007
設計者 Rich Hickey
最新发行时间 1.5.1[1] / 2012年4月18日;2年前 (2012-04-18)
型態系統 动态类型强类型
啟發語言 Common Lisp, Erlang, Haskell, ML, Prolog, Scheme, Java
Platform JVM, CLR
作業系統 跨平台
許可證 Eclipse Public License
常用文件扩展名 .clj
網站 http://clojure.org

Clojure(發音類似"closure")[2]是一套現代的Lisp語言的動態語言版。它是一个函数式多用途的语言。

Clojure可以執行於Java虛擬機通用語言運行時以及JavaScript引擎之上。與其他Lisp一樣,Clojure認為程式即資訊en:Homoiconicity),同時擁有複雜的巨集。

语言哲学[编辑]

因为 Hickey 希望有一个提供函数式编程和并发的现代Lisp实现,所以他开发了 Clojure 语言。

語法[编辑]

Clojure 的語法和其他的Lisp一樣,都是建立在 S-expression 之上。

範例[编辑]

Hello world:

(println "Hello, world!")

定义一个函数:

(defn square [x]
  (* x x))
 
(square 5) ; return 25

使用Java Swing 库的 GUI Hello World:

(javax.swing.JOptionPane/showMessageDialog nil "Hello World")

用Clojure解数独的程序[编辑]

(def board
  [[5 3 0 0 7 0 0 0 0]
   [6 0 0 1 9 5 0 0 0]
   [0 9 8 0 0 0 0 6 0]
   [8 0 0 0 6 0 0 0 3]
   [4 0 0 8 0 3 0 0 1]
   [7 0 0 0 2 0 0 0 6]
   [0 6 0 0 0 0 2 8 0]
   [0 0 0 4 1 9 0 0 5]
   [0 0 0 0 8 0 0 7 9]])
 
(defn board-rows [board]
  (let [full-set (set (range 1 10))
        exists (mapv #(remove (partial == 0) %) board)]
    (mapv #(clojure.set/difference full-set (set %)) exists)))
 
(defn board-cols [board]
  (let [board-v (for [i (range 9)]
                  (map #(% i) board))]
    (board-rows board-v)))
 
(defn board-blks [board]
  (let [board-b (for [i (range 3)
                      j (range 3)]
                  (for [k (range 3)
                        l (range 3)
                        :let [x (+ k (* i 3))
                              y (+ l (* j 3))]]
                    (get-in board [x y])))]
    (board-rows board-b)))
 
(defn board-tofill [board]
  (vec (for [i (range 9)
             j (range 9)
             :let [v (get-in board [i j])]
             :when (== v 0)]
         [i j])))
 
(defn blk-ix [x y]
  (let [i (quot x 3)
        j (quot y 3)]
    (+ j (* i 3))))
 
(defn fill-cand [x y rows cols blks]
  (let [row (get rows x)
        col (get cols y)
        blk (get blks (blk-ix x y))]
    (clojure.set/intersection row col blk)))
 
(defn solve-sudoku
  ([tofill rows cols blks board]
     (if (empty? tofill)
       board
       (let [cands (for [i (range (count tofill))
                         :let [[x y] (get tofill i)
                               cand (fill-cand x y rows cols blks)]]
                     [i x y cand])
             [mk x y min-cand] (apply min-key #(count (peek %)) cands)
             tofill-update (vec (concat (take mk tofill) (drop (inc mk) tofill)))
             ]
         (when (not (empty? min-cand))
           (apply concat
                  (for [cand min-cand
                        :let [cand-set #{cand}
                              remove-cand (fn [s i] (update-in s [i] #(clojure.set/difference % cand-set)))
                              rows-update (remove-cand rows x)
                              cols-update (remove-cand cols y)
                              blks-update (remove-cand blks (blk-ix x y))
                              board-update (assoc-in board [x y] cand)
                              ]]
                    (solve-sudoku tofill-update rows-update cols-update blks-update board-update))))
         )))
  ([board]
     (let [tofill (board-tofill board)
           rows (board-rows board)
           cols (board-cols board)
           blks (board-blks board)
           ]
       (remove nil? (solve-sudoku tofill rows cols blks board))
       )))
 
(solve-sudoku board) ; result: ([5 3 4 6 7 8 9 1 2] [6 7 2 1 9 5 3 4 8] [1 9 8 3 4 2 5 6 7] [8 5 9 7 6 1 4 2 3] [4 2 6 8 5 3 7 9 1] [7 1 3 9 2 4 8 5 6] [9 6 1 5 3 7 2 8 4] [2 8 7 4 1 9 6 3 5] [3 4 5 2 8 6 1 7 9])

巨集[编辑]

作为一种Lisp方言,Clojure支持巨集 。下面的巨集將中缀表达式遞迴展開成Lisp的前缀表达式。

(defmacro recursive-infix [[x op y]]
  `(~op
    ~(if (seq? x)
       `(recursive-infix ~x)
       x)
    ~(if (seq? y)
       `(recursive-infix ~y)
       y)))

编辑器/IDE[编辑]

参考资料[编辑]

  1. ^ Google Discussiegroepen. Groups.google.com. [2013-03-10]. 
  2. ^ meaning and pronunciation of Clojure. Rich Hickey. [2012-04-20]. 

外部連結[编辑]

Wikibooks-logo.svg
您可以在維基教科書中查找此百科条目的相關電子教程: