Education‎ > ‎Closer to Clojure‎ > ‎

Closer to Clojure 01: Function

Functions are the first class objects. You can make one by fn instead of lambda. Let's try (def name expr) syntax.

user=> (def hello (fn [] (println "Hello world")))
#'user/hello
user=> (hello)
"Hello world"

You can also use macro defn for more simplicity. Functions can be overloaded.

user=> (defn argcount
  ([] 0)
  ([x] 1)
  ([x y] 2)
  ([x y & more] (+ (argcount x y) (count more))))
#'user/argcount
user=> (argcount)
0
user=> (argcount 1)
1
user=> (argcount 1 2)
2
user=> (argcount 1 2 3 4 5)
5

You can define local variables by let syntax. The let syntax creates lexical closure.

user=> (defn make-adder [x]
  (let [y x]
    (fn [z] (+ y z))))
user=> (def add2 (make-adder 2))
user=> (add2 4)
6

Clojure simplified conventional let of Common LISP and Scheme by omitting pair of parenthesis.

Here is another syntax sugar for making anonymous function.

user=> (#(+ %1 %2) 10 20)
30

You can use just % if you only have a single argument.

References:
http://clojure.org/functional_programming
http://java.ociweb.com/mark/clojure/article.html
関数はファーストクラスオブジェクトです.lambdaの代わりにfnで作ります.(def name expr) 構文で関数に名前をつけてみましょう.

user=> (def hello (fn [] (println "Hello world")))
#'user/hello
user=> (hello)
"Hello world"

マクロdefnを使うとよりシンプルになります.関数オーバーロードができます.

user=> (defn argcount
  ([] 0)
  ([x] 1)
  ([x y] 2)
  ([x y & more] (+ (argcount x y) (count more))))
#'user/argcount
user=> (argcount)
0
user=> (argcount 1)
1
user=> (argcount 1 2)
2
user=> (argcount 1 2 3 4 5)
5

一時変数はletを使って導入します.レキシカルクロージャが作られます.

user=> (defn make-adder [x]
  (let [y x]
    (fn [z] (+ y z))))
user=> (def add2 (make-adder 2))
user=> (add2 4)
6

letは Common Lisp/Scheme と比べると括弧がひとつ少ないですね.

無名関数を作るためのシンタックスシュガーがあります.

user=> (#(+ %1 %2) 10 20)
30

引数が1個だけのときは%だけでいいです.

参考
http://clojure.org/functional_programming
http://java.ociweb.com/mark/clojure/article.html
Comments