[erlang-questions] case expression scope

Thomas Lindgren thomasl_erlang@REDACTED
Wed Mar 5 12:18:01 CET 2014



However, note that you don't want to write that sort of code anyway!
However, note that that code also is problematic in another way. 

What happens if we modify the second clause of your example to make Value safe? 
Value = 
>   case orddict:find(foo, Dict) of
>     {ok, Value} -> Value;
>     error -> Value = calculate_very_expensive_default_value()
>   end
How does this evaluate? If orddict finds foo, variable Value is bound in {ok, Value} in the first clause of the case. Then that value is returned from the case clause and MATCHED WITH the binding of the variable Value (itself). Recall that, since Value has been bound in the case clause previously, "Value = case ... end" means matching, not just variable binding. The same reasoning goes for the second clause. 


The basic problem is that the code above mixes two ways of writing erlang. It works, but only by accident, and only at the cost of needlessly walking Value a number of times matching itself. (See the end of this mail for the underlying problem, though.)

Here are the two ways to get it right. First, the old way of writing the same code, which these days give warnings about exported variables:
case orddict:find(foo, Dict) of
>  {ok, Value} -> Value
>  ...
>end,
>... %% use Value afterwards
Note that there's no enclosing "Value = case ... end" up there. Then the new way (which is what most of us use now):
Value =
>   case orddict:find(foo, Dict) of
>      {ok, Val} -> Val;    %% fresh variable
>      ...
>   end,
>... %% use Value, but not Val


In the larger scheme of things: The way I see it, the feature of implicit variable matching is more trouble than it's worth. Warnings about such matches would catch this kind of problems.

Best,
Thomas


On Tuesday, March 4, 2014 11:41 PM, Szoboszlay Dániel <dszoboszlay@REDACTED> wrote:


>Some examples where I really miss them:
>
>foo(Dict) ->
>     Value = case orddict:find(foo, Dict) of
>                 {ok, Value} -> Value;
>                 error       -> calculate_very_expensive_default_value()
>             end,
>     ...
>
>Sorry, variable 'Value' is
 unsafe in 'case', please rename your internal  
>variable to 'Value1' or refactor this humble four-liner into a  
>get_foo_from_orddict/1 function, whichever you feel more inconvenient.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20140305/c2cdeb6f/attachment.htm>


More information about the erlang-questions mailing list