[eeps] EEP XXX: Pattern-test operator

Erik Søe Sørensen eriksoe@REDACTED
Mon Apr 16 17:42:31 CEST 2012


Den 16. apr. 2012 10.51 skrev Michael Truog <mjtruog@REDACTED>:

> On 04/15/2012 09:06 PM, Richard O'Keefe wrote:
> > On 16/04/2012, at 1:05 PM, Michael Truog wrote:
> >> So you believe that pattern matching in guards requires binding local
> variables to be useful, right?
> > No, I just believe that it makes them *more* useful.
> >
> >>  You do not seem to be concerned about this change causing guards to
> create side-effects, where they previously where unable to do so.
> > Come off it!  To start with, binding a variable is not a side effect.
> > But consider: apart from 'if', guards are not found on their own, but
> > has one part of a Pattern when Guard combination.  If the Pattern part
> > can bind variables, what is so evil about the Guard part doing so?
> When you consider a side-effect as defined with the simplest possible
> explanation ("a side-effect is where state in context A impacts state in
> context B"), it should be easy to see that a variable created within a
> guard that is then used within a function body is a side-effect.  I
> understand that normal patterns can bind variables.  Why must guards now
> bind variables also?
>
> >>  Are we just not aware or recognizing any potential negative aspects of
> binding variables within guard statements, or do we just accept them as a
> necessary evil?
> > I don't know who "we" are here.  I can imagine no negative aspects of
> binding variables
> > within guards that are not also negative aspects of binding variables
> within patterns.
> >
> > Erlang was strongly influenced by Strand 88 which owed a fair bit to
> Parlog.
> > In Parlog, a clause has the form
> >
> >       H := G1, ..., Gm : Body.
> >
> > where ":" is the "commit" operator, and is left out if m = 0, the Gi
> being
> > the guards., and a Body is
> >       - Body1 , Body2  "parallel AND"
> >       - Body1 & Body2  "sequental AND"
> >       - a call
> > Parlog guards are rather more general than Erlang guards, and it was
> > implementation experience with nested layers of processes that suggested
> > the simplified "flat" guards found in GHC, FCP, and Erlang.  But in all
> > the concurrent logic programming languages, including GHC, FCP, and
> Parlog,
> > guards may include pattern-matches that bind variables.
> >
> > I never heard of any negative consequences of _that_.
> My concern is that you never heard of negative consequences because no one
> cared.  You are arguing with examples from Haskell and Parlog which both
> found no wide-spread use outside of academia.


Saying that there's an abstraction leak in a wide-spread Haskell component
and no-one in the Haskell community cares about it is like saying that the
crew of the ISS doesn't care if there's a leak in their, well, anything.
I find the mention of Haskell in this context quite appropriate.

 I know Haskell has tried very hard to be applied outside of academia,
> however, it never really seems to stick to any problems, so it seems to
> retain status as a language that is a solution in search of a problem to
> solve (any problem will do).  You don't need to bother listing obscure
> research projects done in Haskell here.
>

The XKCD's April Fool's prank recently was at least partially done in
Haskell. Oh, and Facebook, Google and a number of banks use the language
internally. Ericsson too.


> >> To me, the idea of guard statements binding variables seems to
> contradict both the purpose/name "guard" since it is guarding state, and
> binding a variable within the guard statement would be allowing the state
> to leak out.
> > There are no guard statements, only guard tests.  And pattern matching is
> > a perfectly good test.  Consider two clauses:
> >
> >       f(X = Y) when true -> g(X).
> >
> >       f(Y) when X = Y -> g(X).
> >
> > How does the second clause "leak" any "state" that the first one doesn't?
> I agree that both can be written with the changes mentioned in the
> proposal to add variable bindings to guards.  That is part of the reason it
> appears to be an unnecessary addition that is just meant to complicate
> Erlang code and the Erlang VM.
>

The Erlang VM would come to no harm.
(I believe I have enough knowledge of BEAM bytecode to guarantee you this.)



>
> > For that matter, these days Haskell has "pattern guards":
> >
> >       <clause head> | <pattern> <- <expr>{, ...} = <expr>
> >
> > See http://www.haskell.org/haskellwiki/Pattern_guard
> >
> > Nobody in the Haskell community thinks of this as "leaking" any kind of
> "state",
> > and Haskell is notably purer than Erlang...
> Arguing that no one within the Haskell community thought about this
> doesn't seem relevant.  Erlang as a language is at a different place than
> where Haskell is.  I don't see these as differences that should be resolved
> so that Erlang should be more like Haskell.  The purity argument about
> Haskell means very little to someone who is interested in solving problems
> outside of academia.  If Haskell was completely pure, it would never write
> to the screen, and we would know very little about the language... wouldn't
> we?
>

Yes, Haskell can do I/O. If it couldn't, it'd be just as irrelevant as
you're trying to paint it.
But what it also does is keep the I/O parts separate from the parts which
aren't intended to do I/O. And that separation is quite pure.  The purity
argument about Haskell means quite a lot to some which are interested in
solving problems outside of academia and wish to use less of their problem
solving time on hunting bugs caused by unintended side effects. Which, on
the face of it, would be something you care about too.


>
> >> I don't want to push this point if it isn't regarded as a problem, but
> I just wanted to understand how you see it.
> > Here's how I see it:
> > (1) The concurrent programming languages preceding Erlang allowed
> >     pattern matches in guards, using "=".  There were no conceptual
> >     difficulties with this.
> > (2) I have never seen any explanation of why Erlang didn't.
> > (3) It is technically possible to rewrite Erlang clauses with
> >     pattern matching to ones without, at a great loss of clarity.
> >
> >       f(Args) when T1, P = E, T2 -> Body
> >     =>
> >       f(Args) when T1 -> try E of P when T2 -> Body
> >                          catch _ -> rest_f(Args) end;
> >       f(Args) -> rest_f(Args).
> >
> >       f'(Args, P) when T2 -> Body;
> >       f'(Args, _) -> rest_f(Args).
> >
> >     I hope that gives you the idea.  No "state" can be "leaked" by
> >     pattern guards that cannot be "leaked" in this way.
> > (4) Pattern guards in Haskell don't seem to cause any problems.
> >
> My argument is that if patterns already provide us variable bindings, why
> weaken Erlang guards to also bind variables.  I would rather have a
> stronger guarantee that state from a guard will not affect the context it
> controls.  I do not think the aspect in the Haskell language offers a
> convincing argument for binding variables in guards (otherwise, that would
> be like saying "Hey, some academics did something in a language the
> industry doesn't use, but it seems conceptually pure, so lets imitate
> them.").  Implementing something in Haskell does not create a requirement
> that it must be implemented in Erlang.


Certainly not, but countering a purity concern with experience from that
community is not far-fetched.


> A requirement that Haskell features be implemented in Erlang would only
> help Haskell programmers, but if Haskell programmers don't often work
> outside of academia, why would they use Erlang to solve real problems?
>

/Erik (not a practising Haskell programmer myself, but I do know the
paradigm well enough to have respect.)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/eeps/attachments/20120416/63faf3b3/attachment.htm>


More information about the eeps mailing list