CL Extensions: CONTROL FLOW
 

Control Flow

In order to make the use of the UNIFICATION library easier, a few utility macros are provided. The macros MATCH, MATCHING, and MATCH-CASE can be used to unify two (or more) objects and then to build a lexical environment where the variables present in the to objects (or templates) are bound to the values resulting from the application of UNIFY.

  • MATCH is a "single shot" macro. It does one unification and executes forms in an appropriate lexical environment.
  • MATCH-CASE is equivalent to CASE. It tries to match a single object (or template) against a set of clauses. The forms associated to the first clause for which there is a successful unification, are then executed within an appropriate lexical environment.
  • MATCHING is equivalent to COND. Each clause contains a head

    Examples

    These macros allow the construction of interesting pattern matching like code.

      (defun factorial (x)
        (match-case (x)
          (0 1)
          (#T(number ?n) (* ?n (factorial (1- ?n))))
          (otherwise (error "Incorrect match for ~S." x))))
      

    Or consider the more interesting piece of code from a not-so hypothetical Red-Black tree implementation (cfr. [O98].) The function BALANCE is the key part of the rebalancing act played by Red-Black trees.

      (defstruct (tree-node (:conc-name tn-)
                            (:constructor mk-tn (color left elem right)))
         color
         left
         elem
         right)
    
      (defun balance (&rest balancing-arguments)
        (match-case (balancing-arguments)
          ((:black #T(tree-node tn-color :red
                                tn-left #T(tree-node tn-color :red
                                                     tn-left ?a
                                                     tn-elem ?x
                                                     tn-right ?b)
                                tn-elem ?y
                                tn-right ?c)
                   ?z
                   ?d)
            (mk-tn :red (mk-tn :black ?a ?x ?b) ?y (mk-tn :black ?c ?z ?d)))
          ((:black #T(tree-node tn-color :red
                                tn-left ?a
                                tn-elem ?x
                                tn-right #T(tree-node tn-color :red
                                                      tn-left ?b
                                                      tn-elem ?y
                                                      tn-right ?c))
                   ?z
                   ?d)
            (mk-tn :red (mk-tn :black ?a ?x ?b) ?y (mk-tn :black ?c ?z ?d)))
          ((:black ?a
                   ?x
                   #T(tree-node tn-color :red
                                tn-left #T(tree-node tn-color :red
                                                     tn-left ?b
                                                     tn-elem ?y
                                                     tn-right ?c)
                                tn-elem ?z
                                tn-right ?d))
            (mk-tn :red (mk-tn :black ?a ?x ?b) ?y (mk-tn :black ?c ?z ?d)))
          ((:black ?a
                   ?x
                   #T(tree-node tn-color :red
                                tn-left ?b
                                tn-elem ?y
                                tn-left #T(tree-node tn-color :red
                                                     tn-left ?c
                                                     tn-elem ?z
                                                     tn-right ?d)))
            (mk-tn :red (mk-tn :black ?a ?x ?b) ?y (mk-tn :black ?c ?z ?d)))
          ((?color ?left ?elem ?right)
            (mk-tn ?color ?left ?elem ?right))))
      

    This version of BALANCE is more verbose than the one given in [O98], but it preserves the general elegance of the ML implementation.

    Control Flow Dictionary

    Notes

    Other Forms

    It would be obvious to add the macros EMATCH-CASE and CMATCH-CASE, for symmetry with ECASE and CCASE. Also, MATCHING could be renamed to MATCH-COND.

    Current Implementation Details

    The current implementations of MATCHING and MATCH-CASE do not handle user supplied environments yet.

    References

    [O98] C. Okasaki, Purely Functional Data Structures, Cambridge University Press, 1998.

    Site Map

    Enjoy!


    Questions? Queries? Suggestions? Comments? Please direct them at me.