Skip to content

Commit

Permalink
minor markdown stylization
Browse files Browse the repository at this point in the history
  • Loading branch information
Nick Allen committed Mar 28, 2009
1 parent e051f28 commit dddf822
Showing 1 changed file with 20 additions and 26 deletions.
46 changes: 20 additions & 26 deletions README.md
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -110,10 +110,10 @@ Note: you can use a `WHERE` or `WHERE-NOT` clauses within `DEF!`/`DEF` or `MATCH


## API ## API


- - -

* `MATCH (form &amp clauses)` * `MATCH (form &amp clauses)`


- - -

_macro_ `Match` is like [`CASE`](http://www.lisp.org/HyperSpec/Body/mac_casecm_ccasecm_ecase.html) except it uses S-Expression Patterns instead of keys and success forms re executed within the lexical scope of their respective matches. _macro_ `Match` is like [`CASE`](http://www.lisp.org/HyperSpec/Body/mac_casecm_ccasecm_ecase.html) except it uses S-Expression Patterns instead of keys and success forms re executed within the lexical scope of their respective matches.


cl-user> (match '(1 2) cl-user> (match '(1 2)
Expand All @@ -128,11 +128,11 @@ Note: you can use a `WHERE` or `WHERE-NOT` clauses within `DEF!`/`DEF` or `MATCH


`MATCH` clauses can optionally take an arbitrary number of `WHERE` and `WHERE-NOT` clauses. `MATCH` clauses can optionally take an arbitrary number of `WHERE` and `WHERE-NOT` clauses.


- - -

* `DEF! (name pattern &body body)` * `DEF! (name pattern &body body)`
`DEF (name pattern &body body)` `DEF (name pattern &body body)`


- - -

_macro_ `DEF!` is like `DEFUN` except it takes an S-Expression Pattern instead of a lambda list. The created function takes one argument: if that argument matches `PATTERN`, then the function executes `BODY` within the lexical scope of the match. Otherwise it simply returns `NIL`. _macro_ `DEF!` is like `DEFUN` except it takes an S-Expression Pattern instead of a lambda list. The created function takes one argument: if that argument matches `PATTERN`, then the function executes `BODY` within the lexical scope of the match. Otherwise it simply returns `NIL`.


cl-user> (def! foo (_x . _y) cl-user> (def! foo (_x . _y)
Expand All @@ -158,11 +158,11 @@ Note: you can use a `WHERE` or `WHERE-NOT` clauses within `DEF!`/`DEF` or `MATCH


Both `DEF!` and `DEF` can optionally have an arbitrary number of `WHERE` and `WHERE-NOT` clauses in `BODY`. Both `DEF!` and `DEF` can optionally have an arbitrary number of `WHERE` and `WHERE-NOT` clauses in `BODY`.


- - -

* `WHERE` * `WHERE`
`WHERE` `WHERE`


- - -

_symbols_ The symbols `WHERE` and `WHERE-NOT` act as special keywords when seen inside `MATCH` clauses or `DEF!`/`DEF` bodies. _symbols_ The symbols `WHERE` and `WHERE-NOT` act as special keywords when seen inside `MATCH` clauses or `DEF!`/`DEF` bodies.


`WHERE` and `WHERE-NOT` can be thought of as functions that take a single argument (`TEST`): when `WHERE` or `WHERE-NOT` forms appear immediatly after a sexp pattern, a match against that pattern is not considered successful unless all the `WHERE` arguments evaluate to non-`NIL` values and the `WHERE-NOT` arguments evaluate to `NIL`. `WHERE` and `WHERE-NOT` can be thought of as functions that take a single argument (`TEST`): when `WHERE` or `WHERE-NOT` forms appear immediatly after a sexp pattern, a match against that pattern is not considered successful unless all the `WHERE` arguments evaluate to non-`NIL` values and the `WHERE-NOT` arguments evaluate to `NIL`.
Expand All @@ -189,33 +189,29 @@ Note: `WHERE` and `WHERE-NOT` clauses are "short-circuiting" (like `AND`).
(def get-username _req (def get-username _req
(error 'bad-request :request _req)) (error 'bad-request :request _req))


- - -

* `BPM-LAMBDA (pattern &body body)` * `BPM-LAMBDA (pattern &body body)`


- - -

_macro_ `BPM-LAMBDA` is just like `LAMBDA` except that it takes an S-Expression pattern as a first argument instead of a lambda list. _macro_ `BPM-LAMBDA` is just like `LAMBDA` except that it takes an S-Expression pattern as a first argument instead of a lambda list.


The resultant function takes on argument: if that argument matches `PATTERN` then the function executes `BODY` within the lexical scope of the match. Otherwise it simply returns `NIL`. The resultant function takes on argument: if that argument matches `PATTERN` then the function executes `BODY` within the lexical scope of the match. Otherwise it simply returns `NIL`.


Caveat: `BPM-LAMBDA` does not understand `WHERE` or `WHERE-NOT` clauses. Caveat: `BPM-LAMBDA` does not understand `WHERE` or `WHERE-NOT` clauses.


- - -

* `CREATE-BPM-COMPILER (pattern &optional bound)` * `CREATE-BPM-COMPILER (pattern &optional bound)`


- - -

_function_ `CREATE-BPM-COMPILER` takes an S-Expression Pattern and a list of already bound logic variables. It returns a function (`FUNCTION1`) and a new list of logiv variables. _function_ `CREATE-BPM-COMPILER` takes an S-Expression Pattern and a list of already bound logic variables. It returns a function (`FUNCTION1`) and a new list of logiv variables.


This new function takes a piece of unevaluated lisp code and returns the source of a new unary function (`FUNCTION2`). If `FUNCTION2`'s argument matches `PATTERN`, then `FUNCTION2` executes the lisp code given to `FUNCTION2` within the lexical scope of the match. Otherwise it simply returns `NIL`. This new function takes a piece of unevaluated lisp code and returns the source of a new unary function (`FUNCTION2`). If `FUNCTION2`'s argument matches `PATTERN`, then `FUNCTION2` executes the lisp code given to `FUNCTION2` within the lexical scope of the match. Otherwise it simply returns `NIL`.


- - -

`BPM-LAMBDA` can be implemented as: `BPM-LAMBDA` can be implemented as:


(defmacro bpm-lambda (pattern &body body) (defmacro bpm-lambda (pattern &body body)
(funcall (create-bpm-compiler pattern) `(progn ,@body))) (funcall (create-bpm-compiler pattern) `(progn ,@body)))


- - -

`CREATE-BPM-COMPILER`'s second return value is the accumulated list of logiv variables that will be bound within `FUNCTION2`'s evaluation of the lisp form given as an argument to `FUNCTION1`. This list can be given as the argument to `CREATE-BPM-COMPILER`'s optional `BOUND` argument in recursive calls to `CREATE-BPM-COMPILER`: in this way it is possible to create nested pattern matchers that are lexically aware of the pattern matching environment around them. `CREATE-BPM-COMPILER`'s second return value is the accumulated list of logiv variables that will be bound within `FUNCTION2`'s evaluation of the lisp form given as an argument to `FUNCTION1`. This list can be given as the argument to `CREATE-BPM-COMPILER`'s optional `BOUND` argument in recursive calls to `CREATE-BPM-COMPILER`: in this way it is possible to create nested pattern matchers that are lexically aware of the pattern matching environment around them.


cl-user> (create-bpm-compiler '(1 _1 #(_1 _2) _2)) cl-user> (create-bpm-compiler '(1 _1 #(_1 _2) _2))
Expand Down Expand Up @@ -252,38 +248,36 @@ Note: `WHERE` and `WHERE-NOT` clauses are "short-circuiting" (like `AND`).
"one" "one"
"two" "two"


- - -

* `*LOGIV-VAR-PREFIX-CHAR*` * `*LOGIV-VAR-PREFIX-CHAR*`


_variable_ The character that indicates logic and wildcard variables. Initially set to `#\_`.

- - - - - -


* `*LOGIV-VAR-PRED*` _variable_ The character that indicates logic and wildcard variables. Initially set to `#\_`.


_variable_ A unary predicate that returns if its argument is a logic variable. Initially set to a function that looks for symbols whose names start with `*LOGIC-VAR-PREFIX-CHAR*` * `*LOGIV-VAR-PRED*`


- - - - - -


* `*LOGIV-VAR-WILDCARD*` _variable_ A unary predicate that returns if its argument is a logic variable. Initially set to a function that looks for symbols whose names start with `*LOGIC-VAR-PREFIX-CHAR*`


_variable_ A unary predicate that returns `T` if its argument is a logic var wildcard. Initially set to a function that looks for symbols with the name `*LOGIC-VAR-PREFIX-CHAR*` * `*LOGIV-VAR-WILDCARD*`


- - - - - -


* `*DESTRUCTURE-SIMPLE-VECTORS-P*` _variable_ A unary predicate that returns `T` if its argument is a logic var wildcard. Initially set to a function that looks for symbols with the name `*LOGIC-VAR-PREFIX-CHAR*`


_variable_ Initially set to T. Bind this to NIL if you want vectors to be seen as atomic objects in your S-Expression Patterns. * `*DESTRUCTURE-SIMPLE-VECTORS-P*`


- - - - - -


_variable_ Initially set to T. Bind this to NIL if you want vectors to be seen as atomic objects in your S-Expression Patterns.

* `*LOGIC-VAR-EQUALITY-TEST*` * `*LOGIC-VAR-EQUALITY-TEST*`


_variable_ Lambda form or name of function that tests whether or not S-Expressions match parts of an S-Expression pattern. Initially set to `EQL`. _variable_ Lambda form or name of function that tests whether or not S-Expressions match parts of an S-Expression pattern. Initially set to `EQL`.


- - -

* `->` / `-->` * `->` / `-->`


- - -

_constants_ Syntactic spice. These self-evaluating constants exist only to help make your code more visually intuitive. _constants_ Syntactic spice. These self-evaluating constants exist only to help make your code more visually intuitive.

0 comments on commit dddf822

Please sign in to comment.