Skip to content
Browse files

Documentation.

  • Loading branch information...
1 parent fd841d2 commit 457d6a0854867b271cba8296d300e4a8d1c8b774 Tomohiro Matsuyama committed Apr 16, 2012
Showing with 294 additions and 3 deletions.
  1. +5 −0 .gitignore
  2. +161 −0 README.md
  3. +100 −0 fivepm.asd
  4. +16 −0 src/match.lisp
  5. +12 −3 src/pattern.lisp
View
5 .gitignore
@@ -0,0 +1,5 @@
+*.fasl
+*.dx64fsl
+*.dx32fsl
+*.lx64fsl
+*.x86f
View
161 README.md
@@ -0,0 +1,161 @@
+fivepm - Very Fast Pattern Matching Library
+===========================================
+
+fivepm is a very fast pattern matching library
+which uses optimizing techniques widely used in a functional
+programming world. See the following references for more detail:
+
+* [Optimizing Pattern Matching](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.6.5507) by Fabrice Le Fessant, Luc Maranget
+* [The Implementation of Functional Programming Languages](http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/) by Simon Peyton Jones
+
+Pattern Specifier
+-----------------
+
+A pattern specifier, or a pattern for short unless ambiguous, is an
+expression that describes how a value matches the pattern. Pattern
+specifiers are defined as follows:
+
+ pattern-specifier ::= constant-pattern
+ | variable-pattern
+ | constructor-pattern
+ | guard-pattern
+
+ constant-pattern ::= t | nil
+ | atom-except-symbol
+ | (quote VALUE)
+
+ variable-pattern ::= SYMBOL
+
+ constructor-pattern ::= (NAME PATTERN*)
+
+ guard-pattern ::= (guard PATTERN TEST-FORM)
+
+Constant patterns match the constant itself.
+
+Examples:
+
+ (match 1 (1 2)) => 2
+ (match "foo" ("foo" "bar")) => "bar"
+ (match '(1) ('(1) 2)) => 2
+
+Variable patterns match any value and bind the value to the
+variable. _ is a wildcard pattern which matches any value but doesn't
+bind.
+
+Examples:
+
+ (match 1 (x x)) => 1
+ (match 1 (_ 2)) => 2
+
+Constructor patterns match not a value itself but a structure of the
+value. The following constructors are available:
+
+* `(cons car cdr)
+* `(sequence &rest elements)
+* `(array &rest elements)
+* `(vector &rest elements)
+* `(simple-vector &rest elements)
+
+Examples:
+
+ (match '(1 . 2) ((cons a b) (+ a b))) => 3
+ (match #(1 2) ((simple-vector a b) (+ a b))) => 3
+
+LIST is not a constructor pattern but a dervied pattern. If we see the
+following pattern specifier
+
+ (list a b c)
+
+then we expand it into
+
+ (cons a (cons b (cons c nil)))
+
+See DEFPATTERN for more detail.
+
+In addition to above constructor patterns, there is one special
+constructor pattern which matches any value of type of STANDARD-CLASS.
+The form of the pattern looks like
+
+ (class-name &rest slots)
+
+where CLASS-NAME is a class name of the value and SLOTS is a list of
+the form of (SLOT-NAME PATTERN). You can also specify the element as
+SLOT-NAME, which is a shorthand for (SLOT-NAME SLOT-NAME).
+
+Examples:
+
+ (defstruct person name age)
+ (defvar foo (make-person :name "foo" :age 30))
+ (match foo
+ ((person name age) (list name age)))
+ => ("foo" 30)
+ (match foo
+ ((person (name "bar")) 'matched)
+ (_ 'not-matched))
+ => NOT-MATCHED
+
+Guard patterns restrict a matching of PATTERN with a post condition
+TEST-FORM. Note that a symbol GUARD is not exported.
+
+Examples:
+
+ (match 1 ((fivepm::guard x (evenp x)) 'even))
+ => NIL
+
+[Package] fivepm
+----------------
+
+## [Macro] defpattern
+
+ defpattern name lambda-list &body body
+
+Defines a derived pattern specifier named NAME. This is analogous
+to DEFTYPE.
+
+Examples:
+
+ ;; Defines a LIST pattern.
+ (defpattern list (&rest args)
+ (when args
+ `(cons ,(car args) (list ,@(cdr args)))))
+
+## [Macro] match
+
+ match arg &body clauses
+
+Matches ARG with CLAUSES. CLAUSES is a list of the form
+of (PATTERN . BODY) where PATTERN is a pattern specifier and BODY is
+an implicit progn. If ARG is matched with some PATTERN, then evaluates
+BODY and returns the evaluated value. Otherwise, returns NIL.
+
+If BODY starts with a symbol WHEN, then the next form will be used to
+introduce a guard for PATTERN. That is,
+
+ (match list ((list x) when (oddp x) x))
+
+will be translated to
+
+ (match list ((guard (list x) (oddpx)) x))
+
+## [Macro] ematch
+
+ ematch arg &body clauses
+
+Same as MATCH, except MATCH-ERROR will be raised if not matched.
+
+## [Macro] cmatch
+
+ cmatch arg &body clauses
+
+Same as MATCH, except continuable MATCH-ERROR will be raised if not
+matched.
+
+Authors
+-------
+
+* Tomohiro Matsuyama
+
+License
+-------
+
+LLGPL
View
100 fivepm.asd
@@ -1,5 +1,105 @@
(asdf:defsystem :fivepm
:description "Very Fast Pattern Matching Library"
+ :long-description "fivepm is a very fast pattern matching library
+which uses optimizing techniques widely used in a functional
+programming world. See the following references for more detail:
+
+* [Optimizing Pattern Matching](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.6.5507) by Fabrice Le Fessant, Luc Maranget
+* [The Implementation of Functional Programming Languages](http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/) by Simon Peyton Jones
+
+Pattern Specifier
+-----------------
+
+A pattern specifier, or a pattern for short unless ambiguous, is an
+expression that describes how a value matches the pattern. Pattern
+specifiers are defined as follows:
+
+ pattern-specifier ::= constant-pattern
+ | variable-pattern
+ | constructor-pattern
+ | guard-pattern
+
+ constant-pattern ::= T | NIL
+ | atom-except-symbol
+ | (quote VALUE)
+
+ variable-pattern ::= symbol
+
+ constructor-pattern ::= (NAME PATTERN*)
+
+ guard-pattern ::= (guard PATTERN TEST-FORM)
+
+Constant patterns match the constant itself.
+
+Examples:
+
+ (match 1 (1 2)) => 2
+ (match \"foo\" (\"foo\" \"bar\")) => \"bar\"
+ (match '(1) ('(1) 2)) => 2
+
+Variable patterns match any value and bind the value to the
+variable. _ is a wildcard pattern which matches any value but doesn't
+bind.
+
+Examples:
+
+ (match 1 (x x)) => 1
+ (match 1 (_ 2)) => 2
+
+Constructor patterns match not a value itself but a structure of the
+value. The following constructors are available:
+
+* `(cons car cdr)
+* `(sequence &rest elements)
+* `(array &rest elements)
+* `(vector &rest elements)
+* `(simple-vector &rest elements)
+
+Examples:
+
+ (match '(1 . 2) ((cons a b) (+ a b))) => 3
+ (match #(1 2) ((simple-vector a b) (+ a b))) => 3
+
+LIST is not a constructor pattern but a dervied pattern. If we see the
+following pattern specifier
+
+ (list a b c)
+
+then we expand it into
+
+ (cons a (cons b (cons c nil)))
+
+See DEFPATTERN for more detail.
+
+In addition to above constructor patterns, there is one special
+constructor pattern which matches any value of type of STANDARD-CLASS.
+The form of the pattern looks like
+
+ (class-name &rest slots)
+
+where CLASS-NAME is a class name of the value and SLOTS is a list of
+the form of (SLOT-NAME PATTERN). You can also specify the element as
+SLOT-NAME, which is a shorthand for (SLOT-NAME SLOT-NAME).
+
+Examples:
+
+ (defstruct person name age)
+ (defvar foo (make-person :name \"foo\" :age 30))
+ (match foo
+ ((person name age) (list name age)))
+ => (\"foo\" 30)
+ (match foo
+ ((person (name \"bar\")) 'matched)
+ (_ 'not-matched))
+ => NOT-MATCHED
+
+Guard patterns restrict a matching of PATTERN with a post condition
+TEST-FORM. Note that a symbol GUARD is not exported.
+
+Examples:
+
+ (match 1 ((fivepm::guard x (evenp x)) 'even))
+ => NIL"
:version "0.1"
:author "Tomohiro Matsuyama"
:license "LLGPL"
View
16 src/match.lisp
@@ -13,6 +13,19 @@
(match-patterns condition)))))
(defmacro match (arg &body clauses)
+ "Matches ARG with CLAUSES. CLAUSES is a list of the form
+of (PATTERN . BODY) where PATTERN is a pattern specifier and BODY is
+an implicit progn. If ARG is matched with some PATTERN, then evaluates
+BODY and returns the evaluated value. Otherwise, returns NIL.
+
+If BODY starts with a symbol WHEN, then the next form will be used to
+introduce a guard for PATTERN. That is,
+
+ (match list ((list x) when (oddp x) x))
+
+will be translated to
+
+ (match list ((guard (list x) (oddpx)) x))"
(once-only (arg)
`(%match-1 ,arg ,clauses nil)))
@@ -22,6 +35,7 @@
:patterns patterns))
(defmacro ematch (arg &body clauses)
+ "Same as MATCH, except MATCH-ERROR will be raised if not matched."
(once-only (arg)
(let ((else `(%ematch-else ,arg ',(mapcar #'car clauses))))
`(%match-1 ,arg ,clauses ,else))))
@@ -33,6 +47,8 @@
:patterns patterns))
(defmacro cmatch (arg &body clauses)
+ "Same as MATCH, except continuable MATCH-ERROR will be raised if not
+matched."
(once-only (arg)
(let ((else `(%cmatch-else ,arg ',(mapcar #'car clauses))))
`(%match-1 ,arg ,clauses ,else))))
View
15 src/pattern.lisp
@@ -24,7 +24,7 @@
test-form)
;;;
-;;; Pattern Expression
+;;; Pattern Specifier
;;;
(defun pattern-expand-function (name)
@@ -54,14 +54,23 @@
pattern))
(defmacro defpattern (name lambda-list &body body)
+ "Defines a derived pattern specifier named NAME. This is analogous
+to DEFTYPE.
+
+Examples:
+
+ ;; Defines a LIST pattern.
+ (defpattern list (&rest args)
+ (when args
+ `(cons ,(car args) (list ,@(cdr args)))))"
`(setf (pattern-expand-function ',name) (lambda ,lambda-list ,@body)))
(defpattern list (&rest args)
(when args
`(cons ,(car args) (list ,@(cdr args)))))
;;;
-;;; Pattern Expression Parser
+;;; Pattern Specifier Parser
;;;
(defun parse-pattern (pattern)
@@ -72,7 +81,7 @@
((or (eql t) null keyword)
(make-constant-pattern :value pattern))
(symbol
- (make-variable-pattern :name pattern))
+ (make-variable-pattern :name (unless (string= pattern "_") pattern)))
(cons
(case (first pattern)
(quote

0 comments on commit 457d6a0

Please sign in to comment.
Something went wrong with that request. Please try again.