Enhanced type guard syntax]
Richard A. O'Keefe
ok@REDACTED
Mon Sep 22 07:18:08 CEST 2003
Joe Armstrong <joe@REDACTED> wrote:
It depends upon the set of patterns.
If we have a polymorphic function like this:
foo(A/integer, B/...) ->
foo(A/integer, B/...)
foo(true, ...) ->
foo(bar, ...) ->
Then any half decent pattern matching compiler could generate
pattern matching code like this....
switchOnTag Arg0 {
case integer: ...
case atom: ...
}
But any half-way decent pattern-matching compiler *should* be generating
pattern-matching code like that anyway for
foo(A, B) when integer(A), ... ->
foo(A, B) when integer(A), ... ->
foo(true, ...) when ... ->
foo(bar, ...) when ... ->
Someone under Udi Shapiro's supervision wrote a compiler for FCP that did
that years back. I *think* the name was Shmuel Kliger, but I am probably
wrong, and I *think* the year I read it was 1990, but ditto. And of course
I may be misremembering it.
Basic ideas:
(1) Compile pattern matches and guards together
(2) Do guard tests when the data are known to be available
(for Prolog, a variable may be tested after the _last_ mention of
it in a pattern; for Erlang it may be tested after the _first_
mention). So integer(A) may be scheduled at any point after the
first mention of A in the head, A > B may be done at any point
after A and B both become available, and so on.
(3) Introduce the generalisations of a test:
integer(A) => atomic(A) & number(A) & integer(A)
A = 27 => integer(A).... & A = 27
A = true => atomic(A) & atom(A) & A = true
hd(X) > 2 => is_pair(X) & [H|_] = X & atomic(H) & number(H) & H > 2
...
(4) If a test is implied by tests you have already done, emit no code
for it.
(5) When building the tree, at each node pick the most useful test.
I've forgotten the exact rule, but it's something about filtering
out the largest number of clauses, and something about expense.
My general feeling is that "the more you tell the compiler about the
program the better"
As a programmer you shouldn't think about how to write patterns, or
guards for efficiency - let the pattern matching compiler do that.
Right. If Erlang _were_ to be extended with IBM-PROLOG-like type tests
in patterns (*YUCK*) then it should make absolutely no difference to the
compiler whether you do it that way or not.
More information about the erlang-questions
mailing list