Skip to content
pattern combinators extending racket/match to capture πŸ”— contexts πŸ“¦
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


Tangerine Nightmare

β‹± Capture Contexts with Composable Continuations

This library implements several match-expanders which can be used anywhere racket/match pattern-matching is available. β‹± , β‹±+ , and β‹±1 are match-expanders which implement containment patterns. These descend into s-expressions to capture arbitrarily deep matches and their multi-holed contexts.

β‹± Why

I implemented containment patterns to write concise updates on nested structures for syntax-rewriting purposes in structured-editing and algebraic-stepper prototypes. See fructure for an actual use case, or for something simpler, this toy stepper. These are also integrated into fructerm.

β‹± How

Technically: an n-holed context is a captured composable continuation which can be used in a match template as a normal n-ary procedure. These continuations are captured as the pattern-matcher left-to-right preorder-traverses the target looking for matches.

Explicitly: The pattern (β‹± <context-name> <pattern>) binds a procedure to <context-name> and a <match> to <pattern> satisfying (equal? (<context> <matches>) target). β‹±+ is similar, but it binds a list of all matches instead of just the first result, and β‹±1 insists that the match should be unique.

Caveat: If you're using any matchers which have side-effects, note that the inner pattern is evaluated twice for each successful match.

β‹± Installation and Usage Instructions

  • Execute raco pkg install git://
  • Add (require containment-patterns)
  • Insert a β‹± in Dr. Racket by typing \ddo (diagonal dots) and then pressing alt+\

β‹± Usage Examples

See the tests in main.rkt for more examples and additional secret bonus features (which may not yet have found their final forms):

  1. Check if an item is contained in a nested list:
  (match `(0 (0 1) 2 3)
    [(β‹± 1) #t]))
  1. Extracting data from a nested context:
  (match `(0 (1 zap) 2 3)
    [(β‹± `(1 ,a)) a])
  1. Making an update in a nested context:
  (match '(0 0 (0 (0 0 (β–Ή 1)) 0 0))
    [(β‹± context `(β–Ή ,a))
     (β‹± context `(β–Ή ,(add1 a))])
  '(0 0 (0 (0 0 (β–Ή 2)) 0 0))
  1. Serial substitutions: (note how β‹±+ is optional in the template; a context is just a function)
(match '(0 1 (0 1 (1 0)) 0 1)
  [(β‹±+ c 1)
   (c 3 4 5 6)])
  1. Moving a cursor β–Ή through a traversal in a nested list of 0s and 1s:
  (match '(0 1 (0 1 (1 (β–Ή 0))) 0 1)
    [(β‹±+ c (and a (or `(β–Ή ,_) (? number?))))
     (β‹±+ c (match a [`(,x ... (β–Ή ,y) ,z ,w ...)
                      `(,@x ,y (β–Ή ,z) ,@w)]))])
  '(0 1 (0 1 (1 0)) (β–Ή 0) 1))
You can’t perform that action at this time.