Skip to content

Instantly share code, notes, and snippets.

@jkugiya
Created October 3, 2014 07:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jkugiya/42dbde6c35cf7fd4c533 to your computer and use it in GitHub Desktop.
Save jkugiya/42dbde6c35cf7fd4c533 to your computer and use it in GitHub Desktop.
はじめてのClojure勉強会#5 スレッドマクロの実装を調べてみた
; (sourcec ->)
(defmacro ->
"Threads the expr through the forms. Inserts x as the
second item in the first form, making a list of it if it is not a
list already. If there are more forms, inserts the first form as the
second item in second form, etc."
{:added "1.0"}
([x] x)
([x form] (if (seq? form)
(with-meta `(~(first form) ~x ~@(next form)) (meta form))
(list form x)))
([x form & more] `(-> (-> ~x ~form) ~@more)))
; with-metaとmeta
; Clojureのmetadata
; http://clojure.org/metadata
; シンボルとコレクションはメタデータをサポートしており、メタデータはシンボル・コレクションに関するデータのマップです。
; メタデータの仕組みによってデータへ任意の付加情報を与えることができます。この機能はClojureのコンパイラに
; 型情報を与えるところで使われていたりしますが、アプリケーションの開発者もデータソースの情報やポリシーに関する事柄など様々な場面で
; この機能を使うことができます。
; メタデータについて理解するために重要なことは、メタデータ自身は値の一部とみなされないことです。
; メタデータは等価性やオブジェクトのハッシュコードには影響しません。メタデータのみが異なる2つのオブジェクトは等価とみなされます。
; しかし、メタデータとオブジェクトの関係は不変です。異なるメタデータを持つオブジェクトは別のオブジェクトです。
(meta {:a 1})
(def a (with-meta 'aaa {:hoge "aaaa"}))
(def b (with-meta a {:hoge "bbbb"}))
(meta a)
(meta b )
(= a b)
(identical? a b)
; リーダマクロのおさらい
; ` シンタックスクォート
(list `(str "hoge"))
; ~ アンクォート
(list `(~str "hoge"))
(list str)
; ~@アンクォートすプライシング
(list `(~(first '(+ 1 2 3 4 5 6 7 8)) ~10 ~@(next '(+ 1 2 3 4 5 6 7 8))))
; => マクロの中でリストを複数の引数を持つ関数の各引数として与えてあげる時に使う。
; nextとrest
; 動作の確認
(-> "hoge")
(-> "hoge"
(.toUpperCase)); (.toUpperCase "hoge")
(-> "hoge"
.toUpperCase)
(-> "fuga"
(.toUpperCase)
(.split "U")
(vec));(vec (.split (.toUpperCase "fuga") "U"))
(rest '(1 2 3 4))
; このマクロはどう組まれているか?
; => formとして与えられた処理の引数を変更している。
; (.toUpperCase) => (.toUpperCase "hoge")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment