SlideShare a Scribd company logo
 Macros in Clojure
      @athos0220
Agenda

• Lispマクロ入門
• Clojureのマクロとその周辺
• Clojureマクロの応用例
 Lispマクロ入門
マクロとは
                when                                       if



      =        print    print          =                   do            nil



mod       0    "Fizz"   "Buzz"   mod         0    print         print



 x        15                      x         15    "Fizz"        "Buzz"


                                           (if (= (mod x 15) 0)
(when (= (mod x 15) 0)                       (do
  (print “Fizz”)                               (print “Fizz”)
  (print “Buzz”))                              (print “Buzz”))
                                             nil)

             構文木を組み替えるための仕組み
           →自由に構文を作ることができる仕組み
マクロの定義
• シンボルやリストで展開形のコードを
 作ってやる
  (when ⃝⃝   (if ⃝⃝
    △△         (do △△
    ✕✕)             ✕✕)
               nil)
マクロの定義
    • シンボルやリストで展開形のコードを
       作ってやる
           (when ⃝⃝            (if ⃝⃝
             △△                  (do △△
             ✕✕)                      ✕✕)
                                 nil)
(defmacro when [test & body]
  (list ’if
        test
        (cons ’do body)
        nil))
マクロの定義
    • シンボルやリストで展開形のコードを
       作ってやる
           (when ⃝⃝              (if ⃝⃝
             △△                    (do △△
             ✕✕)                        ✕✕)
                                   nil)
(defmacro when [test & body]   (defmacro when [test & body]
  (list ’if                      `(if ~test
        test                        (do ~@body)
        (cons ’do body)             nil)
        nil))
名前衝突の問題
名前衝突の問題
束縛変数の衝突   自由変数の衝突
名前衝突の問題
束縛変数の衝突                  自由変数の衝突
     (defmacro or [expr1 expr2]
       `(let [val ~expr1]
          (if val
            val
            ~expr2)))
名前衝突の問題
束縛変数の衝突                           自由変数の衝突
              (defmacro or [expr1 expr2]
                `(let [val ~expr1]
                   (if val
                     val
                     ~expr2)))
(let [val true]
  (or false val))
名前衝突の問題
束縛変数の衝突                           自由変数の衝突
              (defmacro or [expr1 expr2]
                `(let [val ~expr1]
                   (if val
                     val
                     ~expr2)))
(let [val true]
  (or false val))


(let [val true]
  (let [val false]
    (if val
      val
      val))
名前衝突の問題
束縛変数の衝突                           自由変数の衝突
              (defmacro or [expr1 expr2]
                `(let [val ~expr1]
                   (if val
                     val
                     ~expr2)))
(let [val true]
  (or false val))


(let [val true]
  (let [val false]
    (if val
      val
      val))
名前衝突の問題
束縛変数の衝突                           自由変数の衝突
              (defmacro or [expr1 expr2]
                `(let [val ~expr1]
                   (if val
                     val
                     ~expr2)))
(let [val true]
  (or false val))


(let [val true]
  (let [val false]
    (if val
      val
      val))
名前衝突の問題
束縛変数の衝突                           自由変数の衝突
              (defmacro or [expr1 expr2]
                `(let [val ~expr1]
                   (if val
                     val
                     ~expr2)))
(let [val true]                  (let [let nil]
  (or false val))                  (or false true))


(let [val true]
  (let [val false]
    (if val
      val
      val))
名前衝突の問題
束縛変数の衝突                           自由変数の衝突
              (defmacro or [expr1 expr2]
                `(let [val ~expr1]
                   (if val
                     val
                     ~expr2)))
(let [val true]                  (let [let nil]
  (or false val))                  (or false true))


(let [val true]                 (let [let nil]
  (let [val false]                (let [val false]
    (if val                         (if val
      val                             val
      val))                           true))
名前衝突の問題
束縛変数の衝突                           自由変数の衝突
              (defmacro or [expr1 expr2]
                `(let [val ~expr1]
                   (if val
                     val
                     ~expr2)))
(let [val true]                  (let [let nil]
  (or false val))                  (or false true))


(let [val true]                 (let [let nil]
  (let [val false]                (let [val false]
    (if val                         (if val
      val                             val
      val))                           true))
名前衝突の問題
束縛変数の衝突                           自由変数の衝突
              (defmacro or [expr1 expr2]
                `(let [val ~expr1]
                   (if val
                     val
                     ~expr2)))
(let [val true]                  (let [let nil]
  (or false val))                  (or false true))


(let [val true]                 (let [let nil]
  (let [val false]                (let [val false]
    (if val                         (if val
      val                             val
      val))                           true))
健全なマクロ (Hygienic macros)

• 名前の衝突を自動的に回避してくれる
  ハイパーなマクロ
健全なマクロ (Hygienic macros)

   • 名前の衝突を自動的に回避してくれる
     ハイパーなマクロ
(define-syntax or
  (syntax-rules ()
   ((or expr1 expr2)
    (let ([val expr1])
      (if val
        val
        expr2)))))
健全なマクロ (Hygienic macros)

   • 名前の衝突を自動的に回避してくれる
     ハイパーなマクロ
(define-syntax or        (let ([val true])
  (syntax-rules ()         (or false val))
   ((or expr1 expr2)
    (let ([val expr1])
      (if val
        val
        expr2)))))
健全なマクロ (Hygienic macros)

   • 名前の衝突を自動的に回避してくれる
     ハイパーなマクロ
(define-syntax or        (let ([val true])
  (syntax-rules ()         (or false val))
   ((or expr1 expr2)
    (let ([val expr1])
      (if val            (let ([val true])
        val                (let ([val_0 false])
        expr2)))))           (if val_0
                               val_0
                               val)))
マクロの分類
• 高レベル:専用のパターン言語をもつ
• 低レベル:Lispの関数でコードを操作する
          低レベル                 高レベル
不
健 • 伝統的なマクロ
全

健 • syntactic closures
  • explicit renaming    • syntax-rules
全 • syntax-case
マクロの分類
• 高レベル:専用のパターン言語をもつ
• 低レベル:Lispの関数でコードを操作する
          低レベル                 高レベル
不
健 • 伝統的なマクロ
全
                     >
健 • syntactic closures
  • explicit renaming    • syntax-rules
全 • syntax-case
マクロの分類
• 高レベル:専用のパターン言語をもつ
• 低レベル:Lispの関数でコードを操作する
          低レベル                 高レベル
不
健 • 伝統的なマクロ
全
            >
                     >
健 • syntactic closures
  • explicit renaming    • syntax-rules
全 • syntax-case
 Clojureの
マクロシステムとその周辺
Clojureのマクロシステム


• 伝統的なマクロがベース
                              低レベル                   高レベル


                     不
                     健   • 伝統的なマクロ
                     全




                               >
• syntax-quote が特徴


                                          >
                     健   • syntactic closures
                         • explicit renaming    • syntax-rules
                     全   • syntax-case
syntax-quote
syntax-quote
束縛変数の衝突    自由変数の衝突
syntax-quote
束縛変数の衝突                  自由変数の衝突
     (defmacro or [expr1 expr2]
       `(let [val# ~expr1]
          (if val#
            val#
            ~expr2)))
syntax-quote
束縛変数の衝突                         自由変数の衝突
            (defmacro or [expr1 expr2]
              `(let [val# ~expr1]
                 (if val#
 syntax-quote      val#
                   ~expr2)))
syntax-quote
束縛変数の衝突                           自由変数の衝突
              (defmacro or [expr1 expr2]
                `(let [val# ~expr1]
                   (if val#
   syntax-quote      val#
                     ~expr2)))
(let [val true]
  (or false val))
syntax-quote
        束縛変数の衝突                                自由変数の衝突
                        (defmacro or [expr1 expr2]
                          `(let [val# ~expr1]
                             (if val#
             syntax-quote      val#
                               ~expr2)))
          (let [val true]
            (or false val))



(let [val true]
  (clojure.core/let [val__419__auto__ false]
    (if val__419__auto__
      val__419__auto__
      val))

#をつけた名前を自動でリネーム (auto-gensym)
syntax-quote
        束縛変数の衝突                                自由変数の衝突
                        (defmacro or [expr1 expr2]
                          `(let [val# ~expr1]
                             (if val#
             syntax-quote      val#
                               ~expr2)))
          (let [val true]                     (let [let nil]
            (or false val))                     (or false true))



(let [val true]
  (clojure.core/let [val__419__auto__ false]
    (if val__419__auto__
      val__419__auto__
      val))

#をつけた名前を自動でリネーム (auto-gensym)
syntax-quote
        束縛変数の衝突                                         自由変数の衝突
                        (defmacro or [expr1 expr2]
                          `(let [val# ~expr1]
                             (if val#
             syntax-quote      val#
                               ~expr2)))
          (let [val true]                     (let [let nil]
            (or false val))                     (or false true))



(let [val true]                                (let [let nil]
  (clojure.core/let [val__419__auto__ false]     (clojure.core/let [val__419__auto__ false]
    (if val__419__auto__                           (if val__419__auto__
      val__419__auto__                               val__419__auto__
      val))                                          true))

#をつけた名前を自動でリネーム (auto-gensym) その他の名前にはnamespace名をqualifyする
メタデータ
    •   ほとんどすべてのオブジェクトにメタデータを付加できる

    •   Clojureではコードもデータ

        →コードのほとんどあらゆる部分にメタデータをアノテー
         ションとして付加できる
                                 名前をnamespaceにプライベートにする
               (defn ^:private f [x] x)

               (def ^:dynamic x nil)
動的スコープの変数にする                            戻り値と引数の型ヒント
               (defn fact ^long [^long x]
                 (if (= x 0)
                   1
                   (* x (fact (- x 1)))))
Java Interop

• ClojureからJavaのクラスにアクセスできる
• Clojureは大部分がJavaで書かれている
• Javaで書かれているClojureのコンパイラ自
 体や内部で使われる構文木にも触れる
暗黙の引数 &formと&env

• マクロ呼出しのフォームを囲むコンテ
 キストに関する情報が渡ってくる

 -   &form:マクロ呼出しのフォーム全体

 -   &env:マクロ呼出しの時点で見えて
     いるローカル環境
 Clojure
マクロの応用例
the オペレータ   http://d.hatena.ne.jp/athos/20120129/THE_operator_in_clojure




   •   「型を1つ引数にとり現在のスコープに唯一存
       在するその型のオブジェクトを返す演算子」
       by @kinaba
   •   &envを使って、そのスコープで見えている変
       数のうち、指定した型がメタデータに付いて
       いるものを拾ってくる
(let [^File _ (File. "foo.txt")
      ^FileReader __ (FileReader. (the File))
      ^BufferedReader ___ (BufferedReader (the FileReader))]
  (.readLine (the BufferedReader)))
inline assembler マクロ                         http://www.slideshare.net/sohta/shibuyalisp-tt7




         • Clojureコンパイラが使うバイトコード
              生成ライブラリをマクロ展開時に使う
(def fact                                            public final java.lang.Object invoke(java.lang.
  (fn-iasm [n]                                         Code:
    (aload_1)                                           Stack=2, Locals=6, Args_size=2
    (checkcast Integer)                                 0:   aload_1
    (invokevirtual ^int Integer/intValue [])            1:   checkcast      #25; //class java/lang/I
    (istore_2)                                          4:   invokevirtual #29; //Method java/lang/
    (iconst_1)                                          7:   istore_2
    (istore_3)                                          8:   iconst_1
    :loop                                               9:   istore_3
    (iload_2)                                           10: iload_2
    (ifeq :end)                                         11: ifeq      24
    (ilaod_2)                                           14: iload_2
    (iload_3)                                           15: iload_3
    (imul)                                              16: imul
    (istore_3)                                          17: istore_3
    (iinc 2 -1)                                         18: iinc      2, -1
    (goto :loop)                                        21: goto      10
    :end                                                24: iload_3
    (iload_3)                                           25: invokestatic    #33; //Method java/lang/
    (invokestatic ^Integer Integer/valueOf [int])       28: areturn
    (areturn)))
syntactic-closure
                        http://d.hatena.ne.jp/athos/20120506/syntactic_closure_in_clojure



•   syntactic closuresによる健全なマクロを定義で
    きるようにするライブラリ
                                                                  低レベル              高レベル


•   syntax-quoteで定義できない                                  不
                                                         健
                                                         全
                                                             • 伝統的なマクロ


    ある種のマクロが定義可能に
                                                             • syntactic closures
(define-syntax or [expr1 expr2]           健
                                             • explicit renaming • syntax-rules
                                          全  • syntax-case
  (sc-macro-transformer
    (fn [env]
      (quasiquote
        (let [val ~(make-syntactic-closure env nil expr1)]
          (if val
            val
            ~(make-syntactic-closure env nil expr2)))))))

(let [val true]                       (let [val true]
  (or false val))                       (let [val396 false]
                                          (if val396 val396 val))
 まとめ

• Clojureのマクロ周りには遊べるおも
 ちゃがたくさん

• アイデア次第で貢献できる可能性?
• nagoya-lispに参加しましょう
おわり

More Related Content

Viewers also liked

A little exercise with clojure macro
A little exercise with clojure macroA little exercise with clojure macro
A little exercise with clojure macro
Zehua Liu
 
不自然なcar/ナチュラルにconsして
不自然なcar/ナチュラルにconsして不自然なcar/ナチュラルにconsして
不自然なcar/ナチュラルにconsして
mitsutaka mimura
 
A Dive Into Clojure
A Dive Into ClojureA Dive Into Clojure
A Dive Into Clojure
Carlo Sciolla
 
Clojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVMClojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVM
sunng87
 
Writing Macros
Writing MacrosWriting Macros
Writing Macros
RueiCi Wang
 
入門ClojureScript
入門ClojureScript入門ClojureScript
入門ClojureScript
sohta
 
Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012
Leonardo Borges
 
Clojure的魅力
Clojure的魅力Clojure的魅力
Clojure的魅力
dennis zhuang
 
Clojure概览
Clojure概览Clojure概览
Clojure概览
dennis zhuang
 
Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...
Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...
Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...
AboutYouGmbH
 
Clojureシンタックスハイライター開発から考えるこれからのlispに必要なもの
Clojureシンタックスハイライター開発から考えるこれからのlispに必要なものClojureシンタックスハイライター開発から考えるこれからのlispに必要なもの
Clojureシンタックスハイライター開発から考えるこれからのlispに必要なもの
sohta
 
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
Jacek Laskowski
 
Introduction to clojure
Introduction to clojureIntroduction to clojure
Introduction to clojure
Abbas Raza
 
DSL in Clojure
DSL in ClojureDSL in Clojure
DSL in Clojure
Misha Kozik
 
プログラミング言語Clojureのニャンパスでの活用事例
プログラミング言語Clojureのニャンパスでの活用事例プログラミング言語Clojureのニャンパスでの活用事例
プログラミング言語Clojureのニャンパスでの活用事例
sohta
 
Clojure from ground up
Clojure from ground upClojure from ground up
Clojure from ground up
Di Xu
 
アルゴリズムのイメージを擬人化する
アルゴリズムのイメージを擬人化するアルゴリズムのイメージを擬人化する
アルゴリズムのイメージを擬人化する
AtCoder Inc.
 

Viewers also liked (19)

A little exercise with clojure macro
A little exercise with clojure macroA little exercise with clojure macro
A little exercise with clojure macro
 
不自然なcar/ナチュラルにconsして
不自然なcar/ナチュラルにconsして不自然なcar/ナチュラルにconsして
不自然なcar/ナチュラルにconsして
 
Patterns
PatternsPatterns
Patterns
 
A Dive Into Clojure
A Dive Into ClojureA Dive Into Clojure
A Dive Into Clojure
 
Clojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVMClojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVM
 
Writing Macros
Writing MacrosWriting Macros
Writing Macros
 
入門ClojureScript
入門ClojureScript入門ClojureScript
入門ClojureScript
 
Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012
 
Clojure的魅力
Clojure的魅力Clojure的魅力
Clojure的魅力
 
Clojure概览
Clojure概览Clojure概览
Clojure概览
 
Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...
Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...
Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...
 
Clojureシンタックスハイライター開発から考えるこれからのlispに必要なもの
Clojureシンタックスハイライター開発から考えるこれからのlispに必要なものClojureシンタックスハイライター開発から考えるこれからのlispに必要なもの
Clojureシンタックスハイライター開発から考えるこれからのlispに必要なもの
 
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
 
Clojure: a LISP for the JVM
Clojure: a LISP for the JVMClojure: a LISP for the JVM
Clojure: a LISP for the JVM
 
Introduction to clojure
Introduction to clojureIntroduction to clojure
Introduction to clojure
 
DSL in Clojure
DSL in ClojureDSL in Clojure
DSL in Clojure
 
プログラミング言語Clojureのニャンパスでの活用事例
プログラミング言語Clojureのニャンパスでの活用事例プログラミング言語Clojureのニャンパスでの活用事例
プログラミング言語Clojureのニャンパスでの活用事例
 
Clojure from ground up
Clojure from ground upClojure from ground up
Clojure from ground up
 
アルゴリズムのイメージを擬人化する
アルゴリズムのイメージを擬人化するアルゴリズムのイメージを擬人化する
アルゴリズムのイメージを擬人化する
 

More from sohta

入門Transducers
入門Transducers入門Transducers
入門Transducers
sohta
 
Clojure Language Update (2015)
Clojure Language Update (2015)Clojure Language Update (2015)
Clojure Language Update (2015)
sohta
 
入門core.async
入門core.async入門core.async
入門core.async
sohta
 
REPLライフをもっと快適に
REPLライフをもっと快適にREPLライフをもっと快適に
REPLライフをもっと快適に
sohta
 
genuine-highlighter: マクロを認識するClojure向けのシンタックスハイライター
genuine-highlighter: マクロを認識するClojure向けのシンタックスハイライターgenuine-highlighter: マクロを認識するClojure向けのシンタックスハイライター
genuine-highlighter: マクロを認識するClojure向けのシンタックスハイライター
sohta
 
ClojureではじめるSTM入門
ClojureではじめるSTM入門ClojureではじめるSTM入門
ClojureではじめるSTM入門sohta
 
Clojureによるバイトコードプログラミング
ClojureによるバイトコードプログラミングClojureによるバイトコードプログラミング
Clojureによるバイトコードプログラミングsohta
 

More from sohta (7)

入門Transducers
入門Transducers入門Transducers
入門Transducers
 
Clojure Language Update (2015)
Clojure Language Update (2015)Clojure Language Update (2015)
Clojure Language Update (2015)
 
入門core.async
入門core.async入門core.async
入門core.async
 
REPLライフをもっと快適に
REPLライフをもっと快適にREPLライフをもっと快適に
REPLライフをもっと快適に
 
genuine-highlighter: マクロを認識するClojure向けのシンタックスハイライター
genuine-highlighter: マクロを認識するClojure向けのシンタックスハイライターgenuine-highlighter: マクロを認識するClojure向けのシンタックスハイライター
genuine-highlighter: マクロを認識するClojure向けのシンタックスハイライター
 
ClojureではじめるSTM入門
ClojureではじめるSTM入門ClojureではじめるSTM入門
ClojureではじめるSTM入門
 
Clojureによるバイトコードプログラミング
ClojureによるバイトコードプログラミングClojureによるバイトコードプログラミング
Clojureによるバイトコードプログラミング
 

Recently uploaded

FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdfFIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance
 
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdfFIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance
 
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
Matsushita Laboratory
 
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさJSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
0207sukipio
 
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
Matsushita Laboratory
 
FIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdfFIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance
 
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアルLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
CRI Japan, Inc.
 
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
Toru Tamaki
 
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdfFIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance
 
CS集会#13_なるほどわからん通信技術 発表資料
CS集会#13_なるほどわからん通信技術 発表資料CS集会#13_なるほどわからん通信技術 発表資料
CS集会#13_なるほどわからん通信技術 発表資料
Yuuitirou528 default
 
This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.
chiefujita1
 
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
Fukuoka Institute of Technology
 
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
harmonylab
 
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdfFIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance
 

Recently uploaded (14)

FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdfFIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
 
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdfFIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
 
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
 
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさJSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
 
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
 
FIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdfFIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdf
 
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアルLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
 
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
 
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdfFIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
 
CS集会#13_なるほどわからん通信技術 発表資料
CS集会#13_なるほどわからん通信技術 発表資料CS集会#13_なるほどわからん通信技術 発表資料
CS集会#13_なるほどわからん通信技術 発表資料
 
This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.
 
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
 
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
 
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdfFIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
 

Macros in Clojure

  • 1.  Macros in Clojure @athos0220
  • 4. マクロとは when if = print print = do nil mod 0 "Fizz" "Buzz" mod 0 print print x 15 x 15 "Fizz" "Buzz" (if (= (mod x 15) 0) (when (= (mod x 15) 0) (do (print “Fizz”) (print “Fizz”) (print “Buzz”)) (print “Buzz”)) nil) 構文木を組み替えるための仕組み →自由に構文を作ることができる仕組み
  • 5. マクロの定義 • シンボルやリストで展開形のコードを 作ってやる (when ⃝⃝ (if ⃝⃝ △△ (do △△ ✕✕) ✕✕) nil)
  • 6. マクロの定義 • シンボルやリストで展開形のコードを 作ってやる (when ⃝⃝ (if ⃝⃝ △△ (do △△ ✕✕) ✕✕) nil) (defmacro when [test & body] (list ’if test (cons ’do body) nil))
  • 7. マクロの定義 • シンボルやリストで展開形のコードを 作ってやる (when ⃝⃝ (if ⃝⃝ △△ (do △△ ✕✕) ✕✕) nil) (defmacro when [test & body] (defmacro when [test & body] (list ’if `(if ~test test (do ~@body) (cons ’do body) nil) nil))
  • 10. 名前衝突の問題 束縛変数の衝突 自由変数の衝突 (defmacro or [expr1 expr2] `(let [val ~expr1] (if val val ~expr2)))
  • 11. 名前衝突の問題 束縛変数の衝突 自由変数の衝突 (defmacro or [expr1 expr2] `(let [val ~expr1] (if val val ~expr2))) (let [val true] (or false val))
  • 12. 名前衝突の問題 束縛変数の衝突 自由変数の衝突 (defmacro or [expr1 expr2] `(let [val ~expr1] (if val val ~expr2))) (let [val true] (or false val)) (let [val true] (let [val false] (if val val val))
  • 13. 名前衝突の問題 束縛変数の衝突 自由変数の衝突 (defmacro or [expr1 expr2] `(let [val ~expr1] (if val val ~expr2))) (let [val true] (or false val)) (let [val true] (let [val false] (if val val val))
  • 14. 名前衝突の問題 束縛変数の衝突 自由変数の衝突 (defmacro or [expr1 expr2] `(let [val ~expr1] (if val val ~expr2))) (let [val true] (or false val)) (let [val true] (let [val false] (if val val val))
  • 15. 名前衝突の問題 束縛変数の衝突 自由変数の衝突 (defmacro or [expr1 expr2] `(let [val ~expr1] (if val val ~expr2))) (let [val true] (let [let nil] (or false val)) (or false true)) (let [val true] (let [val false] (if val val val))
  • 16. 名前衝突の問題 束縛変数の衝突 自由変数の衝突 (defmacro or [expr1 expr2] `(let [val ~expr1] (if val val ~expr2))) (let [val true] (let [let nil] (or false val)) (or false true)) (let [val true] (let [let nil] (let [val false] (let [val false] (if val (if val val val val)) true))
  • 17. 名前衝突の問題 束縛変数の衝突 自由変数の衝突 (defmacro or [expr1 expr2] `(let [val ~expr1] (if val val ~expr2))) (let [val true] (let [let nil] (or false val)) (or false true)) (let [val true] (let [let nil] (let [val false] (let [val false] (if val (if val val val val)) true))
  • 18. 名前衝突の問題 束縛変数の衝突 自由変数の衝突 (defmacro or [expr1 expr2] `(let [val ~expr1] (if val val ~expr2))) (let [val true] (let [let nil] (or false val)) (or false true)) (let [val true] (let [let nil] (let [val false] (let [val false] (if val (if val val val val)) true))
  • 19. 健全なマクロ (Hygienic macros) • 名前の衝突を自動的に回避してくれる ハイパーなマクロ
  • 20. 健全なマクロ (Hygienic macros) • 名前の衝突を自動的に回避してくれる ハイパーなマクロ (define-syntax or (syntax-rules () ((or expr1 expr2) (let ([val expr1]) (if val val expr2)))))
  • 21. 健全なマクロ (Hygienic macros) • 名前の衝突を自動的に回避してくれる ハイパーなマクロ (define-syntax or (let ([val true]) (syntax-rules () (or false val)) ((or expr1 expr2) (let ([val expr1]) (if val val expr2)))))
  • 22. 健全なマクロ (Hygienic macros) • 名前の衝突を自動的に回避してくれる ハイパーなマクロ (define-syntax or (let ([val true]) (syntax-rules () (or false val)) ((or expr1 expr2) (let ([val expr1]) (if val (let ([val true]) val (let ([val_0 false]) expr2))))) (if val_0 val_0 val)))
  • 23. マクロの分類 • 高レベル:専用のパターン言語をもつ • 低レベル:Lispの関数でコードを操作する 低レベル 高レベル 不 健 • 伝統的なマクロ 全 健 • syntactic closures • explicit renaming • syntax-rules 全 • syntax-case
  • 24. マクロの分類 • 高レベル:専用のパターン言語をもつ • 低レベル:Lispの関数でコードを操作する 低レベル 高レベル 不 健 • 伝統的なマクロ 全 > 健 • syntactic closures • explicit renaming • syntax-rules 全 • syntax-case
  • 25. マクロの分類 • 高レベル:専用のパターン言語をもつ • 低レベル:Lispの関数でコードを操作する 低レベル 高レベル 不 健 • 伝統的なマクロ 全 > > 健 • syntactic closures • explicit renaming • syntax-rules 全 • syntax-case
  • 27. Clojureのマクロシステム • 伝統的なマクロがベース 低レベル 高レベル 不 健 • 伝統的なマクロ 全 > • syntax-quote が特徴 > 健 • syntactic closures • explicit renaming • syntax-rules 全 • syntax-case
  • 29. syntax-quote 束縛変数の衝突 自由変数の衝突
  • 30. syntax-quote 束縛変数の衝突 自由変数の衝突 (defmacro or [expr1 expr2] `(let [val# ~expr1] (if val# val# ~expr2)))
  • 31. syntax-quote 束縛変数の衝突 自由変数の衝突 (defmacro or [expr1 expr2] `(let [val# ~expr1] (if val# syntax-quote val# ~expr2)))
  • 32. syntax-quote 束縛変数の衝突 自由変数の衝突 (defmacro or [expr1 expr2] `(let [val# ~expr1] (if val# syntax-quote val# ~expr2))) (let [val true] (or false val))
  • 33. syntax-quote 束縛変数の衝突 自由変数の衝突 (defmacro or [expr1 expr2] `(let [val# ~expr1] (if val# syntax-quote val# ~expr2))) (let [val true] (or false val)) (let [val true] (clojure.core/let [val__419__auto__ false] (if val__419__auto__ val__419__auto__ val)) #をつけた名前を自動でリネーム (auto-gensym)
  • 34. syntax-quote 束縛変数の衝突 自由変数の衝突 (defmacro or [expr1 expr2] `(let [val# ~expr1] (if val# syntax-quote val# ~expr2))) (let [val true] (let [let nil] (or false val)) (or false true)) (let [val true] (clojure.core/let [val__419__auto__ false] (if val__419__auto__ val__419__auto__ val)) #をつけた名前を自動でリネーム (auto-gensym)
  • 35. syntax-quote 束縛変数の衝突 自由変数の衝突 (defmacro or [expr1 expr2] `(let [val# ~expr1] (if val# syntax-quote val# ~expr2))) (let [val true] (let [let nil] (or false val)) (or false true)) (let [val true] (let [let nil] (clojure.core/let [val__419__auto__ false] (clojure.core/let [val__419__auto__ false] (if val__419__auto__ (if val__419__auto__ val__419__auto__ val__419__auto__ val)) true)) #をつけた名前を自動でリネーム (auto-gensym) その他の名前にはnamespace名をqualifyする
  • 36. メタデータ • ほとんどすべてのオブジェクトにメタデータを付加できる • Clojureではコードもデータ →コードのほとんどあらゆる部分にメタデータをアノテー ションとして付加できる 名前をnamespaceにプライベートにする (defn ^:private f [x] x) (def ^:dynamic x nil) 動的スコープの変数にする 戻り値と引数の型ヒント (defn fact ^long [^long x] (if (= x 0) 1 (* x (fact (- x 1)))))
  • 37. Java Interop • ClojureからJavaのクラスにアクセスできる • Clojureは大部分がJavaで書かれている • Javaで書かれているClojureのコンパイラ自 体や内部で使われる構文木にも触れる
  • 38. 暗黙の引数 &formと&env • マクロ呼出しのフォームを囲むコンテ キストに関する情報が渡ってくる - &form:マクロ呼出しのフォーム全体 - &env:マクロ呼出しの時点で見えて いるローカル環境
  • 40. the オペレータ http://d.hatena.ne.jp/athos/20120129/THE_operator_in_clojure • 「型を1つ引数にとり現在のスコープに唯一存 在するその型のオブジェクトを返す演算子」 by @kinaba • &envを使って、そのスコープで見えている変 数のうち、指定した型がメタデータに付いて いるものを拾ってくる (let [^File _ (File. "foo.txt") ^FileReader __ (FileReader. (the File)) ^BufferedReader ___ (BufferedReader (the FileReader))] (.readLine (the BufferedReader)))
  • 41. inline assembler マクロ http://www.slideshare.net/sohta/shibuyalisp-tt7 • Clojureコンパイラが使うバイトコード 生成ライブラリをマクロ展開時に使う (def fact public final java.lang.Object invoke(java.lang. (fn-iasm [n] Code: (aload_1) Stack=2, Locals=6, Args_size=2 (checkcast Integer) 0: aload_1 (invokevirtual ^int Integer/intValue []) 1: checkcast #25; //class java/lang/I (istore_2) 4: invokevirtual #29; //Method java/lang/ (iconst_1) 7: istore_2 (istore_3) 8: iconst_1 :loop 9: istore_3 (iload_2) 10: iload_2 (ifeq :end) 11: ifeq 24 (ilaod_2) 14: iload_2 (iload_3) 15: iload_3 (imul) 16: imul (istore_3) 17: istore_3 (iinc 2 -1) 18: iinc 2, -1 (goto :loop) 21: goto 10 :end 24: iload_3 (iload_3) 25: invokestatic #33; //Method java/lang/ (invokestatic ^Integer Integer/valueOf [int]) 28: areturn (areturn)))
  • 42. syntactic-closure http://d.hatena.ne.jp/athos/20120506/syntactic_closure_in_clojure • syntactic closuresによる健全なマクロを定義で きるようにするライブラリ 低レベル 高レベル • syntax-quoteで定義できない 不 健 全 • 伝統的なマクロ ある種のマクロが定義可能に • syntactic closures (define-syntax or [expr1 expr2] 健 • explicit renaming • syntax-rules 全 • syntax-case (sc-macro-transformer (fn [env] (quasiquote (let [val ~(make-syntactic-closure env nil expr1)] (if val val ~(make-syntactic-closure env nil expr2))))))) (let [val true] (let [val true] (or false val)) (let [val396 false] (if val396 val396 val))
  • 43.  まとめ • Clojureのマクロ周りには遊べるおも ちゃがたくさん • アイデア次第で貢献できる可能性? • nagoya-lispに参加しましょう