[erlang-questions] The Erlang Rationale

Edwin Fine erlang-questions_efine@REDACTED
Wed Oct 1 15:49:06 CEST 2008


This is a dissenting vote regarding macros.

Macros *can* make maintenance harder, just like gotos *can* create spaghetti
code. Neither of them are intrinsically bad, merely easy to misuse. Used
with care and discipline, they both arguably have a place in good
programming practice. Now I may get shot down in flames for saying this, but
tail recursion in Erlang is effectively a restricted form of goto, and it's
used a lot (not by choice over some other construct, though - the language
design forces the usage).

There are some things that macros can do that I have not found as easy (or
possible) to do some other way, for example:

-define(LOG_DBG(Msg, ArgList), iutil_log:log_debug(?MODULE, ?LINE, Msg,
ArgList)).

Example usage:

?LOG_DBG("Received ~p from ~p~n", [Msg, Socket]).

The alternative is ugly.

iutil_log:log_debug(?MODULE, ?LINE, "Received ~p from ~p~n", [Msg, Socket]).

If I find that debug logging is causing too much overhead, I can decide to
conditionally compile it:

-ifdef(DEBUG).
    -define(LOG_DBG(Msg, ArgList), iutil_log:log_debug(?MODULE, ?LINE, Msg,
ArgList)).
-else.
    -define(LOG_DBG(Msg, ArgList), ok).
-endif.

A minor inconvenience of the above is that if it uses variables that are not
otherwise used, you can get compile warnings when debug logging is disabled.
This is easily fixed by using the underscore: _Unused.

If I don't like having to recompile the code to enable and disable debug
logging, but want to turn it on and off at run-time (and still have
negligible overhead when debug logging is disabled), I can do this (and the
source code using this does not change in any way, but of course must
undergo a once-off recompilation):

-define(
    LOG_DBG(Msg, ArgList),
    case iutil_log:ok_to_log(debug) of
        true ->
            iutil_log:log_debug(?MODULE, ?LINE, Msg, ArgList);
        false ->
            ok
    end
).

Checking if the Msg and ArgList should be evaluated before calling saves, at
the cost of an efficient function call, potentially enormous amounts of
unnecessary list creation and destruction (and garbage collection), not to
mention any evaluation of the list elements that might be needed.

In this case I would argue that the macro makes the code *more* maintainable
and easier to read, while keeping it efficient. Agreed, if the macro changes
(and this class of macro seldom changes) I will need to recompile the
dependent code, and this is definitely not good, but as Lord Farquhar said,
"[Many of you may be killed, but] it is a sacrifice I am willing to make."
;-)


On Tue, Sep 30, 2008 at 11:50 PM, Richard O'Keefe <ok@REDACTED> wrote:

>
> On 1 Oct 2008, at 2:30 am, Robert Virding wrote:
>
> > OK, OK, OK, enough already! :-) I will fix the next version in PDF.
> > And I thought this was a bunch of computer savvy people who would
> > just laugh at Word format.
>
> I take software piracy seriously,
> so I do not laugh when I see people giving financial
> support to a large company convicted of software piracy,
> especially when there are free alternatives (AbiWord,
> OpenOffice) and when an open format (HTML) would have
> done just as good a job.
> >
> "i.e. large switches" should be "i.e., large switches".
> "handle large number" should be "handle a large number"
>
> Immutable data structures: (1) they eliminate the classic
> OO problem "what happens when you are iterating over a
> collection and the collection changes" because it can't;
> (2) just today in Haskell-Café someone was complaining about
> a data structure in C# (hence in F#) not being thread-safe
> for no apparent reason, immutable data structures means you
> can't make a thread-unsafe data structure.
>
> "all messages sent were complete, no partial messages"
> -- if you are using two or more node, what exactly stops
> a message sent from one node to another arriving only in
> part?  Communications networks are unreliable, after all.
>
> "The level of security in the message protocol" -- I think
> you need to explain why asynchrony avoids problems with
> this, it's certainly not obvious to me.
>
> "Typing"
>   "I still think is was" s/is/it/
>   "distribution were nodes were" s/were nodes/where nodes/
>
> "Generic requests to an i/o server"
>   1,$s:i/o:I/O:g
>   "while the with" s/the //
>
>   I never did get my head around the I/O protocol, not least
>   because it didn't seem to be written down anywhere.  I am
>   very happy indeed to see this discussion of I/O requests.
>   Being a Bear of Very Little Brain, I *still* don't get how
>   to do the continuation stuff.
>
>   It might be worth while splitting this out as a separate
>   document and putting in enough idiot-level examples so that
>   I finally get it.  [Beg beg.]
>
> "Process Groups"
>   The first straightforward explanation of the idea I've ever
>   seen.  Are there any plans to extend this feature or its use?
>   'It would be good to have some example programs' -- you took
>   the words out of my keyboard.
>
>   "SHAPE \* MERGEFORMAT" I take to be an artefact of the way
>   the PDF was produced.
>
> "the '=' operator"
>
>   What you do not mention, and what would strengthen your position,
>   is that in those languages that have 'let', the '=' sign is usually
>   an essential part of the syntax.
>        ML      let val <pattern> = <expression> in <expression> end
>        Haskell let <pattern> = <expression> in <expression>
>                <function bodies> where <pattern> = <expression>
>   ['let' and 'where' were in ISWIM, if I recall correctly.]
>   So there is nothing in the least unusual in the functional world
>   about <pattern> = <expression>.
>
>   "take apart you cake" s/you/your/
>
>   The thing that *is* rather unusual is allowing '=' inside
>   function calls and having the bindings percolate out.  The
>   introduction of 'fun' and list comprehensions has also done
>   bad things to the simple 'the scope of a variable is the
>   entire clause it occurs in' rule.
>
> "Macros"
>
>    Named constants should have been <pattern> = <guard expression>
>    at top level.  I've tried rewriting some modules that way to see
>    what it looks like and it's beautiful.  I grant the utility of
>    -include, but that's not macros.  If I want M4 I know where to
>    find it.  I have CScout to help me cope with C code that's full
>    of macros, but unless I can talk Diomidis Spinellis into it (and
>    he has other maddened grizzly bears to stun) there isn't and won't
>    be an EScout.  Macros make maintenance *harder*.
>
>   "en Erlang point of view" s/en/an/
>
> "Variable scoping and 'let'"
>
>    This is the perfect opportunity to mention LFE and point out
>    that people who want to try an alternative approach to scoping
>    have something they can play with.
>
>    I note that 'begin' ... 'end' were originally introduced in the
>    form "begin <bindings> within <expressions> end".
>
> "Group leader
>  Group leader
>  <blobs>
>  Process group
>  Process group
>  "user"
>  User driver
>  Job 1
>  Job 2
> "
>   I take these lines at the end to be another artefact of the
>   Weird->PDF conversion process.
>
>
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://www.erlang.org/mailman/listinfo/erlang-questions
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20081001/c28b4c5e/attachment.htm>


More information about the erlang-questions mailing list