[erlang-questions] Design patterns?

Anders Svensson anders.otp@REDACTED
Sat Mar 7 12:36:26 CET 2015

Proponent is the right word, and Ulf correctly identifies the reason
my code looks as it does: trace.

Erlang has excellent trace facilities, cryptic match specs and all,
and being able to see what the code is doing by enabling some
judicious trace is truly golden. The bigger the system, the more
valuable it becomes. The only thing I miss (aside from instant recall
of the match spec grammar that is) is the possibility of having
multiple tracer processes: being able to write trace-based test/debug
tools that don't interfere with each other would be a huge plus.

Communication is also important of course, but the smaller the
function clause, the less it can do wrong, the easier it is to
pinpoint problems with trace. (And even without trace I'd argue.)
Readability is subjective in any case. I'd label some of my own overly
concise variable names a fail on that point, but I have far more
difficulty reading code that expands horizontally than code that
expands vertically. There's no debating that nested case and large
funs contribute to code that can be difficult to trace however.


On Wed, Mar 4, 2015 at 11:49 AM, Ulf Wiger <ulf@REDACTED> wrote:
> On 02 Mar 2015, at 20:20, Judson Lester <nyarly@REDACTED> wrote:
> And an open question (for me): when to use case/if versus function heads?
> Roughly, I've been using cases to reformat the returns of a function call,
> but the decision trips me up every time.
> There is a consideration worth noting that can affect this decision:
> While you can’t trace on a given case expression, you *can* trace a function
> call.
> In general, I very much agree with Richard O’Keefe: you should choose
> whatever best communicates your intent.
> However, and perhaps Anders Svensson (now on the OTP team) is one of the
> most extreme proponents of this view, breaking out things like local funs
> into separate functions, makes it much easier to debug. This is especially
> true in live real-time systems, where tracing is one of the few ways you
> *can* debug (hopefully) without making a mess of things.
> Now, Erlang does allow you to selectively trace on anonymous funs, in part
> since it translates them into actual functions using a consistent naming
> scheme, but only the nerdiest of Erlang programmers have actually memorized
> this scheme. So if the code looks like this (example from OTP’s ‘diameter’
> application):
> merge_service(Opts, Svc) ->
>     lists:foldl(fun ms/2, Svc, Opts).
> ms({applications, As}, #diameter_service{applications = Apps} = S)
>   when is_list(As) ->
> insert_local_peer(SApps, T, LDict) ->
>     lists:foldl(fun(A,D) -> ilp(A, T, D) end, LDict, SApps).
> ilp({Id, Alias}, {TC, SA}, LDict) ->
> - then you have no problems tracing the ‘inner loop’ function of e.g. a
> fold.
> (Note that in the second example, Anders uses an anonymous fun to include
> part of the environment.)
> From an aesthetic (i.e. communication) standpoint, I find it slightly
> unfortunate, but OTOH, when it’s consistently and competently done, I will
> agree that you reasonably quickly get used to ‘decoding’ the style.
> For those who want to judge whether it’s a technique they want to adopt, I
> recommend reading the diameter sources, where it *is* pretty consistently
> applied.
> BR,
> Ulf
> Ulf Wiger, Co-founder & Developer Advocate, Feuerlabs Inc.
> http://feuerlabs.com
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions

More information about the erlang-questions mailing list