]> git.lizzy.rs Git - metalua.git/blob - doc/manual/sample-match.tex
fix CRLF
[metalua.git] / doc / manual / sample-match.tex
1 \subsection{Structural pattern matching}
2
3 FIXME: refer to the official match extension instead of re-explaining
4 what pattern matching is about.
5
6 \subsubsection{Basic principles}
7 In many languages, including Lua, ``pattern matching'' generally
8 refers to the ability to:
9 \begin{itemize}
10 \item Analyse the general shape of a string;
11 \item capture specified parts of it into temporary variables
12 \item do some computation when the string matches a certain pattern,
13   generally using the temporary captured variables.
14 \end{itemize}
15
16 In languages derived from ML\footnote{for instance OCaml, SML, Haskell
17   or Erlang.}, pattern matching can be done on arbitrary data, not
18 only strings. One can write patterns which describe the shape of a
19 data structure, bind some interesting sub-parts of it to variables,
20 and execute some statements associated with a given pattern whenever
21 the data matches.
22
23 This sample aims to implement this capability into metalua. It will
24 discuss:
25 \begin{itemize}
26 \item How to describe data patterns (it turns out that we'll hijack
27   metalua's expression parser, which is a great time-saving trick when
28   it can be pulled).
29 \item How to compile them into equivalent code.
30 \item How to wrap all this up into a working compiled statement
31 \item What improvements can be done to the proposed design.
32 \end{itemize}
33
34 \subsubsection{Patterns}
35 A match statement consists of a tested term, and a series of (pattern,
36 block) pairs. At execution, the first pair whose pattern accurately
37 describes the tested term is selected, and its corresponding block is
38 evaluated. Other blocks are ignored. 
39
40 We will keep the implementation of patterns as simple as possible. To
41 do that, we will put a first constraint: the AST of a pattern must be
42 a legal expression AST. This way, we save most of the syntax handling
43 trouble. More specifically:
44
45 \begin{itemize}
46 \item numbers are valid patterns, which only match identical numbers;
47 \item strings are valid patterns, which only match identical strings;
48 \item tables are valid patterns if all of their keys are integers or
49   strings, and all of their values are valid patterns. A table pattern
50   matches a tested term if:
51   \begin{itemize}
52   \item the tested term is a table;
53   \item every key that appears in the pattern also appears in the
54     tested term;
55   \item for every key, the value associated to this key in the tested
56     term is matched by the sub-pattern associated to this key in the
57     pattern;
58   \end{itemize}
59 \item variables are valid patterns, and match everything. Moreover,
60   the term matched by the variable captures it, i.e. in the
61   corresponding block, that variable is set to the
62   matched term.
63 \end{itemize}
64
65 Notice that since \verb|tag| is a regular field in metalua (albeit
66 with an optional dedicated syntax), it doesn't need a special case in
67 our pattern definition.
68
69 \paragraph{Example} Let's consider implementing an evaluator for
70 Metalua expressions. We will restrict ourselves to binary operators,
71 variables and numbers; we will also consider that we have a
72 \verb|values| table mapping variable names to their value, and
73 \verb|binopfuncs| which associate an operator name with the corresponding
74 function. The evaluator would be written:
75
76 \begin{Verbatim}[fontsize=\scriptsize]
77
78 function eval(t)
79    match t with
80    | `Op{ op, a, b } -> return binopfuncs[op](eval(a), eval(b))
81    | `Number{ n }    -> return n
82    | `Variable{ v }  -> return values[v]
83    end
84 end
85 \end{Verbatim}
86
87 \subsubsection{Pattern compilation}
88
89 A pattern in a case will translate into:
90 \begin{itemize}
91 \item tests: testing that the type of the tested case is the same as
92   the pattern's type for numbers, strings and tables;
93 \item local declarations: a variable must be bound to the
94   tested term's value;
95 \item nested tests for every pattern key/value pair, when the pattern
96   is a table. Moreover, since there might be multiple tests to run
97   against the tested term's field, it should be put in a temporary
98   variable.
99 \end{itemize}
100
101 For instance, consider the following pattern:
102
103 \begin{Verbatim}[fontsize=\scriptsize]
104
105 { tag = "Foo", 10, { 20 }, { x = a }, b }
106 \end{Verbatim}
107
108 It corresponds to the series of tests and assignments on the left:
109
110 \begin{minipage}{6cm}
111 \begin{Verbatim}[fontsize=\scriptsize]
112
113 let v1 = <tested_term>
114 type(v1) == "table"
115 let v2 = v1.tag
116 v2 ~= nil
117 type(v2) == "string"
118 v2 == "Foo"
119 let v2 = v1[1]
120 v2 ~= nil
121 type(v2) == "number"
122 v2 == 10
123 let v2 = v1[2]
124 v2 ~= nil
125 type(v2) == "table"
126 let v3 = v2[1]
127 v3 ~= nil
128 type(v3) == "number"
129 v3 == 20
130 let v2 = v1[3]
131 v2 ~= nil
132 type(v2) == "table"
133 let v3 = v2.x
134 v3 ~= nil
135 local a = v3
136 let v2 = v1[4]
137 v2 ~= nil
138 local b = v2
139
140
141 \end{Verbatim}
142 \end{minipage}
143 \begin{minipage}{6cm}
144 \begin{Verbatim}[fontsize=\scriptsize]
145
146 let v1 = tested_term
147 if type(v1) == "table" then
148  let v2 = v1.tag
149  if v2 ~= nil then
150   if type(v2) == "string" then
151    if v2 == "Foo" then
152     let v2 = v1[1]
153     if v2 ~= nil then
154      if type(v2) == "number" then
155       if v2 == 10 then
156        let v2 = v1[2]
157        if v2 ~= nil then
158         if type(v2) == "table" then
159          let v3 = v2[1]
160          if v3 ~= nil then
161           if type(v3) == "number" then
162            if v3 == 20 then
163             let v2 = v1[3]
164             if v2 ~= nil then
165              if type(v2) == "table" then
166               let v3 = v2.x
167               if v3 ~= nil then
168                local a = v3
169                let v2 = v1[4]
170                if v2 ~= nil then
171                 local b = v2
172                 <inner_term>
173 end ... end -- (16 times)
174 \end{Verbatim}
175 \end{minipage}
176 ~\\~\\
177
178 Notice that the relative order of tests and assignments is meaningful:
179 we cannot put all assignments on one side, and all tests on an
180 other, e.g. \verb|v2 = v1.tag| on line 3 doesn't make sense if
181 \verb|type(v1) == table| on line 2 fails.
182
183 We will compile patterns in several steps: first, accumulate all the
184 tests and assignments in order; then, we will collapse them in a
185 single big nesting of ``if'' statements. At first, we won't try
186 to optimize the form of the final term. The list above left would be
187 collapsed into the single compound statement above on the right.
188
189 \paragraph{Accumulating constraints and tests}
190 This is done by a \verb|parse_pattern()| function, which does just what
191 is described in the bullet list above:
192
193 \begin{Verbatim}[fontsize=\scriptsize]
194
195       -------------------------------------------------------------------
196       -- Turn a pattern into a list of conditions and assignations,
197       -- stored into [acc]. [n] is the depth of the subpattern into the
198       -- toplevel pattern; [tested_term] is the AST of the term to be 
199       -- tested; [pattern] is the AST of a pattern, or a subtree of that
200       -- pattern when [n>0].
201       -------------------------------------------------------------------
202       local function parse_pattern (n, pattern)
203          local v = var(n)
204          if "Number" == pattern.tag or "String" == pattern.tag then
205             accumulate (+{ -{v} == -{pattern} })
206          elseif "Id" == pattern.tag then
207             accumulate (+{stat: local -{pattern} = -{v} })
208          elseif "Table" == pattern.tag then
209             accumulate (+{ type( -{v} ) == "table" } )
210             local idx = 1
211             for _, x in ipairs (pattern) do
212                local w = var(n+1)
213                local key, sub_pattern
214                if x.tag=="Key" 
215                then key = x[1];           sub_pattern = x[2]
216                else key = `Number{ idx }; sub_pattern = x; idx=idx+1 end
217                accumulate (+{stat: (-{w}) = -{v} [-{key}] })
218                accumulate (+{ -{w} ~= nil })
219                parse_pattern (n+1, sub_pattern)
220             end
221          else error "Invalid pattern type" end
222       end
223       -------------------------------------------------------------------
224 \end{Verbatim}
225
226 This function relies on the following helper functions:
227 \begin{itemize}
228 \item {\tt var($n$)} generates the variable name ``\verb|v|$n$'', which
229   is used to store the tested term at depth level $n$. Indeed,
230   sub-patterns in table fields are matched against sub-terms of the
231   tested term. It also remembers of the biggest $n$  it ever received, 
232   and stores it into \verb|max_n| (this will be used to know which
233   local vars have to be generated, see below);
234 \item {\tt accumulate()} just stores an additional code snippet in a
235   dedicated list;
236 \end{itemize}
237
238 In the quotes, you might notice the parentheses around the variable in
239 ``\verb|(-{w}) = -{v} [-{key}]|'': they're here to let the compiler
240 know that what's in \verb|-{...}| is an expression, not a
241 statement. Without them, it would expect {\tt w} to be the AST of a
242 statement (since we're in a statement context at this point), then
243 choke on the unexpected ``='' symbol. This is a common idiom, which
244 you should think about everytime you generate an assignment to an
245 anti-quoted identifier.
246
247 \paragraph{Collapsing the accumulated quotes}
248 As written above, our collapsing function will be kept as simple
249 as possible, and will not try to minimize the amount of generated
250 code. It takes as parameters {\tt n}, the index of the quote currently
251 collapsed in the accumulator, and {\tt inner\_term} the statement
252 block to put inside the innermost part of the test. It calls itself
253 recursively, so that the collapsed term is built inside out (generally
254 speaking, working with trees, including AST, involves a lot of
255 recursive functions). \verb|acc| is the list filled by the
256 \verb|accumulate()| function:
257
258 \begin{Verbatim}[fontsize=\scriptsize]
259
260       -------------------------------------------------------------------
261       -- Turn a list of tests and assignations into [acc] into a
262       -- single term of nested conditionals and assignments.
263       -- [inner_term] is the AST of a term to be put into the innermost
264       -- conditionnal, after all assignments. [n] is the index in [acc]
265       -- of the term currently parsed.
266       -- 
267       -- This is a recursive function, which builds the inner part of
268       -- the statement first, then surrounds it with nested 
269       -- [if ... then ... end], [local ... = ...] and [let ... = ...]
270       -- statements.
271       -------------------------------------------------------------------
272       local function collapse (n, inner_term)
273          assert (not inner_term.tag, "collapse inner term must be a block")
274          if n > #acc then return inner_term end
275          local it = acc[n]
276          local inside = collapse (n+1, inner_term)
277          assert (not inside.tag, "collapse must produce a block")
278          if "Op" == it.tag then 
279             -- [it] is a test, put it in an [if ... then .. end] statement
280             return +{block: if -{it} then -{inside} end }
281          else 
282             -- [it] is a statement, just add it at the result's  beginning.
283             assert ("Let" == it.tag or "Local" == it.tag)
284             return { it, unpack (inside) }
285          end
286       end
287 \end{Verbatim}
288
289 To fully understand this function, one must remember that test
290 operations are translated into {\tt`Op\{ <opname>, <arg1>, <arg2>\}}
291 AST. That's why we didn't have to put an explicit reminder in the
292 accumulator, remembering whether a quote was a test or a statement:
293 we'll just check for \verb|`Op|'s presence.
294
295 \subsubsection{Match statement compilation}
296 We already know how to translate a single pattern into a Lua test
297 statement. This statement will execute a given block, with all pattern
298 variables bound appropriately, if and only if the tested term matches
299 the pattern.
300
301 To build a complete match statement, we need to test all patterns in
302 sequence. When one of them succeeds, we must skip all the following
303 cases. We could do that with some complex ``\verb|else|'' parts in the
304 tests, but there is a simpler way to jump out of some nested blocks:
305 the ``\verb|break|'' statement. Therefore, we will enclose the cases
306 into a loop that executes exactly once, so that a ``\verb|break|''
307 will jump just after the last case. Then, we will add a
308 ``\verb|break|'' at the end of every statement that doesn't already
309 finish with a ``\verb|return|'', so that other cases are skipped upon
310 successful matching. To sum up, we will translate this:
311
312 \begin{Verbatim}[fontsize=\scriptsize]
313
314 match <foo> with
315 | <pattern_1> -> <x1>
316 | <pattern_2> -> <x2>
317   ...
318 | <pattern_n> -> <xn>
319 end
320 \end{Verbatim}
321
322 \noindent into this:
323
324 \begin{Verbatim}[fontsize=\scriptsize]
325
326 repeat
327   local v1, v2, ... vx -- variables used to store subpatterns
328   let v1 = <tested_term>
329   if <compilation of pattern_1> ... then x1; break end
330   if <compilation of pattern_2> ... then x2; break end
331   ...
332   if <compilation of pattern_n> ... then xn; break end
333 until true
334 \end{Verbatim}
335
336 First, we add final \verb|break| statements where required, and we
337 compile all (pattern, block) pairs:
338
339 \begin{Verbatim}[fontsize=\scriptsize]
340
341       -------------------------------------------------------------------
342       -- parse all [pattern ==> block] pairs. Result goes in [body].
343       -------------------------------------------------------------------
344       local body = { }
345       for _, case in ipairs (cases) do
346          acc = { } -- reset the accumulator
347          parse_pattern (1, case[1], var(1)) -- fill [acc] with conds and lets
348          local last_stat = case[2][#case[2]]
349          if last_stat and last_stat.tag ~= "Break" and 
350             last_stat.tag ~= "Return" then
351             table.insert (case[2], `Break) -- to skip other cases on success
352          end
353          local compiled_case = collapse (1, case[2])
354          for _, x in ipairs (compiled_case) do table.insert (body, x) end
355       end
356 \end{Verbatim}
357
358 \noindent Then, we can just splice it into the appropriate quote:
359
360 \begin{Verbatim}[fontsize=\scriptsize]
361
362       -------------------------------------------------------------------
363       local local_vars = { }
364       for i = 1, max_n do table.insert (local_vars, var(i))  end
365       
366       -------------------------------------------------------------------
367       -- cases are put inside a [repeat until true], so that the [break]
368       -- inserted after the value will jump after the last case on success.
369       -------------------------------------------------------------------
370       local result = +{ stat: 
371          repeat
372             -{ `Local{ local_vars, { } } }
373             (-{var(1)}) = -{tested_term}
374             -{ body }
375          until true }
376       return result
377       -------------------------------------------------------------------
378 \end{Verbatim}
379
380 There is one point to notice in this quote: \verb|body| is used where
381 a statement is expected, although it contains a {\em list} if
382 statements rather than a single statement. Metalua is designed to
383 accept this, i.e. if {\tt a, b, c, d} are statements, AST {\tt
384 `Do\{  a, b, c, d \}} and {\tt`Do\{ a, \{ b, c \}, d\} } are
385 equivalent. This feature partially replaces Lisp's \verb|@(...)|
386 operator.
387
388 \subsubsection{Syntax extension}
389 To use this, we provide a syntax inspired by OCaml\footnote{It is
390   actually the same syntax as OCaml's, except that we introduced an
391   explicit {\tt end} terminator, to stay homogeneous with Lua.}: 
392
393 \begin{Verbatim}[fontsize=\scriptsize]
394
395 match <foo> with
396   <pattern> -> block
397 | <pattern> -> block
398   ...
399 | <pattern> -> block
400 end
401 \end{Verbatim}
402
403 For this, we need to declare new keywords \verb|match|,
404 \verb|with| and \verb|->|. Then, we build the (pattern, block) parser
405 with \verb|gg.sequence{ }|, and read a list of them, separated with
406 ``\verb+|+'', thanks to \verb|gg.list{ }|. Moreover, we accept an
407 optional ``\verb+|+'' before the first case, so that all cases line up
408 nicely:
409
410 \begin{Verbatim}[fontsize=\scriptsize]
411
412 ----------------------------------------------------------------------
413 mlp.lexer:add{ "match", "with", "->" }
414
415 mlp.stat:add{ "match", mlp.expr, "with", gg.optkeyword "|",
416               gg.list{ gg.sequence{ mlp.expr, "->", mlp.block },
417                        separators  = "|",
418                        terminators = "end" },
419               "end",
420               builder = |x| match_parser (x[1], x[3]) }
421 ----------------------------------------------------------------------
422 \end{Verbatim}
423
424 \noindent Now, if you try this\ldots\ it won't work! Indeed, Metalua
425 needs to know what keywords might terminate a block of statements. In
426 this case, it doesn't know that ``\verb+|+'' can terminate a block. We
427 need therefore to add the following statement:
428
429 \begin{Verbatim}[fontsize=\scriptsize]
430
431 mlp.block.terminators:add "|"
432 \end{Verbatim}
433
434 \noindent Finally that's it, we have implemented a working pattern
435 matching system in 75 lines of code!
436
437 \subsubsection{Possible improvements}
438 Here are a couple of suggestions to further improve the pattern
439 matching system presented above. Some of these proposals can be
440 implemented very quickly, some others more complex; all of them
441 present some practical interest.
442
443 The code of the basic version, as presented here, is available at
444 \url{http://metalua.luaforge.net/FIXME}.
445
446 \paragraph{Booleans} Boolean constants aren't handled in the system
447 above, neither as table keys nor as patterns. They're easy to add, and
448 doing it will help you get gently into the code.
449
450 \paragraph{Gotos considered beneficial} Gotos might be harmful in
451 hand-written programs, but they're a bliss for machine-generated
452 code. They would slightly simplify the code of pattern matching as
453 presented above; but for many extension proposals listed below, they
454 will make reasonnably easy some things which would otherwise be
455 awfully contrived. Exercice: simplify the implementation above as much
456 as possible by using gotos.
457
458 Labels and gotos in metalua ASTs are represented as {\tt`Label\{ id
459   \}} and {\tt`Goto\{ id \}} respectively, with {\tt id} an
460 identifier, typically generated by {\tt mlp.gensym()}. It is always
461 safe to jump out of a block; jumping into a block is not guaranteed
462 against weird interactions with local variables and upvalues.
463
464 \paragraph{{\tt collapse()} optimization} Instead of nesting if
465 statements systematically, two nested {\tt if}s without {\tt else}
466 branches can be simplified in a single branch with an {\tt and}
467 operator. Not sure it would change the bytecode's efficiency, but
468 that's a good exercice of AST manipulation.
469
470 \paragraph{Superfluous assignments} When parsing a table entry, we
471 assign it to a variable, then recursively call {\tt parse\_pattern()}
472 on it; in the frequent case where the entry was simply a variable, it
473 re-assigns it again. This could be optimized away.
474
475 \paragraph{Checking table arity} In many cases, it is practical to
476 check the number of elements in the array-part of the table. Here is a
477 simple modification proposal: by default, a table pattern matches a
478 table term only if they have the same number of array-part
479 elements. However, if the last element of the pattern is {\tt`Dots}
480 (a.k.a. {\tt+\{...\}}), then the term simply has to have 
481 {\it at least} as many array-part elements as the pattern.
482
483 \paragraph{Adding guards}
484 It is sometimes desirable to add arbitrary conditions for a pattern to
485 match, conditions which might no be expressed by a pattern. OCaml
486 allows to add them with a ``\verb|when|'' keyword:
487 \begin{Verbatim}[fontsize=\scriptsize]
488
489 match n with
490 | 0               -> print "zero"
491 | n when n%2 == 0 -> print "even number"
492 | _               -> print "odd number"
493 end
494 \end{Verbatim}
495 I'd advise you to prefer {\tt if} as a dedicated keyword, rather than
496 {\tt when}: it's unambiguous in this context, and saves a keyword
497 reservation. 
498
499 \paragraph{More bindings}
500 The way pattern matching is currently implemented, one can either bind
501 a subterm to a variable, or check its structure against a sub-pattern,
502 not both simultaneously. OCaml provides an ``\verb|as|'' operator,
503 which allows to do both (Haskell calls it ``\verb|@|''). For instance,
504 in the following example, any ADT whose tag is \verb|"RepeatMe"| will
505 be replaced by two occurrences of itself, while others will remain
506 unchanged:
507 \begin{Verbatim}[fontsize=\scriptsize]
508
509 match something with
510 | `RepeatMe{ ... } as r -> { r, r }
511 | x -> x
512 end
513 \end{Verbatim}
514 ``\verb|as|'' will have to be declared as an infix operator, whose
515 meaning will remain undefined in expressions which are not patterns.
516
517 As an alternative, you can reuse an existing infix operator, thus
518 avoiding to mess the expression parser. For instance, use {\tt *}
519 instead of {\tt as}. You can go further, and implement {\tt +} as an
520 ``or'' operator ({\tt pattern1 + pattern2} would match if either
521 of the patterns matches), although this would significantly complicate
522 the implementation of {\tt parse\_pattern()}. 
523
524 The {\tt+} operator might prove tricky to implement, if you don't
525 convert your code generator to gotos and labels first.
526
527 \paragraph{Linear bindings}
528 We should check, when compiling a pattern, that it is left-linear,
529 i.e. that variables don't appear more than once in the pattern. People
530 might be tempted to write things like this to check whether a tree is
531 symmetric:
532 \begin{Verbatim}[fontsize=\scriptsize]
533
534 match t with
535 | `Tree{ x, x } -> print "Symmetric!"
536 | `Tree{ x, y } -> print "Not symmetric"
537 | `Leaf{ _ }    -> print "Symmetric!"
538 end
539 \end{Verbatim}
540 However, this would work in Prolog but not with our pattern matching,
541 as two occurences of the same variable in the pattern don't cause an
542 equality test to be added. We should detect such non-linear variables,
543 and implement a suitable reaction:
544 \begin{itemize}
545 \item throw an error, or at least a warning;
546 \item or add an equality test between the terms matched by the
547   non-linear variable;
548 \item or offer a syntax extension that lets the user provide his own
549   equality predicate.
550 \end{itemize}
551
552 Notice that the latter choice would drive us towards a Prolog
553 unification algorithm, which opens interesting opportunities.
554
555 You might offer an exception for variable ``{\tt\_}'', which is often
556 intended as a dummy, unused variable. Non-linear occurences of it
557 should probably be silently accepted, without even performing the
558 corresponding binding. 
559
560 \paragraph{Generalized assignments}
561 Yet another OCaml-inspired feature: assignments such as
562 ``\verb|foo = bar|'', is almost a special
563 case of pattern matching with only one case: the left-hand side is
564 the pattern, and the right-hand side is the ``raw'' ``\verb|foo=bar|''
565 assignment. Seen this way, it allows to write things such as
566 ``\verb|`If{ cond, block } = some_ast }|'' to assign \verb|cond| and
567 \verb|block| to the subparts of \verb|some_ast| (if we know that
568 \verb|some_ast| is the AST of an \verb|if| statement). 
569
570 If you go this way, however, make sure that the code generated for
571 simple {\tt let}s is as efficient as before! Moreover, there is an (easy) 
572 scoping issue: the variables assigned belong to the scope of the
573 surrounding block.
574
575 \paragraph{Pattern matchings as expressions}
576 Pattern matching are currently statements, and take statements as
577 right-hand sides of cases. We could allow pattern matchings where
578 expressions are expected: these would take expressions instead of
579 statements as right-hand sides. Two ways to implement this: the dirty
580 one (hack with functions to change match statements into expressions),
581 and the clean one (refactoring existing code, so that it is agnostic
582 about its right-hand side type, and provide two specialized
583 versions of it for statements and expressions).
584
585 \paragraph{Bootstrap it}
586 That's something language designers love to do, for largely mystic
587 reasons: writing a language's compiler in the language itself. Here,
588 the idea is to re-implement the pattern matching extension by using
589 pattern matching, and compile it with the older version. Comparing the
590 firsrt and second versions of the code will give you an idea of how
591 much code clarification is brought to you by the pattern matching
592 extension.
593
594 \paragraph{Pattern conjunction} Another feature to take from OCaml is
595 multiple patterns for a single block. Instead of associating one
596 block with one pattern, cases associate a block with a (non-empty)
597 list of patterns. All of these patterns have to bond the same
598 variables, except for {\tt\_}. The first pattern in the list to match
599 the tested term does the binding. Patterns are separated by
600 ``\verb+|+''. Example:
601 \begin{Verbatim}[fontsize=\scriptsize]
602
603 match x with
604 | 1 | 2 | 3 -> print(x)
605 | n -> print "more than 3"
606 end
607 \end{Verbatim}
608 (Hint: put the block in a local function. $2^{\mathrm{nd}}$ hint: sort
609 bound variables, e.g. by lexicographic order. Or much simpler and
610 more effective: convert your code generator to gotos+labels first).
611
612 \paragraph{XML munching} Ever tried to transform some XML document through
613 XSLT? Did you feel that this was even more kludgy than XML itself? Here
614 is a challenging proposal:
615 \begin{itemize}
616 \item Realize, if you didn't already, that Metalua's ADT are
617   isomorphic to XML, if you identify string-keys in tables with
618   attributes, and limit there content to strings and number. For
619   instance, ``{\tt <foo bar=3><baz/>eek</foo>}'' easily maps to ``{\tt
620     `foo\{ bar=3, `baz, "eek" \}}'';
621 \item compare what ML-style pattern matching does with what XSLT
622   does (and with what you'd like it to do);
623 \item design, implement, publish. You might want to google
624   ``CDuce''\footnote{\url{http://www.cduce.org}} for neat ideas.
625 \end{itemize}
626
627 If you do this, I'd be really interested to put back your contribution
628 in the next version of Metalua!
629
630 \subsubsection{Correction}
631 Most of the improvements proposed here are actually implemented in the
632 {\tt match} library provided with metalua. Check its (commented)
633 sources!