Created
November 11, 2011 18:47
-
-
Save alphaneet/1358834 to your computer and use it in GitHub Desktop.
プログラミングClojure 勉強メモ 第1章 Getting Started. つhttp://d.hatena.ne.jp/alpha_neet/20111112/1321086082
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; defn で関数の定義。引数は [] で囲む | |
(defn hello-work [a, b] | |
;; format を使うと printf ライクに書ける | |
(println (format "hello work %s %s" a, b))) | |
;;; 純粋 Lisp は空白を区切りとして扱うが、Clojure は「 , も空白として扱う」らしい | |
;;; 下記は両方とも意味は同じ | |
(hello-work "comma", "test") | |
(hello-work "space" "test") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; 値に名前を付けるには def を使う | |
;;; def は defn の違いは後述 | |
(def PI "3.14なんちゃらかんちゃら") | |
(def Num 12345) | |
(def Persons ["dani-" "joni-" "annjero"]) | |
(println PI) | |
(println Num) | |
(println Persons) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;;; 関数型言語では「変数(副作用があるデータ)」は基本的には使わないが、 | |
;;;; 純粋でない関数型言語である Clojure(Lisp) では変数を扱うことが出来る。 | |
;;;; しかし常にトランザクション(doSync)内でしか変更することが出来ない。 | |
;;;; だが、これにより常に並行プログラミングになっている(はず) | |
;;; 変数の定義には ref(リファレンス)を使用する | |
;;; Integer | |
(println (ref 0)) | |
;;; String | |
(println (ref "")) | |
;;; Vector | |
(println (ref [])) | |
;;; Set | |
(println (ref #{})) | |
;;; リファレンスに名前を付けるにも def を使う | |
(def kazu (ref 0)) | |
(def moji (ref "")) | |
(def bekuta (ref [])) | |
(def setto (ref #{})) | |
;;; alter は Java とかでいう = のようなもので代入(破壊的更新) | |
;;; トランザクション(doSync)を噛ませてない代入は例外が出る | |
;;; (alter kazu + 3) ; <= java.lang.IllegalStateException: No transaction running | |
(println (dosync (alter kazu + 3))) | |
;;; str は与えられた引数をくっつけて文字列にする関数 | |
(println (dosync (alter moji str "oppai"))) | |
;;; conj は要素を追加する関数 | |
;;; よく分からないが型は大分柔軟っぽい | |
(println (dosync (alter bekuta conj 1 1 2 "oppai" 2 3 4))) | |
;;; #{} は Set なのでユニークな値で満されている | |
(println (dosync (alter setto conj "hoge" "hoge" "moge" 1 2 2 2))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; defn は必ず引数を取らないと例外が出る | |
;;; (defn hoge (println "test")) ; <= java.lang.IllegalArgumentException: Parameter declaration println should be a vector | |
;;; def は逆に引数があると例外が出る | |
;;; (def moke [a] (println "aiueo")) ; <= java.lang.Exception: Too many arguments to def | |
;;; def は定義時に評価されるが、defn は呼び出し時に評価される。 | |
;;; def(clojure) は val(scala) で defn(clojure) が def(scala) のような感じっぽい。 | |
(println "===== 定義") | |
(def a (println "--- def")) | |
(defn b [v] (println "--- defn")) | |
(println) | |
(println "===== 呼び出し") | |
(println a) | |
(println b) ; 関数オブジェクトを取得してる感じだろうか? | |
(println (b "v")) ; 括弧を付けると関数呼び出し |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; 別のファイルを読み込む時は require を使う。 | |
;;; ファイルを $CLASSPATH の中から検索する。 | |
;;; 名前に - を使用した場合、実際のファイル名の方は _ にするっぽい。 | |
;;; 複数該当があったらどうなるのか謎 -> 多分例外 -> 調べるのめんどかったれす^q^ | |
(require 'no-ns) | |
;;; だと $CLASSPATH/no_ns.clj を読み込む。 | |
(println hatarake) | |
;;; ディレクトリを潜りたかったら . で区切る | |
(require 'libs.dir-test) | |
;;; だと $CLASSPATH/libs/dir_test.clj を読み込む。 | |
(println oppai) | |
;;; java の package っぽく ns で名前空間を付けることが出来る | |
;;; ns は name space の略だと思われ | |
(require 'libs.use-ns) | |
;;; 使用する時は 名前空間名/関数名 にする | |
(libs.use-ns/echo "aiueo") | |
;;; requireパス と namespace名 は言語仕様上は同じでなくても動くっぽい | |
;;; でも明らかに慣習として namespace の位置にファイルを配置すること推奨っぽい | |
(require 'libs.tekitou) | |
(println nandemoii/shinpi) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; 毎回 namespace/function と書くのがめんどくさい場合は require の後に refer を呼ぶ | |
(require 'refer-test) | |
(println refer-test/kazu) | |
(refer 'refer-test) | |
(println kazu) | |
;;; use を使えば require と refer を同時にしてくれる | |
;;; scala の object import 的なノリ | |
(use 'use-test) | |
(println jojo) | |
;;; 一度読んだライブラリを再読み込みしたい場合は :reload-all フラグを付ける | |
(use :reload-all 'use-test) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; doc を使えば関数のドキュメントが見れる | |
(println (doc str)) | |
;;; 自分で定義した関数にも使える。 | |
;;; 関数にドキュメント(doc-string)を付けるには関数名の直後に文字列を置く | |
(defn hoge | |
"どきゅきゅきゅきゅーん" | |
[a] | |
(println a)) | |
(println (doc hoge)) | |
;; 名前をなんとなくしか覚えていない場合は find-doc を使う | |
;; 関数名だけでなく doc-string にもマッチしているっぽ | |
(println (find-doc "conj")) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; 関数のソースコードを見たい場合 clojure.repl/source を使う | |
(use 'clojure.repl) | |
(println (source str)) | |
;;; Clojure は全て Java オブジェクトなので、 | |
;;; clojure.contrib.repl-utils で裏にある Java API も見ることが出来る | |
;;; 通常の clj では contrib がないっぽいんですが、leiningen にはあるっぽいので、 | |
;;; lein repl 上で load-file して使ってください。 | |
;;; use は何か名前衝突が起きてるっぽいので例外が出ますので、require を使います | |
;;; (use 'clojure.contrib.repl-utils) ; <= java.lang.IllegalStateException: source already refers to: #'clojure.repl/source in namespace: user | |
(require 'clojure.contrib.repl-utils) | |
(println (clojure.contrib.repl-utils/show str)) | |
;;; 自分で定義した関数は source は見れないが、show は見れる | |
(defn mymy [a] | |
(println "maimai")) | |
(println (source mymy)) ; <= Source not found | |
(println (clojure.contrib.repl-utils/show mymy)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; 値が何のクラスかを表示するには class を使う | |
(println (class "")) | |
(println (class 3)) | |
(println (class [])) | |
;;; 値があるクラスのインスタンスかどうかを判定するには instance? を使う | |
(println (instance? String "")) | |
(println (instance? String 3)) | |
;;; 継承されいるクラスやインターフェースの一覧表示をしたい場合は ancestors を使う | |
(def bekuta (ancestors (class []))) | |
;;; どうやら HashSet らしいので順不同っぽい | |
;;; なぜ ruby のような継承ツリー(もどきでいいから)の配列を返さないのら。。。 | |
(println (class bekuta)) | |
(use 'clojure.pprint) | |
(pprint bekuta) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment