source: project/wiki/eggref/5/match-generics @ 40129

Last change on this file since 40129 was 40129, checked in by Idiomdrottning, 2 months ago
File size: 2.0 KB
Line 
1
2== match-generics
3[[toc:]]
4
5Here are some flexible and fast generics.
6
7They don't need to have the same number of arguments or use the same
8names:
9
10 (define-generic (frotz a b c) (list b a c))
11 (define-generic (frotz x y) (+ x y))
12 (list (frotz 1 2 3) (frotz 4 5))
13
14⇒ ((2 1 3) 9)
15
16They can even destructure their arguments:
17
18 (define-generic (my-map proc (x . xs))
19   (cons (proc x) (my-map proc xs)))
20 
21 (define-generic (my-map proc ()) '())
22 
23 (my-map add1 '(1 2 3))
24
25⇒ (2 3 4)
26
27To use predicates, use the form {{(? pred var)}}, like this:
28
29 (define-generic (plus (? list? a) (? list? b)) (append a b))
30 
31 (define-generic (plus (? string? a) (? string? b)) (string-append a b))
32 
33 (define-generic (plus (? number? a) (? number? b)) (+ a b))
34 
35 (list
36  (plus "13" "14")
37  (plus 7 22)
38  (plus 13 19)
39  (plus '(a b c) '(1 2 3)))
40
41⇒ ("1314" 29 32 (a b c 1 2 3))
42
43You need to define them in order from least specific to most specific,
44i.e. define the most specifics last and the fallbacks first.
45
46You can even use nested defines! But if you do, each need to use the same
47inner forms. Only the outer-most form is generic.
48
49 (define-generic ((frobnicate a) b z) (list a b z))
50 (define-generic ((frobnicate a) b) (string-append a b))
51 
52 (let ((hoho (frobnicate "hoho")))
53   (list (hoho 1 2)
54         (hoho " and such")))
55
56⇒ (("hoho" 1 2) "hoho and such")
57
58
59=== Implementation
60By now, maybe some of the long-time readers in the audience has
61guessed what is going on.
62
63Each generic is defined using a clause from [[http://wiki.call-cc.org/eggref/5/matchable|matchable]]!
64
65The implementation using some miscellaneous [[https://idiomdrottning.org/brev-separate|brev-separate]] stuff is just
 '''six lines!'''
66
67 (define-for-syntax gentable (call-table*))
68 (define-ir-syntax*
69   define-generic
70   ((define-generic (name . pattern) . body)
71    (cons 'match-define
72          (gentable (strip-syntax name) (cons (cons name pattern) body)))))
73
74For source code,
75
76 git clone https://idiomdrottning.org/match-generics
77
Note: See TracBrowser for help on using the repository browser.