<div dir="ltr"><div>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.<br>
<br></div>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.<br>
<div><div><br><br></div><div>The actual clause that predicated all this is here: <a href="https://gist.github.com/goertzenator/9347573">https://gist.github.com/goertzenator/9347573</a><br><div class="gmail_extra"><br></div>
<div class="gmail_extra">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.<br>
<br></div><div class="gmail_extra">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.<br>
<br><br></div><div class="gmail_extra">Thank you for your ideas Richard. I see I could also use funs directly instead of cases.<br></div><div class="gmail_extra"><br><span style="font-family:courier new,monospace">f1(X, Y) -><br>
A = fun({0, Q}) -> Q;<br> ({P, Q}) -> P*Q<br> end({X,Y}),<br><br> B = fun({0, Q}) -> Q;<br> ({P, Q}) -> P+Q<br> end({X,Y}),<br> {A,B}.</span><br><br>Regards,<br>Dan.<br>
</div><div class="gmail_extra"><br><br><br><div class="gmail_quote">On Mon, Mar 3, 2014 at 3:23 PM, Richard A. O'Keefe <span dir="ltr"><<a href="mailto:ok@cs.otago.ac.nz" target="_blank">ok@cs.otago.ac.nz</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><br>
On 4/03/2014, at 8:07 AM, Daniel Goertzen wrote:<br>
<br>
> 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.<br>
><br>
> 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.<br>
<br>
</div>I see a non-sequitur there.<br>
<br>
Simplified examples are great for revealing bugs.<br>
<br>
For illuminating style concerns, NOTHING beats REAL code.<br>
<div><br>
"There were a lot of bindings from the enclosing scope"<br>
</div>is already a warning sign that the code should be restructured.<br>
<div><br>
> Funs would be better, but add clutter and maybe runtime overhead.<br>
<br>
</div>There is currently some run-time overhead.<br>
In R16B03-1, the compiler still does not optimise<br>
<br>
(fun (...) -> ... ... end)(...)<br>
<br>
by turning it into the equivalent of an SML let ... in ... end<br>
form, but there is no particular reason why it couldn't.<br>
<br>
Whether you can _measure_ the overhead in a real application<br>
is another matter entirely.<br>
<br>
Splitting out little functions and then telling the compiler<br>
to inline them might well have the least overhead of all.<br>
<br>
<br>
</blockquote></div><br></div></div></div></div>