Yes, that's the whole point: your matching statement is compiled into some equivalent code, harder to read for you but intelligible to the VM. Consider this sample:
match foo with
| { tag='Alpha', x, "some_string", y } -> f1(x+y)
| { a, ... } if a>10 -> f2(a)
end
The first case matches if foo is:
- a table;
- with a tag field containing 'Alpha';
- and exactly 3 array-part children;
- and whose 2nd child must be equal to the constant string "some_string".
If the pattern matches, x will be set to the value of the 1st child, and y to the value of the 3rd one. This will allow to use these children's values in the corresponding block "f1(x+y)". All of this complex test is expressed by the pattern "{ tag = 'Alpha', x, 'some_string', y }".
The second case checks that foo is a table, has at least one array-part element, calls the first one 'a', and checks that a>10.
The first pattern to match is selected, and the corresponding block of code is executed. The code above is therefore equivalent to this:
if type(foo) == "table" and #foo==3 and foo.tag=='Alpha' and foo[2] == "some_string" then
local x, y = foo[1], foo[3]
f1 (x+y)
elseif type(foo)=="table" and #foo>=1 then
local a=foo[1]
if a>10 then
f2(a)
end
end
(In reality, it's compiled into something equivalent, slightly faster and much less readable, but you're but supposed to look at compiled code. There's a "-a" option in the metalua compiler that prints the compiled code as an AST, if you really want to know).
If you compare the match...with version and the compiled one, I believe the interest of the first syntax is quite obvious. And that's with pretty simple pattern, and only two cases. Imagine how readable a bigger program such a this one would be, without pattern matching:
http://repo.or.cz/w/metalua.git?a=blob;f=src/lib/walk.mlua ("`Foo{ bar }" is syntax sugar for "{ tag='Foo', bar }". It's extremely handy to represent deeply nested trees, such as routinely manipulated in XML. And it works for values as well as for patterns).