SlideShare une entreprise Scribd logo
1  sur  104
Télécharger pour lire hors ligne
Pattern Matching &
                          Predicate Dispatch



Thursday, August 18, 11                        1
Thursday, August 18, 11   2
๏    Dynamic programming languages are
                          powerful, productive




Thursday, August 18, 11                                       2
๏    Dynamic programming languages are
                          powerful, productive

                     ๏    Errors from dynamic typing are not fun




Thursday, August 18, 11                                            2
๏    Dynamic programming languages are
                          powerful, productive

                     ๏    Errors from dynamic typing are not fun

                     ๏    Too much type information is “trapped
                          inside”




Thursday, August 18, 11                                            2
๏    Dynamic programming languages are
                          powerful, productive

                     ๏    Errors from dynamic typing are not fun

                     ๏    Too much type information is “trapped
                          inside”

                     ๏    We can do better without resorting to
                          static types


Thursday, August 18, 11                                            2
closed versus open




                               (cond
                                 (map? x) ...
                                 (vector? x) ...
                                 (list? x) ...
                                 :else ...)




Thursday, August 18, 11                            3
better but...




                          (extend-type IPersistentMap
                            ...)

                          (extend-type IPersistentVector
                            ...)

                          (extend-type IPersistentList
                            ...)




Thursday, August 18, 11                                    4
we want to enumerate what is
      allowed

      duck-typing doesn’t let us specify a
      specific set of things which are
      allowed




Thursday, August 18, 11                      5
we want to enumerate what is
      allowed

      duck-typing doesn’t let us specify a
      specific set of things which are
      allowed



                     ๏    Types are often too coarse a granularity
                          for the kind of dispatch we would like to
                          specify




Thursday, August 18, 11                                               5
we want to enumerate what is
      allowed

      duck-typing doesn’t let us specify a
      specific set of things which are
      allowed



                     ๏    Types are often too coarse a granularity
                          for the kind of dispatch we would like to
                          specify

                     ๏    Duck-typing can be a source of pain.




Thursday, August 18, 11                                               5
we want to enumerate what is
      allowed

      duck-typing doesn’t let us specify a
      specific set of things which are
      allowed



                     ๏    Types are often too coarse a granularity
                          for the kind of dispatch we would like to
                          specify

                     ๏    Duck-typing can be a source of pain.

                     ๏    Pre and post conditions are also
                          “trapped inside” functions



Thursday, August 18, 11                                               5
we often reach into a
         data structure to pull it
         part ...
         but isn’t this just like
         what we do w/ cond +
         map? vector?




                                     (cond
                                       (= (first s) 1) ...
                                       (= (first s) 2) ...
                                       (= (second s) :foo) ...
                                       ...)




Thursday, August 18, 11                                          6
destructuring does make
        it more convenient... but
        something is still missing




                                     (let [[x & r] s]
                                       (cond
                                         (= x 1) ...
                                         (= x 2) ...
                                         (= (second s) :foo) ...
                                         ...))




Thursday, August 18, 11                                            7
this where we are today
          with match...

          we’ll talk about this but
          note that this is very
          much a chocolate fudge
          machine infused cond




                                      (match [x]
                                        [[1 & r]] ...
                                        [[2 & r]] ...
                                        [[_ :foo & r]] ...
                                        ...)




Thursday, August 18, 11                                      8
but this is where we’d
       like to be




                    (extend-pred foo [[1 & r]] ...)

                    (extend-pred foo [[2 & r]] ...)

                    (extend-pred foo [[_ :foo & r]] ...)




Thursday, August 18, 11                                    9
Goals




Thursday, August 18, 11           10
Goals
                     ๏    As fast or faster than destructuring for
                          matches with few cases




Thursday, August 18, 11                                              10
Goals
                     ๏    As fast or faster than destructuring for
                          matches with few cases
                     ๏    Pattern matching should follow
                          destructuring syntax when possible




Thursday, August 18, 11                                              10
Goals
                     ๏    As fast or faster than destructuring for
                          matches with few cases
                     ๏    Pattern matching should follow
                          destructuring syntax when possible
                     ๏    Extensible (!)




Thursday, August 18, 11                                              10
Goals
                     ๏    As fast or faster than destructuring for
                          matches with few cases
                     ๏    Pattern matching should follow
                          destructuring syntax when possible
                     ๏    Extensible (!)
                     ๏    Testbed for predicate dispatch


Thursday, August 18, 11                                              10
pattern matching



Thursday, August 18, 11                      11
Thursday, August 18, 11   12
๏    Popular feature among functional
                          programming languages - Standard ML,
                          Erlang, Haskell, OCaml, Scala




Thursday, August 18, 11                                          12
๏    Popular feature among functional
                          programming languages - Standard ML,
                          Erlang, Haskell, OCaml, Scala

                     ๏    Literature on efficient pattern matching
                          in the ML language family is extensive




Thursday, August 18, 11                                            12
๏    Popular feature among functional
                          programming languages - Standard ML,
                          Erlang, Haskell, OCaml, Scala

                     ๏    Literature on efficient pattern matching
                          in the ML language family is extensive

                     ๏    Decisions trees and backtracking
                          automata popular approaches


Thursday, August 18, 11                                            12
Thursday, August 18, 11   13
๏    Pattern matching in ML restricts the
                          types in the columns




Thursday, August 18, 11                                          13
๏    Pattern matching in ML restricts the
                          types in the columns

                     ๏    We want pattern matching to work
                          across types




Thursday, August 18, 11                                          13
Luc Maranget




Thursday, August 18, 11                  14
Thursday, August 18, 11   15
Thursday, August 18, 11   16
๏    Compiling Pattern Matching to Good
                          Decision Trees




Thursday, August 18, 11                                        16
๏    Compiling Pattern Matching to Good
                          Decision Trees

                     ๏    Simple compilation algorithm




Thursday, August 18, 11                                        16
๏    Compiling Pattern Matching to Good
                          Decision Trees

                     ๏    Simple compilation algorithm

                     ๏    Big idea is choosing which column to
                          test based on the notion of “necessity”
                          from lazy pattern matching



Thursday, August 18, 11                                             16
How it works in match




Thursday, August 18, 11                           17
false and true are literals, _ is a
        wildcard pattern, it will match
        anything




                                              (match [x y z]
                                                 [_ false true] 1
                                                 [false true _ ] 2
                                                 [_ _ false] 3
                                                 [_ _ true] 4
                                                 :else 5)




Thursday, August 18, 11                                              18
x   y   z
                          [_   f   t]   1
                          [f   t   _]   2
                          [_   _   f]   3
                          [_   _   t]   4
                          [_   _   _]   5




Thursday, August 18, 11                     19
top down evaluation
           order, we don’t need to
           test anything below a
           wildcard




                                      x   y   z
                                     [_   f   t]   1
                                     [f   t   _]   2
                                     [_   _   f]   3
                                     [_   _   t]   4
                                     [_   _   _]   5




Thursday, August 18, 11                                20
y column has the largest
        useful (non-wildcard)
        patterns




                                        y

                                   [_   f   t]   1
                                   [f   t   _]   2
                                   [_   _   f]   3
                                   [_   _   t]   4
                                   [_   _   _]   5




Thursday, August 18, 11                              21
swap y column to the
        front, now we need to
        specialize




                                 y   x   z
                                [f   _   t]   1
                                [t   f   _]   2
                                [_   _   f]   3
                                [_   _   t]   4
                                [_   _   _]   5




Thursday, August 18, 11                           22
Matrix Specialization



Thursday, August 18, 11                    23
set constructors in the y
       column




                                   #{t f}




Thursday, August 18, 11                     24
we remove the rows that


                                         x   z
        don’t match the value for
        y. we drop the y column.

        here are the next

                                                  2
        pattern matrices for the
        t wo values of y
                                        [f   _]
                                    t   [_
                                        [_
                                             f]
                                             t]
                                                  3
                                                  4
                                        [_   _]   5

                                         x   z
                                        [_   t]   1

                                    f   [_
                                        [_
                                             f]
                                             t]
                                                  3
                                                  4
                                        [_   _]   5


Thursday, August 18, 11                               25
rinse, repeat



Thursday, August 18, 11                   26
we can take that
                                                                               process and produce a
                                                                               nested conditional.
                     (cond                                                     note that the order
                      (= y false) (cond                                        testing matches
                                                                               what we saw in
                                   (= z false) (let [] 3)                      previous slides
                                   (= z true) (let [] 1)
                                   :else (throw (java.lang.Exception. "Found
                     FailNode")))
                      (= y true) (cond
                                  (= x false) (let [] 2)
                                  :else (cond
                                         (= z false) 3
                                         (= z true) 4
                                         :else (throw
                                                (java.lang.Exception.
                                                 "Found FailNode"))))
                      :else (cond
                             (= z false) (let [] 3)
                             (= z true) (let [] 4)
                             :else (throw (java.lang.Exception. "Found FailNode"))))




Thursday, August 18, 11                                                                                27
Thursday, August 18, 11   28
๏    a pattern matrix is composed of pattern
                          rows




Thursday, August 18, 11                                             28
๏    a pattern matrix is composed of pattern
                          rows

                     ๏    pattern rows contain all the specified
                          patterns in addition to an action




Thursday, August 18, 11                                             28
๏    a pattern matrix is composed of pattern
                          rows

                     ๏    pattern rows contain all the specified
                          patterns in addition to an action

                     ๏    pattern rows must all be of the same size
                          (equal number of patterns)



Thursday, August 18, 11                                               28
Thursday, August 18, 11   29
๏    Patterns in match are implemented as
                          deftypes




Thursday, August 18, 11                                          29
๏    Patterns in match are implemented as
                          deftypes

                     ๏    The key protocol for a pattern to extend
                          is ISpecializeMatrix which defines a
                          single protocol fn - specialize-matrix




Thursday, August 18, 11                                              29
๏    Patterns in match are implemented as
                          deftypes

                     ๏    The key protocol for a pattern to extend
                          is ISpecializeMatrix which defines a
                          single protocol fn - specialize-matrix

                     ๏    The pattern produces the new matrix
                          after specialization. This may involve
                          introducing new occurrences.

Thursday, August 18, 11                                              29
what are occurrences?




                                     y   x   z
                                    [f   _   t]
                                    [t   f   _]
                                    [_   _   f]
                                    [_   _   t]




Thursday, August 18, 11                           30
consider this seq pattern
            match




                                        (match   [x]
                                           [[1   & r] 1
                                           [[2   & r] 2
                                           [[3   & r] 3)




Thursday, August 18, 11                                    31
x
                          [[1 & r]]
                          [[2 & r]]
                          [[3 & r]]




Thursday, August 18, 11               32
when the matrix is specialized by
             SeqPattern we get this new pattern
             matrix. We have the occurrence that
             represents the head of the list and
             the tail of the list.




                                                   xh xt
                                                   [1 r]
                                                   [2 r]
                                                   [3 r]




Thursday, August 18, 11                                    33
The Decision Tree
Thursday, August 18, 11                       34
occurrences will end up
            being represented as
            switch nodes




                                                    1

                                                    2
                                      SwitchNodex
                                                    3

                                                    fail




Thursday, August 18, 11                                    35
Thursday, August 18, 11   36
๏    We end up with a tree of switch nodes.
                          Each switch nodes represents a
                          occurrence/binding and a multiway test
                          which points to other switch nodes, leaf
                          nodes, or fail nodes.




Thursday, August 18, 11                                              36
๏    We end up with a tree of switch nodes.
                          Each switch nodes represents a
                          occurrence/binding and a multiway test
                          which points to other switch nodes, leaf
                          nodes, or fail nodes.

                     ๏    This is the decision tree.



Thursday, August 18, 11                                              36
Examples



Thursday, August 18, 11              37
Seq pattern matching

              note that the length of the
              seq patterns do no matter!




                                            (match [x]
                                              [[1]   :a0
                                              [[1 2]] :a1
                                              [[1 2 nil nil nil]] :a2
                                              :else :a3)




Thursday, August 18, 11                                                 38
note the rest pattern syntax
          support just like destructuring.

          notice that we can introduce
          bindings anywhere we would
          use a wildcard




                                  (match [x]
                                    [[1]] :a0
                                    [[_ 2 & [a & b]]] [:a1 a b]
                                    :else :a2)




Thursday, August 18, 11                                           39
map pattern matching




                                       (match [x]
                                         [{_ :a 2 :b}] :a0
                                         [{1 :a _ :c}] :a1
                                         [{3 :c _ :d 4 :e}] :a2
                                         :else :a3)




Thursday, August 18, 11                                           40
we can restrict that only
          maps with the exact keys will
          match




                                (match [x]
                                  [{_ :a 2 :b :only [:a :b]}] :a0
                                  [{1 :a c :c}] :a1
                                  [{3 :c d :d 4 :e}] :a2
                                  :else :a3)




Thursday, August 18, 11                                             41
or patterns!




                          (match [x y z]
                            [[1 (3 | 4) 3]] :a0
                            [[1 (2 | 3) 3]] :a1
                            :else :a2)




Thursday, August 18, 11                           42
Guards!




                          (match [y]
                            [[_ (a :when even?) _ _]] :a0
                            [[_ (b :when [odd? div3?]) _ _]] :a1
                            :else :a2)




Thursday, August 18, 11                                            43
sometimes you want to
              match a specific
              portion and bind that
              to a local name




                                  (match [v]
                                    [[3 1]] :a0
                                    [[([1 a] :as b)]] [:a1 a b]
                                    :else :a2)




Thursday, August 18, 11                                           44
you can pattern match
      Java classes!




                              (extend-type java.util.Date
                                IMatchLookup
                                (val-at* [this k not-found]
                                  (case k
                                    :year    (.getYear this)
                                    :month   (.getMonth this)
                                    :date    (.getDate this)
                                    :hours   (.getHours this)
                                    :minutes (.getMinutes this)
                                    not-found)))




Thursday, August 18, 11                                           45
(let [d (java.util.Date. 2010 10 1 12 30)]
                 (match [d]
                   [{2009 :year a :month}] [:a0 a]
                   [{(2010 | 2011) :year b :month}] [:a1 b]))




Thursday, August 18, 11                                         46
problems




Thursday, August 18, 11              47
problems
                     ๏    Pattern matching is closed




Thursday, August 18, 11                                47
problems
                     ๏    Pattern matching is closed
                     ๏    We want the matching to happen at the
                          level of our most powerful abstraction -
                          functions




Thursday, August 18, 11                                              47
problems
                     ๏    Pattern matching is closed
                     ๏    We want the matching to happen at the
                          level of our most powerful abstraction -
                          functions
                     ๏    Without open dispatch, all we have is a
                          chocolate fudge machine powered cond


Thursday, August 18, 11                                              47
multimethods?



Thursday, August 18, 11                   48
problems




Thursday, August 18, 11              49
problems
                     ๏    Hard coded dispatch function




Thursday, August 18, 11                                  49
problems
                     ๏    Hard coded dispatch function
                     ๏    In order to specify complex matches we
                          have to construct a collection




Thursday, August 18, 11                                            49
problems
                     ๏    Hard coded dispatch function
                     ๏    In order to specify complex matches we
                          have to construct a collection
                     ๏    For complex matches, performance is less
                          than we would like



Thursday, August 18, 11                                              49
future directions




Thursday, August 18, 11                       50
future directions

                     ๏    Vector patterns: for any data type that
                          supports random access and fast
                          “slicing” - PersistentVector, primitive
                          arrays, buffers, etc.




Thursday, August 18, 11                                             50
future directions

                     ๏    Vector patterns: for any data type that
                          supports random access and fast
                          “slicing” - PersistentVector, primitive
                          arrays, buffers, etc.
                     ๏    Predicate Dispatch (huh?)



Thursday, August 18, 11                                             50
predicate dispatch



Thursday, August 18, 11                  51
pattern matching vs.
                predicate dispatch




Thursday, August 18, 11                52
pattern matching vs.
                predicate dispatch




                                       ๏   static vs. dynamic




Thursday, August 18, 11                                         52
pattern matching vs.
                predicate dispatch




                                       ๏   static vs. dynamic

                                       ๏   closed vs. open




Thursday, August 18, 11                                         52
pattern matching vs.
                predicate dispatch




                                       ๏   static vs. dynamic

                                       ๏   closed vs. open

                                       ๏   fast vs. slow (ouch)




Thursday, August 18, 11                                           52
Goals




Thursday, August 18, 11           53
Goals
                     ๏    move the matching to level of function, as with
                          multimethods




Thursday, August 18, 11                                                     53
Goals
                     ๏    move the matching to level of function, as with
                          multimethods
                     ๏    this change is in conflict with the semantics of
                          pattern matching - pattern matching is ordered




Thursday, August 18, 11                                                     53
Goals
                     ๏    move the matching to level of function, as with
                          multimethods
                     ๏    this change is in conflict with the semantics of
                          pattern matching - pattern matching is ordered
                     ๏    We need some way to know where to put new
                          pattern rows in the matrix



Thursday, August 18, 11                                                     53
A Sketch




Thursday, August 18, 11              54
A Sketch
                     ๏    Use core.logic to order the pattern rows




Thursday, August 18, 11                                              54
A Sketch
                     ๏    Use core.logic to order the pattern rows
                     ๏    A high performance in-memory DAG
                          representation of the decision tree




Thursday, August 18, 11                                              54
A Sketch
                     ๏    Use core.logic to order the pattern rows
                     ๏    A high performance in-memory DAG
                          representation of the decision tree
                     ๏    Perhaps we can go the route of deftype-
                          inline patterns get best performance



Thursday, August 18, 11                                              54
Challenges




Thursday, August 18, 11                55
Challenges
                     ๏    How much of the pattern matching
                          syntax can we bring over?




Thursday, August 18, 11                                      55
Challenges
                     ๏    How much of the pattern matching
                          syntax can we bring over?
                     ๏    How close can we get to the performance
                          of static code?




Thursday, August 18, 11                                             55
Challenges
                     ๏    How much of the pattern matching
                          syntax can we bring over?
                     ๏    How close can we get to the performance
                          of static code?
                     ๏    Can we limit the scope of changes to
                          namespaces?


Thursday, August 18, 11                                             55
(defpred foo
                            ([{a :a} 0] ...)
                            ([{a :a} (y :when even?)] ...))

                          (extend-pred foo [{c :c} 3]
                            ...)




Thursday, August 18, 11                                       56
Questions?



Thursday, August 18, 11                57

Contenu connexe

En vedette

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 2012Leonardo Borges
 
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 clojureAbbas Raza
 
プログラミング言語Clojureのニャンパスでの活用事例
プログラミング言語Clojureのニャンパスでの活用事例プログラミング言語Clojureのニャンパスでの活用事例
プログラミング言語Clojureのニャンパスでの活用事例sohta
 
Clojure from ground up
Clojure from ground upClojure from ground up
Clojure from ground upDi Xu
 

En vedette (11)

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
 

Patterns

  • 1. Pattern Matching & Predicate Dispatch Thursday, August 18, 11 1
  • 3. Dynamic programming languages are powerful, productive Thursday, August 18, 11 2
  • 4. Dynamic programming languages are powerful, productive ๏ Errors from dynamic typing are not fun Thursday, August 18, 11 2
  • 5. Dynamic programming languages are powerful, productive ๏ Errors from dynamic typing are not fun ๏ Too much type information is “trapped inside” Thursday, August 18, 11 2
  • 6. Dynamic programming languages are powerful, productive ๏ Errors from dynamic typing are not fun ๏ Too much type information is “trapped inside” ๏ We can do better without resorting to static types Thursday, August 18, 11 2
  • 7. closed versus open (cond (map? x) ... (vector? x) ... (list? x) ... :else ...) Thursday, August 18, 11 3
  • 8. better but... (extend-type IPersistentMap ...) (extend-type IPersistentVector ...) (extend-type IPersistentList ...) Thursday, August 18, 11 4
  • 9. we want to enumerate what is allowed duck-typing doesn’t let us specify a specific set of things which are allowed Thursday, August 18, 11 5
  • 10. we want to enumerate what is allowed duck-typing doesn’t let us specify a specific set of things which are allowed ๏ Types are often too coarse a granularity for the kind of dispatch we would like to specify Thursday, August 18, 11 5
  • 11. we want to enumerate what is allowed duck-typing doesn’t let us specify a specific set of things which are allowed ๏ Types are often too coarse a granularity for the kind of dispatch we would like to specify ๏ Duck-typing can be a source of pain. Thursday, August 18, 11 5
  • 12. we want to enumerate what is allowed duck-typing doesn’t let us specify a specific set of things which are allowed ๏ Types are often too coarse a granularity for the kind of dispatch we would like to specify ๏ Duck-typing can be a source of pain. ๏ Pre and post conditions are also “trapped inside” functions Thursday, August 18, 11 5
  • 13. we often reach into a data structure to pull it part ... but isn’t this just like what we do w/ cond + map? vector? (cond (= (first s) 1) ... (= (first s) 2) ... (= (second s) :foo) ... ...) Thursday, August 18, 11 6
  • 14. destructuring does make it more convenient... but something is still missing (let [[x & r] s] (cond (= x 1) ... (= x 2) ... (= (second s) :foo) ... ...)) Thursday, August 18, 11 7
  • 15. this where we are today with match... we’ll talk about this but note that this is very much a chocolate fudge machine infused cond (match [x] [[1 & r]] ... [[2 & r]] ... [[_ :foo & r]] ... ...) Thursday, August 18, 11 8
  • 16. but this is where we’d like to be (extend-pred foo [[1 & r]] ...) (extend-pred foo [[2 & r]] ...) (extend-pred foo [[_ :foo & r]] ...) Thursday, August 18, 11 9
  • 18. Goals ๏ As fast or faster than destructuring for matches with few cases Thursday, August 18, 11 10
  • 19. Goals ๏ As fast or faster than destructuring for matches with few cases ๏ Pattern matching should follow destructuring syntax when possible Thursday, August 18, 11 10
  • 20. Goals ๏ As fast or faster than destructuring for matches with few cases ๏ Pattern matching should follow destructuring syntax when possible ๏ Extensible (!) Thursday, August 18, 11 10
  • 21. Goals ๏ As fast or faster than destructuring for matches with few cases ๏ Pattern matching should follow destructuring syntax when possible ๏ Extensible (!) ๏ Testbed for predicate dispatch Thursday, August 18, 11 10
  • 24. Popular feature among functional programming languages - Standard ML, Erlang, Haskell, OCaml, Scala Thursday, August 18, 11 12
  • 25. Popular feature among functional programming languages - Standard ML, Erlang, Haskell, OCaml, Scala ๏ Literature on efficient pattern matching in the ML language family is extensive Thursday, August 18, 11 12
  • 26. Popular feature among functional programming languages - Standard ML, Erlang, Haskell, OCaml, Scala ๏ Literature on efficient pattern matching in the ML language family is extensive ๏ Decisions trees and backtracking automata popular approaches Thursday, August 18, 11 12
  • 28. Pattern matching in ML restricts the types in the columns Thursday, August 18, 11 13
  • 29. Pattern matching in ML restricts the types in the columns ๏ We want pattern matching to work across types Thursday, August 18, 11 13
  • 33. Compiling Pattern Matching to Good Decision Trees Thursday, August 18, 11 16
  • 34. Compiling Pattern Matching to Good Decision Trees ๏ Simple compilation algorithm Thursday, August 18, 11 16
  • 35. Compiling Pattern Matching to Good Decision Trees ๏ Simple compilation algorithm ๏ Big idea is choosing which column to test based on the notion of “necessity” from lazy pattern matching Thursday, August 18, 11 16
  • 36. How it works in match Thursday, August 18, 11 17
  • 37. false and true are literals, _ is a wildcard pattern, it will match anything (match [x y z] [_ false true] 1 [false true _ ] 2 [_ _ false] 3 [_ _ true] 4 :else 5) Thursday, August 18, 11 18
  • 38. x y z [_ f t] 1 [f t _] 2 [_ _ f] 3 [_ _ t] 4 [_ _ _] 5 Thursday, August 18, 11 19
  • 39. top down evaluation order, we don’t need to test anything below a wildcard x y z [_ f t] 1 [f t _] 2 [_ _ f] 3 [_ _ t] 4 [_ _ _] 5 Thursday, August 18, 11 20
  • 40. y column has the largest useful (non-wildcard) patterns y [_ f t] 1 [f t _] 2 [_ _ f] 3 [_ _ t] 4 [_ _ _] 5 Thursday, August 18, 11 21
  • 41. swap y column to the front, now we need to specialize y x z [f _ t] 1 [t f _] 2 [_ _ f] 3 [_ _ t] 4 [_ _ _] 5 Thursday, August 18, 11 22
  • 43. set constructors in the y column #{t f} Thursday, August 18, 11 24
  • 44. we remove the rows that x z don’t match the value for y. we drop the y column. here are the next 2 pattern matrices for the t wo values of y [f _] t [_ [_ f] t] 3 4 [_ _] 5 x z [_ t] 1 f [_ [_ f] t] 3 4 [_ _] 5 Thursday, August 18, 11 25
  • 46. we can take that process and produce a nested conditional. (cond note that the order (= y false) (cond testing matches what we saw in (= z false) (let [] 3) previous slides (= z true) (let [] 1) :else (throw (java.lang.Exception. "Found FailNode"))) (= y true) (cond (= x false) (let [] 2) :else (cond (= z false) 3 (= z true) 4 :else (throw (java.lang.Exception. "Found FailNode")))) :else (cond (= z false) (let [] 3) (= z true) (let [] 4) :else (throw (java.lang.Exception. "Found FailNode")))) Thursday, August 18, 11 27
  • 48. a pattern matrix is composed of pattern rows Thursday, August 18, 11 28
  • 49. a pattern matrix is composed of pattern rows ๏ pattern rows contain all the specified patterns in addition to an action Thursday, August 18, 11 28
  • 50. a pattern matrix is composed of pattern rows ๏ pattern rows contain all the specified patterns in addition to an action ๏ pattern rows must all be of the same size (equal number of patterns) Thursday, August 18, 11 28
  • 52. Patterns in match are implemented as deftypes Thursday, August 18, 11 29
  • 53. Patterns in match are implemented as deftypes ๏ The key protocol for a pattern to extend is ISpecializeMatrix which defines a single protocol fn - specialize-matrix Thursday, August 18, 11 29
  • 54. Patterns in match are implemented as deftypes ๏ The key protocol for a pattern to extend is ISpecializeMatrix which defines a single protocol fn - specialize-matrix ๏ The pattern produces the new matrix after specialization. This may involve introducing new occurrences. Thursday, August 18, 11 29
  • 55. what are occurrences? y x z [f _ t] [t f _] [_ _ f] [_ _ t] Thursday, August 18, 11 30
  • 56. consider this seq pattern match (match [x] [[1 & r] 1 [[2 & r] 2 [[3 & r] 3) Thursday, August 18, 11 31
  • 57. x [[1 & r]] [[2 & r]] [[3 & r]] Thursday, August 18, 11 32
  • 58. when the matrix is specialized by SeqPattern we get this new pattern matrix. We have the occurrence that represents the head of the list and the tail of the list. xh xt [1 r] [2 r] [3 r] Thursday, August 18, 11 33
  • 59. The Decision Tree Thursday, August 18, 11 34
  • 60. occurrences will end up being represented as switch nodes 1 2 SwitchNodex 3 fail Thursday, August 18, 11 35
  • 62. We end up with a tree of switch nodes. Each switch nodes represents a occurrence/binding and a multiway test which points to other switch nodes, leaf nodes, or fail nodes. Thursday, August 18, 11 36
  • 63. We end up with a tree of switch nodes. Each switch nodes represents a occurrence/binding and a multiway test which points to other switch nodes, leaf nodes, or fail nodes. ๏ This is the decision tree. Thursday, August 18, 11 36
  • 65. Seq pattern matching note that the length of the seq patterns do no matter! (match [x] [[1] :a0 [[1 2]] :a1 [[1 2 nil nil nil]] :a2 :else :a3) Thursday, August 18, 11 38
  • 66. note the rest pattern syntax support just like destructuring. notice that we can introduce bindings anywhere we would use a wildcard (match [x] [[1]] :a0 [[_ 2 & [a & b]]] [:a1 a b] :else :a2) Thursday, August 18, 11 39
  • 67. map pattern matching (match [x] [{_ :a 2 :b}] :a0 [{1 :a _ :c}] :a1 [{3 :c _ :d 4 :e}] :a2 :else :a3) Thursday, August 18, 11 40
  • 68. we can restrict that only maps with the exact keys will match (match [x] [{_ :a 2 :b :only [:a :b]}] :a0 [{1 :a c :c}] :a1 [{3 :c d :d 4 :e}] :a2 :else :a3) Thursday, August 18, 11 41
  • 69. or patterns! (match [x y z] [[1 (3 | 4) 3]] :a0 [[1 (2 | 3) 3]] :a1 :else :a2) Thursday, August 18, 11 42
  • 70. Guards! (match [y] [[_ (a :when even?) _ _]] :a0 [[_ (b :when [odd? div3?]) _ _]] :a1 :else :a2) Thursday, August 18, 11 43
  • 71. sometimes you want to match a specific portion and bind that to a local name (match [v] [[3 1]] :a0 [[([1 a] :as b)]] [:a1 a b] :else :a2) Thursday, August 18, 11 44
  • 72. you can pattern match Java classes! (extend-type java.util.Date IMatchLookup (val-at* [this k not-found] (case k :year (.getYear this) :month (.getMonth this) :date (.getDate this) :hours (.getHours this) :minutes (.getMinutes this) not-found))) Thursday, August 18, 11 45
  • 73. (let [d (java.util.Date. 2010 10 1 12 30)] (match [d] [{2009 :year a :month}] [:a0 a] [{(2010 | 2011) :year b :month}] [:a1 b])) Thursday, August 18, 11 46
  • 75. problems ๏ Pattern matching is closed Thursday, August 18, 11 47
  • 76. problems ๏ Pattern matching is closed ๏ We want the matching to happen at the level of our most powerful abstraction - functions Thursday, August 18, 11 47
  • 77. problems ๏ Pattern matching is closed ๏ We want the matching to happen at the level of our most powerful abstraction - functions ๏ Without open dispatch, all we have is a chocolate fudge machine powered cond Thursday, August 18, 11 47
  • 80. problems ๏ Hard coded dispatch function Thursday, August 18, 11 49
  • 81. problems ๏ Hard coded dispatch function ๏ In order to specify complex matches we have to construct a collection Thursday, August 18, 11 49
  • 82. problems ๏ Hard coded dispatch function ๏ In order to specify complex matches we have to construct a collection ๏ For complex matches, performance is less than we would like Thursday, August 18, 11 49
  • 84. future directions ๏ Vector patterns: for any data type that supports random access and fast “slicing” - PersistentVector, primitive arrays, buffers, etc. Thursday, August 18, 11 50
  • 85. future directions ๏ Vector patterns: for any data type that supports random access and fast “slicing” - PersistentVector, primitive arrays, buffers, etc. ๏ Predicate Dispatch (huh?) Thursday, August 18, 11 50
  • 87. pattern matching vs. predicate dispatch Thursday, August 18, 11 52
  • 88. pattern matching vs. predicate dispatch ๏ static vs. dynamic Thursday, August 18, 11 52
  • 89. pattern matching vs. predicate dispatch ๏ static vs. dynamic ๏ closed vs. open Thursday, August 18, 11 52
  • 90. pattern matching vs. predicate dispatch ๏ static vs. dynamic ๏ closed vs. open ๏ fast vs. slow (ouch) Thursday, August 18, 11 52
  • 92. Goals ๏ move the matching to level of function, as with multimethods Thursday, August 18, 11 53
  • 93. Goals ๏ move the matching to level of function, as with multimethods ๏ this change is in conflict with the semantics of pattern matching - pattern matching is ordered Thursday, August 18, 11 53
  • 94. Goals ๏ move the matching to level of function, as with multimethods ๏ this change is in conflict with the semantics of pattern matching - pattern matching is ordered ๏ We need some way to know where to put new pattern rows in the matrix Thursday, August 18, 11 53
  • 96. A Sketch ๏ Use core.logic to order the pattern rows Thursday, August 18, 11 54
  • 97. A Sketch ๏ Use core.logic to order the pattern rows ๏ A high performance in-memory DAG representation of the decision tree Thursday, August 18, 11 54
  • 98. A Sketch ๏ Use core.logic to order the pattern rows ๏ A high performance in-memory DAG representation of the decision tree ๏ Perhaps we can go the route of deftype- inline patterns get best performance Thursday, August 18, 11 54
  • 100. Challenges ๏ How much of the pattern matching syntax can we bring over? Thursday, August 18, 11 55
  • 101. Challenges ๏ How much of the pattern matching syntax can we bring over? ๏ How close can we get to the performance of static code? Thursday, August 18, 11 55
  • 102. Challenges ๏ How much of the pattern matching syntax can we bring over? ๏ How close can we get to the performance of static code? ๏ Can we limit the scope of changes to namespaces? Thursday, August 18, 11 55
  • 103. (defpred foo ([{a :a} 0] ...) ([{a :a} (y :when even?)] ...)) (extend-pred foo [{c :c} 3] ...) Thursday, August 18, 11 56