Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Literal pattern matching library in common lisp

branch: master

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 test
Octocat-spinner-32 Makefile
Octocat-spinner-32 README
Octocat-spinner-32 litmatch.lisp
README
 LitMatch - Yet Another Pattern Matching Library
=================================================

 Introduction
--------------

LitMatch is the pattern matching library for Common Lisp. It was made
for writing pattern patching as if you write just literals. Let's see
examples.

    (defun litmatch-sample1 (x)
      (litmatch x
        ((hello japan)	"x is (hello japan)")
        ((hello world)	"x is (hello world)")
        (t			"x is unknown")))

Here is a sample function 'litmatch-sample1'. It contains one pattern
matching expression containing three clauses.

    > (litmatch-sample1 '(hello japan))
    ;=> "x is (hello japan)"
    
    > (litmatch-sample1 '(hello world))
    ;=> "x is (hello world)"
    
    > (litmatch-sample1 '(hello universe))
    ;=> "x is unknown"

You can try more complicated data structure.

    (defun litmatch-sample2 (x)
      (litmatch x
        ((1 2 3 (4 5) 6)		"clause 1")
        ((1 2 (3 (4 5) 6))		"clause 2")))

    > (litmatch-sample2 '(1 2 3 (4 5) 6))
    ;=> "clause 1"
    
    > (litmatch-sample2 '(1 2 (3 (4 5) 6)))
    ;=> "clause 2"
    
    > (litmatch-sample2 '(1 (2 (3 (4 5) 6))))
    ;=> NIL

As you can see in last result, NIL is returned when there's no
matching clause.

The matcher '_'(underscore) matches with ANY data. If you use single T
as a matcher, it works the same as underscore.

> (litmatch 1 (_ 'OK))
;=> OK

> (litmatch '(1 2 3) ((1 2 _) 'OK))
;=> OK

> (litmatch '(1 2 3) ((1 . _) 'OK))  ;;; (1 2 3) == (1 . (2 . (3 . nil)))
;=> OK

You can capture matched values by two ways. One is the 'v%' prefix.

> (litmatch 1 (v%matched-value matched-value))
;=> 1

> (litmatch '(1 2 3) ((1 2 v%matched-value) matched-value))
;=> 3

> (litmatch '(1 2 3) ((1 . v%matched-value) matched-value))  ;;; (1 2 3) == (1 . (2 . (3 . nil)))
;=> (2 3)

If you use a 'v%' prefixed symbol in a matcher, corresponding value is
bound to the symbol and available in a body of the clause.

Another way of capturing value is 'as%' prefix.

> (litmatch '(1 2 3) ((1 2 (3 . as%matched-value)) matched-value))
;=> 3

> (litmatch '(1 2 3) ((1 . ((2 3) . as%matched-value)) matched-value))  ;;; (1 2 3) == (1 . (2 . (3 . nil)))
;=> (2 3)

'as%' prefix is always used in this form: (<matcher> . as%<symbol name>)

This cons pair means "If the <matcher> matches with a corresponding
value, bind it to <symbol name>." 'as%' prefix is useful when you want
to capture a value and impose some conditions on it. 'v%' prefixed
symbol just capture a value without checking its contents.


 Formal description of LitMatch syntax
---------------------------------------

(litmatch:litmatch <matched-value>
  <clauses>)

<matched-value>	:= <expr>
<clauses>	:= <clause> *
<clause>	:= (<matcher> <body>)
<matcher>	:= literal expression with _(undescore) matchers, 'v%' prefixed symbols and 'as%' prefixed symbols
<body>		:= <expr> *
<expr>		:= any valid lisp expression
Something went wrong with that request. Please try again.