[erlang-questions] eep: multiple patterns
Richard A. O'Keefe
ok@REDACTED
Wed Jun 4 07:56:21 CEST 2008
On 30 May 2008, at 8:25 pm, Ulf Wiger (TN/EAB) wrote:
> I thought I'd try to convey a feeling for just
> how hairy the receive clauses can get. I think
> this is the worst one.
>
> It would of course be a candidate for the sort of
> refactoring you've shown on the other examples.
> It is perhaps a matter of taste, whether or not
> one prefers to extract as much code as possible out
> of the receive statement (which in this case is 650
> lines of code + comments). Most of the snipped
> action bodies are only a handful of lines of code.
> A few are considerably longer (up to 30 LOC).
At 650 lines, I suggest that 'a candidate for .. refactoring'
is putting it mildly. Without knowing which actions are
supposed to be the same, I can't comment on _what_ refactoring
might be appropriate.
Instead I'll comment on something else.
I appreciate why things like
{distr_msg, DistrMsgId, ?HCMSG_REMOVE_HC} ->
exist. I appreciate how the use of suitable names here can
make it easier to figure out the intention of the code.
However, as soon as you have things like
{a, B, ?C} ->
; {a, B, ?D} ->
; ...
you discover that you cannot tell whether these patterns
overlap without manually expanding the macros.
In an earlier message in this thread I suggested that a tool
that warns you of 'critical' pairs in receive, case, or
function heads would be useful. For getting code of this
level of complexity right, I must raise that to EXTREMELY
useful.
Something I should point out about abstract patterns is that
one of the jobs they were designed to do was to describe
message protocols. Of course you can also see them as a
strict generalisation of the new type notation; it's a pity
that abstract patterns weren't implemented first. One of
the things that struck me when trying to read other people's
Erlang was that I could tell without enormous trouble (because
I hadn't seen the system Ulf Wiger was talking about!) what
messages processes DID receive, but it was very much harder
to tell what messages they SHOULD receive.
There were two ways I thought of using abstract patterns
for this.
(1) As executable message filters. A process would be able
to install an abstract pattern as its filter, and any message
sent to it that _didn't_ match the filter would automatically
be discarded at once.
(2) As possibly-executable annotations.
#protocol() receive
Pattern1 when Guard1 -> Action1
; ...
end
would allow a static checking tool to report Pattern/Guard
cases that _didn't_ form a critical pair with #protocol(),
that is, things you were matching that according to your
claimed protocol wouldn't happen anyway. It would also
allow such a tool to warn you if there were messages in the
protocol that you *didn't* match in the body. As we've seen
in explanations of selective receive, that doesn't mean there
is a bug. My ideas were pretty vague; I was thinking in terms
of flattening stuff and then using clause subsumption, but it
is basically the same problem that Mercury faces when deciding
whether an 'or' is really a 'switch'. As an executable check,
before passing any message on to the receive body proper, it
would give it to #protocol(), and you'd get an exception if
the match failed. Again, the idea is an *optional* debugging
tool activated when you explicitly say so, but it seemed as
if it might be useful.
Another thing that occurs to me with an example of this size
and complexity is that perhaps some 'little language' could
be used for specifying separate pieces and then weaving them
together. I certainly don't begin to have the glimmerings of
an initial approximation of understanding the outlines of the
elements of the application domain, so I couldn't do it myself,
but if I _did_, that's the way I'd be thinking. But then,
I'm the sort of person of whom it was said "He'd rather be
writing programs to help him write programs that help him
write programs than write programs that help him write programs."
(Anyone help me with the source of that?)
More information about the erlang-questions
mailing list