[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: [ANN] tamale-1.2 - Erlang-style pattern matching library
- From: Scott Vokes <vokes.s@...>
- Date: Sat, 25 Sep 2010 19:05:54 -0400
> -- test composed patterns (alternation)
> local m2 = M { {1, true}, {2, true} }
> local m = M{{ {m2, m2}, 3 }}
> print(m {1, 2}) --> 3, table
> print(m {1, 3}) --> false, "Match failed"
For matching { [1 or 2], [1 or 2] }...There could probably be a
utility function added to tamale, "any(array_of_values)", that tamale
would recognize and turn into multiple rows. (There could be an ugly
combinatorial explosion though.)
> -- test false/nil result (ok?)
> print(M {{1}} (1)) --> nil, table
This is nil because there's no result in the rule. Should I add an
assert for this? It'd almost certainly be an error, like a typo in a
variable name.
> -- test match function values
> --FAILS: print(M {{math.sqrt, true}} (math.sqrt) )
> local function issqrt(o) return o == math.sqrt end -- alternative
> print(M {{issqrt, true}} (math.sqrt) ) --> true, table
Function literals aren't tested by equality, they're considered
predicates to test on the value. (sort of like when=guard_function,
but there, it tests against all captures). the issqrt works, though.
It's idiomatic of declarative programming to have the rules mainly
work on things that can be expressed literally, so that they have a
relatively independent logical meaning. (In Prolog, it can potentially
backtrack and try all rules, not just the first match. It has
backtracking with full extent, unlike LPEG.)
> -- test match approximate
> local function approx(a) return function(b) return math.abs(a-b) < 1 end end
> print(M {{tuple(approx(5), approx(10)), true}} (tuple(5.1, 10.1))) -->
> true, table
> print(M {{tuple(approx(5), approx(10)), true}} (tuple(5.1, 11.1))) -->
> false, ...
I don't think you need tuple for this one - I see why you're using
it, but it makes the intent less clear.
approx_m = M {
{ {approx(5), approx(10)}, true }
}
print(approx_m({5.1, 10.1}))
print(approx_m({5.1, 11.1}))
>> I also added a special variable, V"...", which sets the partial flag
>> and captures all subsequent array-portion values. (e.g. { "foo, V"..." }).
> Maybe decompose V"..." into Star(V"_"). This generalization allows
> {Star(isnumber)} to match an array of numbers.
I'm not sure what you mean here. V"_" means "don't capture or test
against this value", sort of like . in regular expressions. (It's a
Prolog-ism.)
Thanks,
Scott