Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Extensible Pattern Matching
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Sam Tobin-Hochstadt
September 26, 2011
Programming
79
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Extensible Pattern Matching
A talk at IFL 2010 in Alphen an der Rijn, the Netherlands
Sam Tobin-Hochstadt
September 26, 2011
More Decks by Sam Tobin-Hochstadt
See All by Sam Tobin-Hochstadt
Evolving Existing Languages: The Typed Racket Experience
samth
1
140
Logical Types for Untyped Languages
samth
1
280
Semantic Solutions to Program Analysis Problems
samth
1
89
Other Decks in Programming
See All in Programming
月間100万人のサービス刷新で、 技術選定をHonoに振り切った話
yutobara
8
6.6k
個人開発者よ、Honoを使え(おじさんver)
tanahiro2010
2
260
golang-bob.pdf
iwatsukayura
0
130
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
210
コーディング自動化の次へ。人の介入をゼロにするファクトリーとサポートAIによる実践
timakin
4
3.5k
contenteditable と日本語入力に向き合う
colorful12
0
200
コードで差別化できない時代の ソフトウェアエンジニアリング / Software Engineering in an Era Where Code Doesn’t Differentiate
kishida
2
180
TechTown - Creating Composable Callables in Contemporary C++
rollbear
0
130
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Rails World 2026, Austin, Texas
marcoroth
0
220
sbt 2.0: takeoff
eed3si9n
0
160
FactoryBotをやめればRSpecは速くなるのか?
yuta_onishi_97
0
270
GemmaをJevのように使ってみる / Use Gemma like Jev
kishida
5
790
Featured
See All Featured
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
780
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
3
3.9k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.9k
WCS-LA-2024
lcolladotor
0
890
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
480
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
3.4k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
320
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
6
1.2k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
2
2k
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
540
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