目次

関数はfirst-class object

"fn", "#"を用いて作成する

(#はfnのshort-hand)

(#はfnのshort-hand) clojureに於いては、fn, #を用いてラムダ式を表す

( println ((fn [ x y ] ( * x y )) 1 2 )) ( println (#( * %1 %2) 1 2 ))

%1, %2について short-handで定義した場合の引数は%と番号で表す。

なお1つ目の引数は%のみでも表せる。

( println (# ( * % %) 2 ))

デフォルト値は多重定義かオプショナル引数で行う

( defn add ([ x ] ( add x 1 )) ([ x y ] ( + x y ))) ( defn add [ x & { : keys [ y ] : or { y 1 }}] ( + x y ))

def関数を利用して命名する

(def x 100 ) (def mul (fn [ x y ] ( * x y )))

関数はdefnマクロを使うと楽

( defn mul [ x y ] ( * x y ))

(let [ x 1 , y 1 ] ( println ( + x y )) (let [ x 1 y 1 ] ( println ( + x y )))

NOTE

変数の定義時に、横に並べる場合、カンマを入れると見やすくなる。

カンマを入れない場合、自由変数に束縛変数を入れると、[x a y b]のようになったりする。

'( 1 2 3 ) { :x 100 :y 200 } #{ 10 20 } ( set '( 10 20 10 )) [ 1 2 3 ]

すべてのデータは、メタデータを持てる

(def vect [ 1 2 3 4 ]) (def vect-with-meta ( with-meta vect { :music :be-ok })) ( :music ( meta vect-with-meta ))

ここが参考になると思う(yuwki0131-blog: Clojure(1.3-1.4)のリスト/ベクタ(シーケンス)操作関数一覧)

条件文はif,when,if-let,when-letなどを使う

(if condition then-expr else-expr ) ( defn even-printer [ n ] (if ( = ( mod n 2 ) 0 ) ( println "Even!" ) ( println "Odd!" ))) ( defn even-printer2 [ n ] (if ( = ( mod n 2 ) 0 ) ( println "Even!" ) (do ( println "Odd!" ) ( println "Odd2!" )))) ( when condition expr1 expr2 ... ) ( defn even-printer [ n ] ( when ( even? n ) ( println "Even1" ) ( println "Even2" ) ( println "Even3" ))) ( defn p-next [ lst ] (if -let [ element ( first lst )] ( println "Exist Element : " element ) ( println "No Elements" ))) ( defn p-next [ lst ] ( when -let [ element ( first lst )] ( println "First : " element ) ( println "First : " element )))

値が必要になるまで、実際の計算を行わないこと

用語 promise : 実際に計算を行われていない中間状態 thunk : 計算の実体 force : 値の計算(promiseをforceする)



( defn inf-list ([] inf-list 0 ) ([ n ] ( cons n ( lazy-seq ( inf-list ( inc n )))))) ( println ( inf-list )) ( println ( take 3 ( inf-list ))) ( println ( take 3 ( inf-list 100 )))

ClojureはJVMを使う為、末尾再帰の最適化を行えないらしい

(通常の再帰呼び出しよりloopマクロを利用する方が、スタックを無駄にしないということか？)

( defn fact [ n ] (loop [ i n result 1 ] (if ( zero? i ) result (recur ( dec i ) ( * result i ))))) ( defn fact [ n ] (if ( zero? n ) 1 ( * n ( fact ( dec n )))))

( defmulti class -checker class ) ( defmethod class -checker Integer [ arg ] ( println "Integer!" )) ( defmethod class -checker Double [ arg ] ( println "Double!" )) ( defmethod class -checker String [ arg ] ( println "String!" )) ( defmethod class -checker :default [ arg ] ( println "Other!" )) ( defmulti func (fn [ x y ] [( class x ) ( class y )])) ( defmethod func [ Integer Integer ] [ x y ] ( Math/pow x y )) ( defmethod func [ Double Integer ] [ x y ] ( Math/pow x y )) ( defmethod func :default [ _ _ ] ' other )

(new java.lang.Double "100" ) ( java.lang.Double. "100" ) (new Double "100" ) ( Double. "100" )

(def value1 ( Double. 10 .0 )) (def value2 ( Double. 20 .0 )) (def value3 ( Double. 10 .0 )) ( .compareTo value1 value2 ) ( . value1 compareTo value3 )

( println ( . Math PI )) ( println Math/PI ) ( println ( Double/parseDouble )) ( println ( . Double parseDouble ))

( map ( memfn toUpperCase ) [ "do it" "do it" ]) ( map #( .toUpperCase %1) [ "do it" "do it" ])

( .. ( Double/valueOf 10 .0 ) toString length ) ( -> ( Double/valueOf 10 .0 ) .toString .length )

糖衣構文 __可能な限りclojureの糖衣構文を利用した方がよいらしい



( String. "doit doit" ) Math/PI ( Math/abs -10 ) ( .length "DOIT" ) ( .. ( Double/valueOf 10 .0 ) toString length ) ( -> ( Double/valueOf 10 .0 ) .toString .length )

( defn delayed-print [ ms text ] ( Thread/sleep ms ) ( println text )) ( .start ( Thread. #( delayed-print 100 "wwwwwww" ))) ( print "grass" )

( binding [ *out* ( java.io.FileWriter. "__my.log" )] ( println "YHVH1" ) ( println "YHVH2" ) ( println "YHVH3" ) ( println "YHVH4" ) ( println "Lucifer" ) ( flush )) ( with-open [ fr ( java.io.FileReader. "__my.log" ) br ( java.io.BufferedReader. fr )] ( doseq [ line ( line-seq br )] ( print line )))

( require ' clojure.string ) ( require '[ clojure.string :as str ]) ( require '[ clojure.string : refer [ join ]]) ( require '[ clojure.string : refer :all ])

( import '( java.math BigDecimal BigInteger )) ( import java.io.InputStream ) ( import '( java.util List Set ) '( java.net URL )) ( println ( BigDecimal. 100 .0 )) ( println ( BigInteger. "10000" ))

basedir ├── lib │ ├── another.clj │ ├── another_math.clj │ └── calc │ ├── core.clj │ └── core_math.clj ├── main.clj └── utils.clj #^ :shebang '[ java -cp "$CLOJUREPATH/clojure-1.6.0.jar:./" clojure.main "$0" "$@" ] ( require ' utils ) ( require ' lib.another ) ( require ' lib.calc.core ) ( utils/hello ) ( println ( lib.calc.core/myadd 1 2 )) ( println ( lib.another/mymul 2 4 )) ( ns utils ) ( defn hello [] ( println "HELLO" )) ( ns lib.another ( load "another_math" )) ( in-ns ' lib.another ) ( defn mymul [ x y ] ( * x y )) ( ns lib.calc.core ( load "core_math" )) ( in-ns ' lib.calc.core ) ( defn myadd [ x y ] ( + x y ))

first-class object

生成、代入、演算、受け渡しなどが無制限に使用できる対象の事。 定義としては、以下の能力を持つプログラムの事を言う。

DEF

オブジェクトに名前が付けられる

(defを使った命名とかかな？) 引数として関数・手続きに渡す事ができる

(手続き？) 結果値として関数から帰ってくる事ができる

(戻り値を"関数"としてもよいという事) データ構造に組み込む事ができる

(データ構造 : class, struct, dict, listなど

組み込む？)

version date memo 0.1 2015/03/21 first create 0.2 2015/03/22 JavaAPI関連追加 0.3 2015/03/25 名前空間,ファイル分割追加 0.4 2016/12/17 文字化け修正

Information

Using(SW etc) version Ubuntu 12.04 Clojure 1.6.0

MEMO

macro調査

namespace調査