Clojure

Clojure + Emacs でのシンボル補完を M-Tab ではなく Tab でやりたい。

swank-clojure(slime) を使うと REPL では Tab でシンボル補完してくれますが、ソースファイル内では M-Tab で補完になります。 インデントは C-i や C-j でできるので、ソースファイル内でも Tab キーひとつで補完したいです。 (add-hook 'slime-mode-hook …

Ubuntu 10.04 での Clojure + Emacs + Leiningen の環境構築

2011/12/29更新 時代遅れの手順になってしまいました。 Clojure+Emacsな開発環境を作る(late 2011) - λab's Blogを参照してください。 ネットブックにUbuntu 10.04 を入れたので emacs から Clojure を使う手順を最初の最初から書いてみる。2ヶ月ぐらい前に…

Clojure の式の評価を追跡するツール eyewrap

user> (cap (* 2 (+ (- 3 8) 4))) 0 : + (* 2 (+ (- 3 8) 4)) 1 : + (+ (- 3 8) 4) 2 : + (- 3 8) 2 :=> -5 1 :-> (+ -5 4) 1 :=> -1 0 :-> (* 2 -1) 0 :=> -2 -2 fatrow's eyewrap at master - GitHub式の返してくる値だけじゃなくて、中でどの式がどう評価…

cond をスリムにする condp

普通の cond (defn cond1 [x] (cond (= x :hey) "Hey!" (= x :bye) "Bye!" (= x :hi) "Hi!")) 重複するパターンがあります。condp を使うとスマートに。 (defn condp1 [x] (cond = x :hey "Hey!" :bye "Bye!" :hi "Hi!")) 次の例はちょっとトリッキーなので…

リストではなくシーケンスに入っている関数呼び出しも実行できる

macroexpand は展開結果をリストじゃなくてシーケンスで返してくるのにちょっと驚いた。 user> (macroexpand '(-> 1 (+ 2) (- 3))) (- (clojure.core/-> 1 (+ 2)) 3) user> (type (macroexpand '(-> 1 (+ 2) (- 3)))) clojure.lang.Cons user> (seq? (macroe…

無限にメモ化しない memoize

memoize で上限を設定できたらいいのになぁと思って、hackathonの時に作ってましたが Clojure Google Groupにそのものズバリのスレッドがありました。bounded memoizehttp://groups.google.com/group/clojure/browse_thread/thread/36a13d150d830683議論の末…

HTML と Clojure のコードを分離するテンプレートシステム Enlive

cgrand's enlive at master - GitHubEnlive は html と Clojure のコードを完全に分離できるのが特徴のテンプレートシステムです。つまり、テンプレート元の html はピュアな html であり、コードはピュアなClojureのコードなのです。デザイナーとプログラマ…

Clojure + Emacs のキーバインド

swank-clojureの機能なのかslimeの機能なのかclojure-modeの機能なのか知らないのですが。 M-. カーソル位置のシンボルを定義しているソースまで移動。jarの中のファイルも見れて便利! M-, 飛んでから戻る M-TAB 補完 (単にTABだけでいいと思うが特にカスタ…

Clojureでクラスパスを表示する

(use 'clojure.contrib.pprint) (pprint (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader)))) しょっちゅう必要になるのでこれ用の関数があってもいい気がする。 参考: Printing the class-path in Clojure

関数内だけで使うローカル関数定義は defn ではなく letfn を使う

ローカル関数のつもりで defn をネストさせても defn は動的にvarを作っているだけなので関数外からも見えてしまう。 user> (defn aaa [] (defn bbb [] 1) 1) #'user/aaa user> (aaa) 1 user> (bbb) 1 しかも遅い。 (defn aaa1 [] (defn bbb [] 1) 1) (defn …

標準入力ジャック *in* jack

*in* (System.io)からの入力を前提としてしまった関数(*in*がべた書きされている)があり、動作を見るために入力データをファイルから読み込みたい。綺麗なやり方は引数で入力先を渡してやることだが、関数のあちらこちらで入力を読み込んでいてそれを修正す…

Clojure のエレガントなところ

リスト、ハッシュマップ、ベクタ、集合のリテラルがある ;リスト (1 2 3 4) ;ハッシュマップ {:a 1, :b 2, :c 3} ;ベクタ [1 2 3 4] ;集合 #{1 2 3 4} よく使う基本データ型のリテラルがあるというのはソースコードに図が入ってるみたいで考えるよりも早く理…

無名関数で直にmapやvectorを返す時は #() ではなく fn を使う

user=> ((fn [x] [x x]) 1) [1 1] user=> ((fn [x] {:a x}) 1) {:a 1} fn が ok なので #() でもいけそうだと思ったが user=> (#([% %]) 1) java.lang.IllegalArgumentException: Wrong number of args passed to: LazilyPersistentVector (NO_SOURCE_FILE:0…

Clojure の シーケンスを python のスライスのように取り出す

(use 'clojure.contrib.test-is) (defn slice ([coll start] (let [start (max start 0)] (drop start coll))) ([coll start end] (let [start (max start 0)] (take (- end start) (drop start coll)))) {:doc "Extract a subsequencet like a slice of pyt…

character のシーケンスをStringに変換

こんなことでずっと悩んでた。apply str で解決。 user> (seq "abc") (\a \b \c) user> (str (seq "abc")) "(\\a \\b \\c)" user> (apply str (seq "abc")) "abc"

Clojure を emacs で

2010/5/6追記:ここの情報は古いので Ubuntu 10.04 での Clojure + Emacs + Leiningen の環境構築 を参照した方が良いと思います。 環境 Mac Snow leopard Carbon emacs 22.3.1まずここをそのままやれば emacsから使う事ができた。 http://riddell.us/tutori…