8
5

More than 5 years have passed since last update.

楽しいClojureの話

Posted at
1 / 13

これはなに?

沖縄で行われたハッカーズチャンプルー 2016の懇親会のLT大会で発表した資料です。


Clojureとは

  • Lisp方言のひとつ
  • インタラクティブな開発(REPL)
  • 関数型プログラミング
  • 並行処理をしやすい
  • 多様な実行環境(JVM、ClojureScript)

Lispの特徴

(str "カッコが多い言語です")

;; 関数をカッコの1番目に、2番目からあとにはその関数の引数をいれます
(+ 1 2 3 4) ; => 10

;; マクロを使って新しい文法を自分で追加できます
(defmacro unless [test then]
  (list 'if (list 'not test)
    then)))

(if true "then" "else") ; => "then"
(unless true "then" "else") ; => "else"


インタラクティブな開発(REPL)

スクリーンショット 2016-06-25 16.37.49.png


基本、不変なデータ(変数じゃない)

; シンボルにデータを束縛する
(def my-name "arakaki yuji")
my-name ; => "arakaki yuji"

; レキシカルスコープ内のみで一時的に束縛
 (let [my-name "yuji"]
   my-name) ; => "yuji"

; スコープ外には影響ない
my-name; => "arakaki yuji" 

; 文字
/a 

; 文字列
"Hello World"

; list(Lispのベースとなるデータ型)
(list 1 2 3) ; => (1 2 3)

; Vector(順番を持ったコレクション)
["a" 1 'hello \a]

; Map(キーと値を対応させたコレクション)
{:name "arakaki yuji" :age 27}

; Set(値が一意になること保証したコレクション)

; シンボル
(symbol "my-name") ; my-name

; 関数
(fn [n] (+ n 5))
; => #object[user$eval19622$fn__19623 0x243a2394 "user$eval19622$fn__19623@243a2394"]


関数が第一級オブジェクト

; 関数定義
(defn hello-world [name]
  (str "Hello World, " name))

; 関数が第1級オブジェクトなので引数で関数を返せる関数作れる
(defn add-factory [number]
        (fn ([] number)
            ([n & more] (apply + (conj more n number)))))

(def add-8 (add-factory 8)
(def add-100 (add-factory 100))
(add-8 2)
; => 10
(add-100 30)
; => 130


変更可能なデータもある

基本不変データのClojureですが、変更可能なデータ型もある。
それらは用途に応じて使い分けれるように複数あります。


変更可能なデータ型の種類

  • atom
  • ref
  • agent
; atom 
(atom x 1)
x ; => #object[clojure.lang.Atom 0x757c7948 {:status :ready, :val 1}]
;; 値を参照するには@をつける
@x ; => 1
;; 単独で値を変更したいデータの時に使う
(reset! x 5)
@x ; => 5

; ref
(def y (ref 1))
y ; => #object[clojure.lang.Ref 0x3fe68e45 {:status :ready, :val 1}]
;; 値を参照するには@をつける
@y ; => 1
; refは複数の値を協調して変更したい場合に使う
(def z (ref 5))
(dosync 
  (ref-set y 10)
  (ref-set z 20))
@y ; => 10
@z ; => 20

; agent
(def a (agent 1))
a ; => #object[clojure.lang.Agent 0x307b6b7e {:status :ready, :val 1}]
@a : => 1
; agentは非同期でデータを変更したい場合に使う
(send a + 100)
; => #object[clojure.lang.Agent 0x307b6b7e {:status :ready, :val 1}]
a
; => #object[clojure.lang.Agent 0x307b6b7e {:status :ready, :val 101}]


並行処理をしやすい

Clojure自体が並行処理を前提として設計されている

  • 不変なデータ型
  • 関数型プログラミングにより副作用を減らす
  • 並行処理をサポートする機能を複数用意

並行処理用の機能

まだちゃんと勉強できていないのでこんなのあるよ〜ぐらい・・

  • agent
  • thread
  • core.async
  • future

多様な実行環境

  • Clojure(.clj)

    • JVM上で実行される
    • Javaのライブラリを使用可能
  • ClojureScript(.cljs)

    • JavaScriptにコンパイルされる(AltJS)
  • 両方でコードを共有可能(.cljc)

    • フロントエンドとサーバーサイドでロジックを共有できる
    • 各動作環境の独自機能は共有できないので注意

最後に

Clojure楽しいがまだ自分は大きなアプリケーション書いたことはないので、これから書いていきたい。

もし他にも興味ある方がいれば一緒にやりましょう^^/

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5