Skip to content

pattern combinators extending racket/match to capture šŸ”— contexts šŸ“¦

Notifications You must be signed in to change notification settings

disconcision/containment-patterns

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Ā 

History

29 Commits
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 

Repository files navigation

ā‹± CONTAINMENT PATTERNS ā‹±

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://github.com/disconcision/containment-patterns
  • 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:
(check-true
  (match `(0 (0 1) 2 3)
    [(ā‹± 1) #t]))
  1. Extracting data from a nested context:
(check-equal?
  (match `(0 (1 zap) 2 3)
    [(ā‹± `(1 ,a)) a])
  `zap)
  1. Making an update in a nested context:
(check-equal?
  (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:
(check-equal?
  (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))

About

pattern combinators extending racket/match to capture šŸ”— contexts šŸ“¦

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages