[erlang-questions] case expression scope

Daniel Goertzen daniel.goertzen@REDACTED
Wed Mar 5 18:12:38 CET 2014


So I received suggestions to factor out the little functions.  But I was
sure that would ruin the visual locality and "flow" of the code thereby
making it harder to read.  So I decided to go ahead and implement it that
way so I could show those people that they are wrong.  But as I starting
factoring things out I could see the larger-grain structure more easily,
and saw some easy ways to collapse and clean up things... and some of things
that I thought would be problems were not problems at all.  Boy, am I ever
eating crow now. :)

Here is the result: https://gist.github.com/goertzenator/9370847

There may be a bug or two; I am in the process of making functional changes.

So a big thank you to Richard and the others who commented on my coding
style.  I am the sole Erlanger at a small startup, so I don't get the
benefit of that kind of review.

The scoping rules of case still irritate me, but now I have a better sense
as to why it is the way it is, and I have been shown a better coding style
that mostly removes the irritation.

Thanks again,
Dan.


On Tue, Mar 4, 2014 at 10:10 AM, Daniel Goertzen
<daniel.goertzen@REDACTED>wrote:

> I've been reflecting on this some more, and have realized one of my biases
> on the subject comes from the way C/C++ manages scope:  Anything within
> curly braces, whether it is a function, if, while, for, try, or catch, is a
> scope which encapsulates all declarations within.  This uniform rule makes
> it easier to reason about code, and not having it in Erlang is, well,
> jarring to me.
>
> Now both Erlang and C/C++ can *read* variables from enclosing scopes, but
> only C/C++ can *mutate* variables from enclosing scopes.  Perhaps Erlang's
> case scoping rules are just a way to give similar powers to affect the
> enclosing scope.
>
>
> The actual clause that predicated all this is here:
> https://gist.github.com/goertzenator/9347573
>
> There are a lot of case expressions that leave unwanted bindings lying
> around.  I have to pay attention to use different binding names for each to
> avoid collisions.  Specifically the AuthKey and PrivKey expressions had
> collisions at first because they are nearly identical.  The code would be a
> lot easier to reason about if I didn't have to look out for such things.
>
> I tried putting this function together in various different ways, and this
> way was the most concise, most readable, and most amenable to future
> tweaking.  I normally don't tolerate clauses this long, but breaking it up
> always seemed to compromise those things.
>
>
> Thank you for your ideas Richard.  I see I could also use funs directly
> instead of cases.
>
> f1(X, Y) ->
>     A = fun({0, Q}) -> Q;
>            ({P, Q}) -> P*Q
>            end({X,Y}),
>
>     B = fun({0, Q}) -> Q;
>            ({P, Q}) -> P+Q
>         end({X,Y}),
>     {A,B}.
>
> Regards,
> Dan.
>
>
>
> On Mon, Mar 3, 2014 at 3:23 PM, Richard A. O'Keefe <ok@REDACTED>wrote:
>
>>
>> On 4/03/2014, at 8:07 AM, Daniel Goertzen wrote:
>>
>> > Hmm, fun wrapping could be the basis of hygienic-case parse transform.
>>  I'll have to see what the performance overhead of a fun wrap is like.
>> >
>> > The example I gave is contrived and a bit weak I guess.  In my most
>> recent run-in with this issue there were a lot of bindings from the
>> enclosing scope that were used, so breaking things out to top level
>> functions would not always be a good option.
>>
>> I see a non-sequitur there.
>>
>> Simplified examples are great for revealing bugs.
>>
>> For illuminating style concerns, NOTHING beats REAL code.
>>
>> "There were a lot of bindings from the enclosing scope"
>> is already a warning sign that the code should be restructured.
>>
>> >  Funs would be better, but add clutter and maybe runtime overhead.
>>
>> There is currently some run-time overhead.
>> In R16B03-1, the compiler still does not optimise
>>
>> (fun (...) -> ... ... end)(...)
>>
>> by turning it into the equivalent of an SML let ... in ... end
>> form, but there is no particular reason why it couldn't.
>>
>> Whether you can _measure_ the overhead in a real application
>> is another matter entirely.
>>
>> Splitting out little functions and then telling the compiler
>> to inline them might well have the least overhead of all.
>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20140305/88297d52/attachment.htm>


More information about the erlang-questions mailing list