[erlang-questions] I think I wish I could write case Any of whatever -> _ end.
Richard O'Keefe
ok@REDACTED
Tue May 18 01:09:09 CEST 2010
On May 18, 2010, at 2:00 AM, Eric Newhuis (personal) wrote:
> For the record, I might still disagree, so far. I'm not sure.
> Simply for argument's sake...
>
> The context in which this might be maximally useful is the following.
>
> case some_module:some_function(...) of
> {some, pattern} -> _;
> {some, other, pattern} -> _;
> _ -> whatever
> end.
What is wrong with
case X = some_module:some_function(...)
of {some, pattern} -> X
; {some, other, pattern} -> X
; _ -> whatever
end
>
> Note that I belong to the school of philosophy that suggests that
> the number of temporary variables should be minimized.
By using the wild card, you have *NOT* minimised the number of temporary
variables. All you have done is to carefully deprive your reader of any
clues as to what it is about.
> I don't understand why the above would be called wild-card abuse.
Because the whole *point* of the wild-card is that each and
every occurrence of "_" should represent a DIFFERENT variable.
That's what it means in Prolog, Mercury, Strand88, Parlog, GHC,
ML, Haskell, Clean, ... Every time, a different variable.
But you are relying on the "_" in each arm of the case being
the *SAME* variable.
You are also creating great confusion.
Suppose I have
case foo()
of {ping,_} -> _
; {_,pong} -> _
end
The wild cards *following* the arrows are the *same* variable;
what about the wild cards inside the patterns? If not, why not?
What if I write
case foo() of _ -> case bar() of _ -> _ end end
Does this mean the same as
case foo() of X -> case bar() of X -> X end end
or case foo() of X -> case bar() of Y -> X end end
or case foo() of X -> case bar() of Y -> Y end end
or what?
There's another point. In Erlang as it stands, _every_
variable _without exception_ must be visibly present at
the point where it is bound. (Wild cards are no exceptions
to this rule). You are introducing a new reading of "_"
that violates this rule. If you want to think of the
variable as bound in the pattern, write
case Expr
of X = Pattern when Guard -> X
If you want to think of the variable as bound in the head,
write
case X = Expr
of Pattern when Guard -> X
In either case, the variable X is *visibly* bound.
> It is clear from context that the wild-card represents something
> other than matching.
Yes, but we already *have* something we can use for this purpose.
Ordinary variable names.
> We've seen this idea before. There are those grammars that expose
> variables whose value is whatever matched.
I have no idea what you are referring to. Can you explain?
"Exposing variables" is different from "invisibly binding anonymous
variables".
>
> I suppose the following is where this great idea of mine might break
> down.
>
> case some_module:some_function(...) of
> {some, pattern} ->
> {encapsulated, _};
> {some, other, pattern} ->
> {another, _, encapsulation}
> end.
>
> Although I still don't have a problem with that.
You may not. I do.
> From context I know that the right hand side of the arrow isn't
> pattern matching.
You as author may; your reader WILL have to work harder in reading
to find out what the context *is*, especially if (as is often the
case) the arrow is on the previous screen.
This would be better as
case X = some_module:some_function(...)
of {some, pattern} ->
{encapsulated, X}
; {some, other, pattern} ->
{another, X, encapsulation}
end
There is not one of your examples that would not be massively improved
by introducing a named variable, even a literal X.
>
> I guess where readability might break down is in nesting:
>
> case some_module:some_function(...) of
> {some, _, pattern} -> % _1
> case _ of -> % _2
> {some, great, pattern} ->
> not_so_bad;
> _ -> % _3
> {_, Kind, _} = _, % _4, _5, _6
> Kind
> end
> end.
>
> Although I can still read the above once I learn that underscore
> ('_') is context sensitive.
>
> _1 :: any()
> _2 :: {some, any(), pattern}
> _3 :: {some, any(), pattern}, not {some, great, pattern}
> _4 :: some
> _5 :: pattern
> _6 :: _3
If I want to play at silly puzzles I do the Sudoku problem in the
newspaper. If I'm reading a program, I do *NOT* enjoy pointless
stumbling-blocks placed in my path to understanding.
Let's rewrite your example.
case some_module:some_function(...)
of {some,Kind,pattern} ->
case Kind
of great -> not_so_bad
_ -> Kind
end
end
There is now *no* puzzle-solving for the reader.
Let me raise my usual refrain:
let's have a REAL example.
More information about the erlang-questions
mailing list