[mercury-users] Preferred coding style for switches

Ralph Becket rbeck at microsoft.com
Fri Dec 10 05:07:34 AEDT 1999


> After discussions with my advisor about such topic, He 
> convinced me that
> the second style is more readable and thus more declarative, 
> but it's true
> that it's more verbose. I've heard also that the compiler 
> translates the
> clausal form of the 1st style into a switch-like form (am I wrong?).

Both styles are semantically identical and so are equally declarative -
well, in Mercury you have to work hard *not* to write declarative code :)

> Would be less efficient to rewrite this as follows?
> 
> p(Y, X) :-
> 	(
> 		X = bar1,
> 		p_bar1(Y, X)
> 	;
> 		X = bar2,
> 		p_bar2(Y, X)
> 	;
> 	...
> 	;
> 		X = barN,
> 		p_barN(Y, X)
> 	).
> [...]
> 
> I know this would be tedious, specially the declarations of the new
> predicates. My question is if programming like this would be 
> inefficient.

This is a Prologism: typically, a Prolog compiler will only perform indexing
on the first argument.  That is, it can spot when a choice-point can be
avoided by looking for predicates where each clause unifies its first
argument against a different functor, in which case it generates code for a
switch or something similar.  But this is usually only done for the first
argument, so if you want efficiency you end up recoding as you show above.

The Mercury compiler, however, indexes on *all* arguments, so this is
unnecessary.  The Mercury compiler also does an excellent job of spotting
places where it can generate switches (i.e. where an argument is tested
exhaustively against the different constructors of a type) and will even
spot nested switches.

This is the case that I described in my previous post.  The question is
whether people find the many-clauses approach easier to read or prefer the
clause-plus-disjunction style.  It's an aesthetics thing.

The many-clauses style, I feel, makes it more obvious that one is coding
up a table of some sort.  The down-side is that you can end up duplicating a
lot of boilerplate in the extra clause headers.  The clause-plus-disjunction
style avoids verbiage and makes the switch obvious at the cost of
(a) stealing a level of indentation and (b) putting more space between the
clause head and the lower switch arms.

> If some bar's are not needed for the foo's, another avantage 
> of switches
> could be that it could be rewritten as if-then-else and like 
> this, it could
> be easy to program a "default" case for the bar's not used, 
> and maybe make
> this deterministic. I think the determinism analysis of 
> Mercury is more
> safe when programming with switchs.

In Mercury parlance, a switch is an exhaustive test against the possible
type constructors a variable can have.  This might be implemented as
cascading if-then-elses or as a lookup table [Mercury chaps: what rule
does get used?]  The key thing is there's no default case - to do that
you have to explicitly write a chain of if-then-elses or put a wrapper
around a semideterministic predicate.

Cheers,

Ralph
--------------------------------------------------------------------------
mercury-users mailing list
post:  mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the users mailing list