Skip to content

Latest commit

 

History

History
67 lines (52 loc) · 2.21 KB

README.md

File metadata and controls

67 lines (52 loc) · 2.21 KB

match-record

A Clojure library with a match macro match-record for the purpose of matching on Clojure record types.

Motivation

To emulate the deftype macro from the Racket EOPL dialect, and to have some fun constructing a non-trival macro in Clojure.

Usage

; Given an AST represented as nested records
(defrecord VarExp [id])
(defrecord LambdaExp [id body])
(defrecord AppExp [rator rand])

; And such an AST...
(def ast (AppExp. (LambdaExp. (VarExp. 'a)
                              (AppExp. (VarExp. 'a)
                                       (VarExp. 'b)))
                  (VarExp. 'c)))

; which represents...
 ((lambda (a) (a b)) c)

; instead of writing a functions like this...
(defn unparse-ast
  [node]
  (condp = (type node)
    VarExp (let [{:keys [id]} node] 
             id)
    LambdaExp (let [{:keys [id body]} node]
                (list 'lambda 
                      (list (unparse-ast id))
                      (unparse-ast body)))
    AppExp (let [{:keys [rator rand]} node]
             (list (unparse-ast rator)
                   (unparse-ast rand)))
    (throw (Exception. "Unmatched type"))))

; we would like to write this...
(defn unparse-ast
  [node]
  (match-record node 
    (VarExp id) -> id
    (LambdaExp id body) -> (list 'lambda 
                                 (list (unparse-ast id))
                                 (unparse-ast body))
    (AppExp rator rand) -> (list (unparse-ast rator)
                                 (unparse-ast rand))
    _ -> (throw (Exception. "No match for type"))))

(unparse-ast ast) ;-> ((lambda (a) (a b)) c)

Todo

Undoubtably, when errors would occur in the clauses passed to the macro, the likely error messages would not be pretty and perhaps not very helpful, potentially leaking the details of the macro implementation to users. Pending the validation of these statements, future work would be to improve the robustness of the macro and provide error messages that don't leak implementation details.

  • Validation of the clause forms
  • Handling of match variable ids that don't exist in the record.

License

Copyright © 2015 Chris Cornelison

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.