Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Extensible Pattern Matching
Search
Sam Tobin-Hochstadt
September 26, 2011
Programming
1
72
Extensible Pattern Matching
A talk at IFL 2010 in Alphen an der Rijn, the Netherlands
Sam Tobin-Hochstadt
September 26, 2011
Tweet
Share
More Decks by Sam Tobin-Hochstadt
See All by Sam Tobin-Hochstadt
Evolving Existing Languages: The Typed Racket Experience
samth
1
130
Logical Types for Untyped Languages
samth
1
230
Semantic Solutions to Program Analysis Problems
samth
1
80
Other Decks in Programming
See All in Programming
contribution to astral-sh/uv
shunsock
0
530
バッチ処理を「状態の記録」から「事実の記録」へ
panda728
PRO
0
190
Google Opalで使える37のライブラリ
mickey_kubo
3
140
Developer Joy - The New Paradigm
hollycummins
1
360
CSC305 Lecture 09
javiergs
PRO
0
310
はじめてのDSPy - 言語モデルを『プロンプト』ではなく『プログラミング』するための仕組み
masahiro_nishimi
4
14k
品質ワークショップをやってみた
nealle
0
620
iOSでSVG画像を扱う
kishikawakatsumi
0
160
コード生成なしでモック処理を実現!ovechkin-dm/mockioで学ぶメタプログラミング
qualiarts
0
260
組込みだけじゃない!TinyGo で始める無料クラウド開発入門
otakakot
2
370
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
610
Android16 Migration Stories ~Building a Pattern for Android OS upgrades~
reoandroider
0
130
Featured
See All Featured
Designing for Performance
lara
610
69k
Context Engineering - Making Every Token Count
addyosmani
8
300
KATA
mclloyd
PRO
32
15k
The Invisible Side of Design
smashingmag
302
51k
Designing for humans not robots
tammielis
254
26k
How To Stay Up To Date on Web Technology
chriscoyier
791
250k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
31
2.7k
Testing 201, or: Great Expectations
jmmastey
45
7.7k
Side Projects
sachag
455
43k
The World Runs on Bad Software
bkeepers
PRO
72
11k
jQuery: Nuts, Bolts and Bling
dougneiner
65
7.9k
Leading Effective Engineering Teams in the AI Era
addyosmani
7
600
Transcript
Extensible Pattern Matching Sam Tobin-Hochstadt PLT @ Northeastern University IFL,
September 3, 2010
Extensible Pattern Matching in an Extensible Language Sam Tobin-Hochstadt PLT
@ Northeastern University IFL, September 3, 2010
(: magnitude : Complex -> Real) (define (magnitude n) (cond
[(eq? (first n) 'cart) (sqrt (+ (sqr (second n)) (sqr (third n))))] [(eq? (first n) 'polar) (second n)]))
(: magnitude : Complex -> Real) (define (magnitude n) (if
(not (pair? n)) (error 'bad-input) (let ([t1 (first n)] [t1* (rest n)]) (if (not (pair? t1*)) (error 'bad-input) (let ([t2 (first t1*)] [t2* (rest t1*)]) (if (not (pair? t3)) (error 'bad-input) (let ([t3 (first t2*)] [t3* (rest t2*)]) (if (not (null? t3)) (error 'bad-input)) (cond [(eq? t1 'cart) (sqrt (+ (sqr t2) (sqr t3)))] [(eq? t1 'polar) t2] [else (error 'bad-input)]))))))) )
(: magnitude : Complex -> Real) (define (magnitude n) (match
n [(list 'cart x y) (sqrt (+ (sqr x) (sqr y)))] [(list 'polar r theta) r]))
(: magnitude : Complex -> Real) (define (magnitude n) (match
n [(list 'cart xs ...) (sqrt (apply + (map sqr xs)))] [(list 'polar r theta ...) r]))
(: magnitude : Complex -> Real) (define (magnitude n) (match
n [(cart xs ...) (sqrt (apply + (map sqr xs)))] [(polar r theta ...) r]))
(: magnitude : Complex -> Real) (define (magnitude n) (match
n [(polar r theta ...) r]))
Pattern Matching in Racket
match works for arbitrary data (match e [(list a b)
(+ a b)] [(? string? a) (string-length a)] [(? number? a) a])
match provides expressive patterns (match e [(app add1 n) n])
match is an optimizer (match e [(list (? B?)) do-something-else])
[Le Fessant & Maranget]
match supports recursive patterns (match (list 2 4 6 8
10) [(list (? even? y) ...) (foldr + 0 y)])
match supports recursive patterns (match '(3 2 1 3) [(list-no-order
1 2 3 ...) 'yes] [_ 'no])
Extensible Languages
Simple Language Extension (define-syntax (let ([x e] ...) body) ((lambda
(x ...) body) e ...)) (let ([x 1] [y 2]) (+ x y))
Simple Language Extension (define-syntax (let ([x e] ...) body) ((lambda
(x ...) body) e ...)) (let ([x 1] [y 2]) (+ x y)) ((lambda (x y) (+ x y)) 1 2)
Simple Language Extension (define-syntax (let ([x e] ...) body) ((lambda
(x ...) body) e ...)) (let ([x 1] [y 2]) (+ x y)) ((lambda (x y) (+ x y)) 1 2) [Kohlbecker et al, 1980s]
Adding Computation (define-syntax (numbers start end) (list (in-range start end)))
(numbers 1 10)
Adding Computation (define-syntax (numbers start end) (list (in-range start end)))
(numbers 1 10) (list 1 2 3 4 5 6 7 8 9 10)
Adding Computation (define-syntax (numbers start end) (list (in-range start end)))
(numbers 1 10) (list 1 2 3 4 5 6 7 8 9 10) [Dybvig et al, 1990s]
Racket Modular Language Extension Compiler API Arbitrary Language Rewriting ...
Racket Modular Language Extension Compiler API Arbitrary Language Rewriting ...
[Flatt et al, 2000s]
(define-syntax x 1) (define-syntax (get-x) (syntax-value x)) (get-x)
(define-syntax x 1) (define-syntax (get-x) (syntax-value x)) (get-x) 1
Extensible Pattern Matching
(define-syntax (let ([x e] ...) b) ((lambda (x ...) b)
e ...))
(define-syntax (let ([x e] ...) b) ((lambda (x ...) b)
e ...)) (define-matcher (not-false p) (? (compose not false?) p))
The core of match (define (parse-pattern pat) (syntax-case pat [(cons
pat1 pat2) ...] [(? pred pat) ...] ...))
The extended core (define (parse-pattern pat) (syntax-case pat [(id pats
...) ] [(cons pat1 pat2) ...] [(? pred pat) ...] ...))
The extended core (define (parse-pattern pat) (syntax-case pat [(id pats
...) #:when (bound-to-match-expander? id) ] [(cons pat1 pat2) ...] [(? pred pat) ...] ...))
The extended core (define (parse-pattern pat) (syntax-case pat [(id pats
...) #:when (bound-to-match-expander? id) (syntax-value id) ] [(cons pat1 pat2) ...] [(? pred pat) ...] ...))
The extended core (define (parse-pattern pat) (syntax-case pat [(id pats
...) #:when (bound-to-match-expander? id) (match-expander-fn (syntax-value id)) ] [(cons pat1 pat2) ...] [(? pred pat) ...] ...))
The extended core (define (parse-pattern pat) (syntax-case pat [(id pats
...) #:when (bound-to-match-expander? id) (let ([transformer (match-expander-fn (syntax-value id))]) )] [(cons pat1 pat2) ...] [(? pred pat) ...] ...))
The extended core (define (parse-pattern pat) (syntax-case pat [(id pats
...) #:when (bound-to-match-expander? id) (let ([transformer (match-expander-fn (syntax-value id))]) (transformer (id pats ...)) )] [(cons pat1 pat2) ...] [(? pred pat) ...] ...))
The extended core (define (parse-pattern pat) (syntax-case pat [(id pats
...) #:when (bound-to-match-expander? id) (let ([transformer (match-expander-fn (syntax-value id))]) (parse-pattern (transformer (id pats ...))))] [(cons pat1 pat2) ...] [(? pred pat) ...] ...))
An Example (define-matcher (not-false p) ...) (match (list 7 #f)
[(list (not-false x) ... y) x])
An Example (define-syntax not-false (match-expander ...)) (match (list 7 #f)
[(list (not-false x) ... y) x])
An Example (define-syntax not-false (match-expander ...)) (match (list 7 #f)
[(list (not-false z) ... y) z]) (let ([transformer (match-expander-fn (syntax-value not-false))]) (parse-pattern (transformer (not-false z))))
An Example (define-syntax not-false (match-expander ...)) (match (list 7 #f)
[(list (not-false z) ... y) z]) (? (compose not false?) z)
An Example (define-syntax not-false (match-expander ...)) (match (list 7 #f)
[(list (? (compose not false?) z) ... y) z])
Applications
Views [Wadler 87] as a library (require (planet cobbe/views/views)) (define-view
Zero zero? ()) (define-view Succ exact-positive-integer? (sub1)) (define (even? n) (match n [(Zero) true] [(Succ (Zero)) false] [(Succ (Succ n)) (even? n)]))
Web Server Dispatching (dispatch-rules [("") list-posts] [("posts" (string-arg)) review-post] [("archive"
(integer-arg) (integer-arg)) review-archive] [else list-posts])
Other Extensible Systems View Patterns [Peyton-Jones et al]: app patterns
Views [Wadler]: define-matcher and app Active Patterns [Syme et al]: Multiple uses of define-matcher, app, and ?
Pattern matching is great Extensible pattern matching is even better
An expressive and extensible language can give us both
Thanks! Available at racket-lang.org