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