WindowsでClojure
鉄分豊富な人が遊びにやって来た。一泊して酒を酌み交わし親交を深めた訳であるが、翌日はどうすべ? って、話になったよ。そこはそれ、磁石に吸い寄せられるように、大宮にある 鉄道博物館 へ、行ってみようとあっさり決まった。実はおいらも行った事無いんだよね。(昔々、秋葉原と言うか神田の それには行ったけど)
ちょいっと早めに着いたけど、長蛇の列になってましたよ。列の大半は小さい子供さんを伴った家族連れ。 おいらみたいな、中年おじさん連は浮いていた。自動発券機で1000円のスイカもどきのカードを買って 改札を通りました。本物のスイカも勿論使えます。
家族連れのお目当ては、各種シュミレーターの予約券Getで、列を成してました。TDLみたいな雰囲気 ですな。おいら達は、まずは2階へ、一番乗りでした。壁に沿って、鉄道の歴史が展示されてて、思わず 昔にトリップしてしまいましたよ。そして、一角には、日本一大きいと言うジオラマ(鉄道模型)室が ありました。鉄道の一日を約10分に渡って解説してました。始発電車、始発新幹線が動き出し、夕刻には 夜行寝台の北斗星とかが動き、ああ、あれに乗って北海道まで行ったなあなんて思いだしました。 また、資料室は地味だけど、ヘッドプレート等がたくさん展示されてて面白かった。国鉄が終了する時 の、さおようなら国鉄(1987.3.31)、よろしくJR(1987.4.1)のプレートが感慨深いでした。
一階には、お召し列車の展示とかSLとかいろいろあって、全部乗ってみるとどのくらい時間がかかる のだろう? 連れは何度も来たいと申しておりました。12時から始まる、SL機関車の転回台運用は 必見です。途中で鳴らす汽笛が何とも言えないいい味を出してましたね。
昼は中で売っている駅弁を買って食べるべし。いろいろあって迷っちゃうぞ。いろいろ買ってお土産に するのもいいかも。おいらは、お土産に、石炭あられ(竹炭入りで石炭とそっくり、土産で一番人気とか)と、銚子 電鉄のぬれせんべいを買いました。連れは、2Fのショップでしか手に入らないというグッズ類を 大量に買ってましたよ。
WindowsでClojure
今までずっと歴史物をやっていたけど、そろそろ飽きてきたので現代に戻ります。暫く前にClojureが 1,1から1.2になりました。Wnidowsに入れている Clojure-Box でも、1.2にしようと思って、*.jarだけ1.2に入れ替えたのはいいんだけど、構成が変わって微妙な 警告が出てくるようになりました。このまま使っていてもいいんだろうけど、ちと気分が悪いので 新たに入れなおしました。 あの人 も始めたようですし、本も読み直しています。
で、どうせ整備するなら、少し使いやすいようにしようと、環境整備編に(性懲りもなく)走って しまうのでした。何するか? WindowsだってLein使いたいよね。Leinって、Clojure界のデブロイ 環境です。(あっ、正確には開発環境だけど、おいらは、出来上がったjarファイルをひとまとまりに して、Clojureも入っていないPCに持って行ける事に価値を見出しています)
github に行って、lein-win32.zipとleiningen-1.3.1-standalone.jarを落としてきて、適当なdirに両者を 入れ、Pathを通せば出来上がり。使い方と言うかサブコマンドは、Lein help すれば出てきます。
余勢を駆ってFreeBSDでも
やってみよう。Linuxでの解説はいろいろあるもんで。。。
問題は、Windows上にあるClojure-boxもどきをどう作るかです。emacsには便利な ELPA と言うのが提供されているので、今回はこれを利用する事にします。
まず上記の指示に従って、パッケージリストを取り寄せます。emacsを再起動してから M-x package-list-package すると、インストール可能なパッケージが出てくるので、swank-clojureと pareditの所で I を押します。(インストールするパッケージの選択)続いて X を押すと、実行 (インストール)されます。途中でエラーが発生するかも知れませんが無視しても大丈夫です。 これで、関連する便利パッケージも自動的に入ります。emacsでファイルを閲覧する時にキー操作が 面倒だと思ったら、ついでに less も入れておくといいです。M-x less-minner-mode すれば、emacsがless に変身してくれます。Windowsみたいな貧弱な環境だと超便利!
paredit-modeは、開き括弧に対する閉じ括弧(いわゆるコッカ)を自動で挿入してくれる 機能があります。また文字列を囲むダブルクォートも2つ自動で挿入してカーソルがその間に位置 してくれるので、カッコやダブルクォートの閉じ忘れを防止出来ます。設定は、.emacsに
(autoload 'paredit-mode "paredit" "Minor mode for pseudo-structurally editing Clojure code." t) (add-hook 'clojure-mode-hook (lambda () (paredit-mode +1))) (add-hook 'slime-repl-mode-hook (lambda () (paredit-mode +1)))
と書いておきます。
ついでに、leinも入れておくと吉。lein new project-nameした後、project-name-dir内に自動 生成される project.cljに
:dev-dependencies [[swank-clojure "1.3.0-SNAPSHOT"]]
を追加し、lein depsすると、便利機能が追加されます。
こうしておいて、lein swankした後で、emacsを起動し、slime-connect すると、便利です。
例題
clojure本もいいけど、もっと他にないかと探してみると
に、L5という面白いものが掲載されてた。試してみよっと。
試してみた。FreeBSDで作った L5.jar をWindowsへ持ってきて、サンプルを動かしてみたらちゃんと 動いた。これぞClojure(Java)の威力。(jarファイルのダブルクリックで、起動するなんて、ちょっと びっくりです。これって、leinが気を利かせてくれてるから?)
秋だから絵を描こう
(ns simple-plotter (:import (javax.swing JFrame JPanel ) (java.awt Color Graphics Graphics2D Image)) (:use (clojure.contrib def))) ;; This is an attempt to make graphics in clojure as simple as it was on a ZX ;; Spectrum. Let us count the whole maven/leiningen/cake-clojure-emacs-(require ;; 'simple-plotter) thing as being a one-time effort equivalent to persuading ;; one's father to buy a ZX Spectrum in the first place. ;; Define some colours to use: ;; java.awt.Color/GREEN -> simple-plotter/green (defmacro- defcolours [& colours] (list* 'do (map #(list 'def (symbol (. (str %) toLowerCase)) (symbol (str "Color/" (str %)))) colours))) (defcolours black blue cyan darkGray gray green lightGray magenta orange pink red white yellow) ;; Private machinery (defn- draw-lines [lines #^Graphics2D g2d xs ys] (doseq [[x1 y1 x2 y2 color] @lines] (. g2d setColor color) (. g2d drawLine (* xs x1) (* ys y1) (* xs x2) (* ys y2)))) (defn- render-lines-to-graphics [lines paper-color height width #^Graphics2D g w h ] (doto g (.setColor @paper-color) (.fillRect 0 0 w h)) (draw-lines lines g (/ w @width) (/ h @height))) (defn- primitive-repaint [plotter] (. (plotter :panel) repaint)) (defn create-plotter [title width height ink paper] (let [lines (atom []) height (atom height) width (atom width) paper-color (atom paper) panel (proxy [JPanel] [] (paintComponent [g] (proxy-super paintComponent g) (render-lines-to-graphics lines paper-color height width #^Graphics2D g (. this getWidth) (. this getHeight)))) frame (JFrame. title)] (doto frame (.add panel) ;; The extra space 2,32 is taken up by the window decorations ;; in GNOME. How to get that from the OS? (.setSize (+ @width 2) (+ @height 32)) (.setVisible true)) {:height height :width width :ink-color (atom ink) :paper-color paper-color :current-position (atom [0,0]) :lines lines :panel panel})) (defn- primitive-line [plotter x1 y1 x2 y2] (let [ink @(:ink-color plotter)] (swap! (:lines plotter) conj [x1 y1 x2 y2 ink])) (primitive-repaint plotter)) (defn- set-paper-color [plotter color] (swap! (plotter :paper-color) (constantly color)) (primitive-repaint plotter)) (defn- set-ink-color [plotter color] (swap! (plotter :ink-color) (constantly color))) (defn- set-current-position [plotter [x y]] (swap! (plotter :current-position) (constantly [x y]))) (defn- remove-lines [plotter] (swap! (plotter :lines) (constantly []))) (defn- make-scalars [points xleft xright ytop ybottom] (let [xmax (reduce max (map first points)) xmin (reduce min (map first points)) ymax (reduce max (map second points)) ymin (reduce min (map second points))] [(fn[x] (+ xleft (* (/ (- x xmin) (- xmax xmin)) (- xright xleft)))) (fn[y] (+ ybottom (* (/ (- y ymin) (- ymax ymin)) (- ytop ybottom))))])) (defvar- current-plotter (atom nil)) ;; ;; Public Interface (defn create-window ([] (create-window "Simple Plotter")) ([title] (create-window title 1024 768)) ([title width height] (create-window title width height white black )) ([title width height ink paper] (let [plotter (create-plotter title width height ink paper)] (swap! current-plotter (constantly plotter)) plotter))) ;;Makes a version of a function with an implicit first argument of plotter, and ;;a default version with no first argument is not supplied, and which uses ;;current-plotter instead. (defmacro ddefn [fnname args & body] `(defn ~fnname (~args (~fnname @~'current-plotter ~@args)) ([~'plotter ~@args] ~@body))) (ddefn plot [x1 y1] (primitive-line plotter x1 y1 x1 y1) (set-current-position plotter [x1 y1])) (ddefn cls [] (remove-lines plotter) (primitive-repaint plotter)) (ddefn plot [x1 y1] (primitive-line plotter x1 y1 x1 y1) (set-current-position plotter [x1 y1])) (ddefn draw [dx dy] (let [[x1 y1] @(plotter :current-position) [x2 y2] [(+ x1 dx) (+ y1 dy)]] (primitive-line plotter x1 y1 x2 y2) (set-current-position plotter [x2 y2]))) (ddefn line [x1 y1 x2 y2] (plot plotter x1 y1) (draw plotter (- x2 x1) (- y2 y1))) (ddefn ink [color] (set-ink-color plotter color)) (ddefn paper [color] (set-paper-color plotter color)) (ddefn scaled-scatter-plot [points xleft xright ytop ybottom scalepoints] (let [[xsc ysc] (make-scalars (take scalepoints points) xleft xright ytop ybottom)] (doseq [[x y] points] (plot (* (xsc x)) (* (ysc y)))))) (defn window [plotter] (swap! current-plotter (fn[x] plotter))) (ddefn get-height [] @(plotter :height)) (ddefn get-width [] @(plotter :width)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Examples (defn sine-example[] (create-window "sine") (cls) ;; sine graph (doseq [x (range 1024)] (plot x (+ 384 (* 376 (Math/sin (* Math/PI (/ x 512))))))) ;; axes (ink yellow) (plot 0 384) (draw 1024 0) (line 512 0 512 1024)) (sine-example)
上記をREPL画面に貼り付けると、お試しの正弦波が別画面に表示されます。
;; (use 'simple-plotter) (defn transform [[xx xy yx yy dx dy]] (fn [[x y]] [(+ (* xx x) (* xy y) dx) (+ (* yx x) (* yy y) dy)])) (def barnsleys-fern '((2 [ 0 0 0 0.16 0 0 ]) (6 [ 0.2 -0.26 0.23 0.22 0 0 ]) (7 [ -0.15 0.28 0.26 0.24 0 0.44 ]) (85 [ 0.85 0.04 -0.004 0.85 0 1.6 ]))) (defn choose [lst] (let [n (count lst)] (nth lst (rand n)))) (defn iteration [transforms] (let [transform-list (mapcat (fn [[n t]] (repeat n (transform t))) transforms)] (fn [x] ((choose transform-list) x)))) (def barnsley-points (iterate (iteration barnsleys-fern) [0 1])) (create-window "Barnsley's Fern" 350 450) (ink green) (scaled-scatter-plot (take 10000 barnsley-points) 50 300 50 400 100)
続いて、上記を貼り付けると。。。 色は秋色の方が良かったかしら?
初心(これでウブと読むんだってさ)でも clojure してみよう
ウブンツでもやってみんべぇ。
sudo apt-get install maven2 vi pom.xml mvn clojure:repl
たったこれだけで、Clojureを始められます。劣化したS式であるxmlを事前に準備するのが 面倒ですが。(下記をpom.xmlとして用意) 初回は、あれこれ御取り寄せするので、プロンプトが出てくるまで、ちと時間がかかります。なお、REPL は、ヒストリー機能付きになってるので、矢印キー等で過去に入力したS式を簡単に呼び出せます。
それから、事前にJDKを入れておくのをお忘れなく。Sunのやつでもopenなやつでも、お好きにどうぞ。 嗚呼、もうSunのJDKじゃ無いんですね。Javaの生みの親 James Gosling はオラクルを辞めちゃったし いろいろとごたごた してるみたいだし。ごたごたついでに、Lambada は λ にしてね。Clojureは、Lambdaの代わりを fn が 務めているよ。変わらない事がStatusというCLは、結局独自追加が祟って非互換性が生まれるんでしょうな。 だったら、最初から互換性なんて期待しなければいいのに。
話が逸れちゃったわい。FreeBSDで使ってるJavaは
[sakae@cdr ~]$ java -version java version "1.6.0_07" Diablo Java(TM) SE Runtime Environment (build 1.6.0_07-b02) Diablo Java HotSpot(TM) Client VM (build 10.0-b23, mixed mode, sharing) [sakae@cdr ~]$ javac -version javac 1.6.0_07
こんなのでした、って、普通の人には参考にならないよね。後、
mvn clojure:swank
お好みで、emacsから、M-x slime-connectするのもいいでしょう。
<project> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>hello-maven-clojure-swank</artifactId> <version>1.0-SNAPSHOT</version> <name>hello-maven</name> <description>maven, clojure, emacs: together at last</description> <repositories> <repository> <id>clojars</id> <url>http://clojars.org/repo/</url> </repository> <repository> <id>clojure</id> <url>http://build.clojure.org/releases</url> </repository> <repository> <id>central</id> <url>http://repo1.maven.org/maven2</url> </repository> </repositories> <dependencies> <dependency> <groupId>org.clojure</groupId> <artifactId>clojure</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>org.clojure</groupId> <artifactId>clojure-contrib</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>jline</groupId> <artifactId>jline</artifactId> <version>0.9.94</version> </dependency> <dependency> <groupId>swank-clojure</groupId> <artifactId>swank-clojure</artifactId> <version>1.2.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>com.theoryinpractise</groupId> <artifactId>clojure-maven-plugin</artifactId> <version>1.3.3</version> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>versions-maven-plugin</artifactId> <version>1.2</version> </plugin> </plugins> </build> </project>
MyMEMO: Swap CapLock and Control Key
REGEDIT4 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout] "Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,1d,00,3a,00,3a,00,1d,00,00,00,00,00
キーボード配列をWindows上で変更すると Windows キーボードレイアウトの変更。 これ、自分へのメモ。だったら、ここに書くなちゅうに!