[erlang-questions] case expression scope
Thomas Lindgren
thomasl_erlang@REDACTED
Wed Mar 5 12:20:43 CET 2014
(The beginning of that mail looks like Yahoo did a remix of multiple drafts, but I think the rest is okay. Sorry.)
Best,
Thomas
On Wednesday, March 5, 2014 12:18 PM, Thomas Lindgren <thomasl_erlang@REDACTED> wrote:
>
>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/c6fa089b/attachment.htm>
More information about the erlang-questions
mailing list