ウェブ技術 デジタルトランスフォーメーション技術 人工知能技術 自然言語処理技術 セマンティックウェブ技術 深層学習技術 オンライン学習&強化学習技術 チャットボットと質疑応答技術 ユーザーインターフェース技術 知識情報処理技術 推論技術 Clojure プログラミング
前回までで、Clojureの環境設定からtemplateファイルの生成までを述べた。今回は、Clojureの特徴の一つであるreplとimmutableなデータについて述べる。
まずspacemacsを開き、「SPC」「f」「t」の順にkeyを押すで左側にファイル構成を表示、前回作成したtemplateであるmy-appのフォルダのsrc/my-app/core.cljを開く。次に「SPC」「m」「s」「i」の順にkeyを押す。replのサーバーが立ち上がり始める。しばらく待つとspacemacsのフッターのバーに[nreapl]Direct connection to localhost:xxxx establishedの表示が出ればREPLが開始する。
ここでClojureのREPLについて少し解説する。REPLとはRead-Eval-Print Loopの略で、日本語にすると入力・評価・出力のループとなるだろうか。Clojureの場合は先ほどのnreplというサーバーが立ち上がり、そこでコードの評価を行い結果を返す。全て関数から出来ている関数型言語である為、評価対象は全て「関数」と言うことになり、評価結果は関数に入力を入れた時の出力結果となる。
ClojureでのREPLを使った開発の流れは、
1.nREPLを起動、
2.エディタからnREPLに接続、
3.REPL 上で開発する名前空間に移動(前回のtemplateの(ns 〜)から始まるファイル、
4.名前空間上にあるコードの中で関数を選択しREPLに送信、
5.評価結果(出力結果)をnREPLガ送信し4で選択した関数の横に表示する。
6.表示結果に間違いがなければ保存して次の関数を評価する。
となる。コードを開発する際には最初から順番に関数を評価していくため、デバッグ確認も完了することになり、最後のmain関数に到達した時には全ての動作の確認が終わった状態となる。上記の仕組みがあることにより後戻りの少ない高速開発が可能となる。
ここでSpacemacs上でnREPLが立ち上がり、src/my-app/core.cljのコードが編集できる状態までもどる。
入力としてvimを選択しているため、一旦入力モードに設定する必要がある。入力したい位置までカーソルを移動させ、iまたはa keyを押すことで入力モードに変わる。後はコードを打ち込んでいくだけである。入力モードから出るには「ESC」keyを押せばよい。
実際にコードを入力する、例えば「( + 1 2)」右括弧の右側にカーソルを移動させ「CTRL」「c」「e」を同時に押すことで、左側にある括弧で包まれた関数をnREPLに送信し、評価結果が帰ってきて表示される。評価が問題なければ、出力結果「3」が表示され、関数のコードに何らかの問題がある場合にはエラーメッセージが表示される。その際には、エラーメッセージを見てコードを修正し再度評価する。
Clojureの特徴の一つに「データがimmutable」と言うものがある。例えばrubyのようなmutableなデータ構造を持つ言語の場合
irb(main):001:0> foo = [0, 1, 2, 3, 4, 5, 6, 7, 8]=> [0, 1, 2, 3, 4, 5, 6, 7, 8]irb(main):002:0> foo[6] = 9
=> 9
irb(main):003:0> foo
=> [0, 1, 2, 3, 4, 5, 9, 7, 8] # fooが変更されている
のように、最初に設定した変数fooが処理により変化してしまうのに対して、Clojureの場合は
user=> (def foo [0 1 2 3 4 5 6 7 8])
#’user/foo
user=> (assoc foo 6 9)
[0 1 2 3 4 5 9 7 8]user=> (println foo)
[0 1 2 3 4 5 6 7 8] ; fooは元のまま
nil
のように、変数foo自体は処理を行っても変化しない。データがmutableになると言うことは、複数のモジュールで変数にアクセスした時に、アクセスする順によってデータが異なることになり、複雑なモジュール構成になるとそれらの変化の”状態”を管理することが困難になってバグが生成しやすくなる。
Clojureの場合は、データが変化しないと言う前提でコードを組むためmutableなデータのコーディングに慣れた人には思考の変換を強いることになるが、immutableモードに慣れてしまうことで変数をコントロールするという恩恵を受けることができる。
それでは状態の変化が必要な場合はどうすればよいのか?というと、ClojureではSTM (Software Transactional Memory)とデータベースのトランザクション部に似た仕組みが準備されている。refとかatomとかの関数で表される変数を用いるもので、例えばatomでは
user=> (def my-atom (atom 0)) #'user/my-atom user=> @my-atom 0 user=> (swap! my-atom inc) 1 user=> @my-atom 1
のように、変化可能な変数としてmy-atomを定義し、それに処理を加えることでデータが変化していく仕組みとなる。ウェブUIの場合、直前の”状態”によって処理を変化させる(例えばボックスがチェックされているかどうかによってその後の処理が変わる)必要があり、このようなデータ構造が必要になる。
次回は、もうもう少し詳細なデータ構造の話について述べてみたい。
コメント
[…] 前回は、Clojureの特徴であるREPLとimmutableなデータについて述べた。今回はデータ構造について述べる。 […]
[…] ピンバック: Clojureについて(3) – Deus Ex Machina […]
[…] Clojureを始めよう(3) Replの利用とimmutableなデータ […]
[…] このようなケースでは”Clojureを始めよう(2)Replと基本プログラミング“でも述べたように、コードが膨大になってくると意図しない変数の変化を生じさせるため、最近のプログラミ […]