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