[erlang-questions] Floating guard sequences

Hynek Vychodil <>
Fri Feb 20 02:06:11 CET 2009


+1 Yep

On Fri, Feb 20, 2009 at 12:53 AM, Richard O'Keefe <> wrote:

>
> On 20 Feb 2009, at 9:22 am, Zvi wrote:
> >
> >
> > fess-3 wrote:
> >>
> >> ...
> >> floating guards on the LHS of a match seem like they could make
> >> code much more concise and readable, and erlang-like [ to me ]
> >>
> >>
> >>   { X when is_integer(X), [ "x" | Rest ] } = string:to_integer(Str),
> >>   { Y when is_integer(Y), _ } = string:to_integer(Rest),
> >>
> >
> > much more readable, if we can marry patterns with guards:
> >
> >   { X = int(), [ "x" | Rest ] } = string:to_integer(Str),
> >   { Y = int(), _ } = string:to_integer(Rest),
> >
> > where int() is patten matching any integer value.
>
> int() would be a function call, which doesn't make much sense
> in a guard.
>
> This is a rather interesting example, because
>  - string:to_integer/1 and string:to_float/1
>    ARE in the on-line documentation
>  - they ARE accepted by 'erl'
>  - but they are NOT in lib/stdlib/src/string.erl
> They both return either {Number,Tail} or {error,Cause}.
>
> I have to say that this interface is brain-dead.
> When a function can return one of several outcomes,
> it should be possible to tell one from another by a simple
> pattern match.  A *good* result would be
>        {ok,Number,Tail}
> or      {error,Cause}
>
> The solution is not to bloat the pattern sublanguage beyond
> all recognition, but to fix the broken interface.
>
> better_to_integer(String) ->
>     case string:to_integer(String)
>       of {error,Cause} -> {error,Cause}
>        ; {Number,Tail} -> {ok, Number,Tail}
>     end.
>
> better_to_float(String) ->
>     case string:to_float(String)
>       of {error,Cause} -> {error,Cause}
>        ; {Number,Tail} -> {ok,Number,Tail}
>     end.
>
> and then to write a plain
>
>        {ok,X,[$x|Rest]} = better_to_integer(Str),
>        {ok,Y,_        } = better_to_integer(Rest)
>
> Testing whether X or Y is an integer ASKS THE WRONG QUESTION.
> A better question is "is this not the atom 'error'"?
> But the best question is the one we really want: "is this
> conversion ok?"  And fixing the interface lets us ask very
> simply what we really mean.
>
> There's a common pattern I'm seeing in discussions like this.
> There is some ugly code, but people accept the *cause* of the
> ugliness and just want to put a glossy coat of paint over
> the *symptoms*.
>
> It's a basic principle of good data structure design in Prolog,
> which has carried over without change to Erlang, that when a
> data structure could be one of several alternatives, you
> should be able to recognise each of the alternatives with a
> single *positive* pattern match.  (That is, nothing should
> be recognised by virtue of not being something else.)  When I
> reimplemented the internal data structures of the Quintus
> Prolog compiler to follow this principle, not only was the
> code easier to read, the compiler ran 20% faster.
>
> > Or, if X and Y unused, like in the example above:
> >
> >   { int(), [ "x" | Rest ] } = string:to_integer(Str),
> >   { int(), _ } = string:to_integer(Rest),
>
> It's *still* better to write
>
>     {ok,_,[$x|Rest]} = better_to_integer(Str),
>     {ok,_,_        } = better_to_integer(Rest)
>
> By the way, the pattern ["x"|Rest] should be
> [$x|Rest] as I have it, or "x"++Rest.
>
>
> _______________________________________________
> erlang-questions mailing list
> 
> http://www.erlang.org/mailman/listinfo/erlang-questions
>



-- 
--Hynek (Pichi) Vychodil

Analyze your data in minutes. Share your insights instantly. Thrill your
boss.  Be a data hero!
Try Good Data now for free: www.gooddata.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20090220/61a7c2af/attachment.html>


More information about the erlang-questions mailing list