Guards and side effects
Richard A. O'Keefe
Mon Mar 14 03:20:16 CET 2005
"Vlad Dumitrescu" <> wrote:
Good point, I think. The language proper should not be
restricted by what are mostly implementation/optimization
issues. And extra power might open possibilities that now are closed.
What is allowed in guards is NEITHER an implementation NOR an optimisation
What's more, there are *NO* 'possibilities that are now closed'
with the single exception of the 'receive' construct.
Proof: the Haskell report shows how Haskell guards are nothing more than
syntactic sugar and provides explicit transformations which can be used
to eliminate guards entirely. This elimination does not introduce
order-of-magnitude changes in efficiency or expressiveness. Indeed,
many functional programming languages including ML and its relative
have no guards at all. (Nor do Lisp and Scheme, including Kali-Scheme,
a version of Scheme with some similarities to Erlang.)
Erlang was influenced by Prolog and concurrent logic programming languages.
There are technical reasons why committed choice concurrent LP languages
like Parlog, GHC, and FCP place strong constraints on what you can say in
a guard. In the absence of logical variables, not only guards but even
pattern matching are entirely dispensable.
In Haskell, the choice between using guards and using 'if' is entirely
stylistic. That is NOT a necessary truth about all functional programming
languages. In particular, for a language which is supposed to be useful for
soft real time programming, it is useful to know that certain constructions
MUST terminate and in bounded time.
I repeat my earlier observation that the real problem is not that guards
need to be more like expressions in Erlang but that they are already too
MUCH like expressions, and should be restricted further. For example,
length/1 should not be allowed in guards. All the uses of length/1 I've
seen in guards could either be replaced by body code using length/1 (with
an increase in clarity) OR by
<guard expression> length<relop> <constant>
where for example
X length>= 2
is true if X = [_,_|_]. This replacement would in some cases yield a
substantial increase in efficiency. Naturally, this construct would not\
be made available in expressions; guards and expressions *in Erlang*
should be distinct. (This is not a general truth about all functional
programming languages, any more than the converse is.)
I also repeat that abstract patterns give you a way to have user-defined
"predicates" for use in guards that don't break the basic rules, and are
entirely safe to use in 'receive'.
More information about the erlang-questions