Clojure

JVM でホスティング

Clojure は JVM のタイプシステム、GC、スレッドなどを共有する、ホスト型の言語として設計されています。すべての関数は JVM バイトコードにコンパイルされます。Clojure は Java ライブラリの優れた消費者であり、Java への呼び出しに対してドットターゲットメンバー表記を提供しています。クラス名は完全に参照することも、インポートしたら非修飾名として参照することもできます。Clojure は、reifyproxy を使用して、動的に Java インターフェイスやクラスを実装することをサポートしています。

Java クラスにアクセスするのは、次のように簡単です。

(import '[java.time LocalDate])

(defn add-week ^LocalDate [^LocalDate date]
  (.plusDays date 7))

(defn day->str [^LocalDate date]
  (format "%s %s, %s" (.getMonth date) (.getDayOfMonth date) (.getYear date)))

;; infinite sequence of weekly dates, starting from today
(def future-weeks (iterate add-week (LocalDate/now)))

(map day->str (take 4 future-weeks))
;; ("JULY 24, 2017" "JULY 31, 2017" "AUGUST 7, 2017" "AUGUST 14, 2017")

以下は、もう少し複雑な例として、小型 Swing アプリです。

(import '(javax.swing JFrame JLabel JTextField JButton)
        '(java.awt.event ActionListener)
        '(java.awt GridLayout))
(defn celsius []
  (let [frame (JFrame. "Celsius Converter")
        temp-text (JTextField.)
        celsius-label (JLabel. "Celsius")
        convert-button (JButton. "Convert")
        fahrenheit-label (JLabel. "Fahrenheit")]
    (.addActionListener
     convert-button
     (reify ActionListener
            (actionPerformed
             [_ evt]
             (let [c (Double/parseDouble (.getText temp-text))]
               (.setText fahrenheit-label
                         (str (+ 32 (* 1.8 c)) " Fahrenheit"))))))
    (doto frame
      (.setLayout (GridLayout. 2 2 3 3))
      (.add temp-text)
      (.add celsius-label)
      (.add convert-button)
      (.add fahrenheit-label)
      (.setSize 300 80)
      (.setVisible true))))
(celsius)

celsius