<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=us-ascii"><meta name=Generator content="Microsoft Word 14 (filtered medium)"><!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><style><!--
/* Font Definitions */
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:SimSun;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:SimSun;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Tahoma;
panose-1:2 11 6 4 3 5 4 4 2 4;}
@font-face
{font-family:SimSun;
panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Times New Roman","serif";
color:#000066;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
{mso-style-priority:99;
mso-style-link:"Balloon Text Char";
margin:0in;
margin-bottom:.0001pt;
font-size:8.0pt;
font-family:"Tahoma","sans-serif";
color:#000066;}
span.EmailStyle17
{mso-style-type:personal-reply;
font-family:"Calibri","sans-serif";
color:#1F497D;}
span.BalloonTextChar
{mso-style-name:"Balloon Text Char";
mso-style-priority:99;
mso-style-link:"Balloon Text";
font-family:"Tahoma","sans-serif";
color:#000066;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.25in 1.0in 1.25in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body bgcolor=white lang=EN-US link=blue vlink=purple><div class=WordSection1><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>I really think it’s a great idea.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>For daily erlang programming, I will always collect call traces and get familiar of the modules that I am not familiar with.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Actually I wrote a small tool to generate call flows, but there is a poor muti-process support, so it doesn’t require Lamport clock.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>It just collect the dbg:tracer output and print it out in another way, it’s simple but it works fine </span><span style='font-size:11.0pt;font-family:Wingdings;color:#1F497D'>J</span><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>It work like this:<o:p></o:p></span></p><p class=MsoNormal><img width=787 height=420 id="Picture_x0020_1" src="cid:image001.png@01CD4324.29645FA0"> <span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><div><div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in'><p class=MsoNormal><b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif";color:windowtext'>From:</span></b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif";color:windowtext'> erlang-questions-bounces@erlang.org [mailto:erlang-questions-bounces@erlang.org] <b>On Behalf Of </b>Henning Diedrich<br><b>Sent:</b> Sunday, June 03, 2012 3:02 AM<br><b>To:</b> Erlang Questions<br><b>Subject:</b> [erlang-questions] Trace-Driven Development<o:p></o:p></span></p></div></div><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal style='margin-bottom:12.0pt'><span style='font-family:"Calibri","sans-serif"'>Should there be any interest I would like to discuss tracing and if it may be more valuable for the actor model than unit tests.<br><br>A couple of days ago, during Jesper Louis Andersen's very enlightening debugging and tracing tutorial at Ericsson, Joe Armstrong asked whether showing visual traces <i>first</i> may be a good approach to <i>teaching</i> Erlang, book-side.<br><br>I would like to propose again that trace-driven development may possibly be <i>the</i> way to teach andalso <i>program</i> Erlang. <br><br>In the instance, we were talking about visual traces, like these:<br><br><a href="http://www.erlang.org/doc/apps/et/coffee_order.png">http://www.erlang.org/doc/apps/et/coffee_order.png</a><br><br>I mean it in the slightly unrealistic way that most people probably appreciate test-driven programming as a great idea but seldom execute it as dogmatically as preached.<br><br>But I realize that what I <i>actually</i> do when programming a new app, or when looking for truly nasty bugs, is almost always pretty 'trace-driven'. Writing traces into the program has become a routine step for me when coding medium complicated stuff that uses supervisors, monitors and multiple process that come to live at various times throughout the lifetime of an Erlang (OTP) application -- and most of all, during the <i>start up</i>. And I have always found surprises, which process comes to live when. I think Jesper related a similar story how they found tons of bugs that no-one had realized were there when using tracing (not sure any more.)<br><br>I believe that the main aggravating factor is that you don't construct an OTP application from scratch that often. You'll have to look things up again every next time. My guess is that this is true for the vast majority of Erlang programmers. Of course, for the ultimate expert, it may be hard to grasp what I am even talking about because it's all so 'obvious'.<br><br>But what I really find myself currently doing, before writing tests, is writing traces. I also haven't found out how to plan out and write meaningful stateful tests up front, before I even made it to architect the application.<br><br>My concrete order is: writing first, get to compile, put in traces, try to run, debug.<br><br>I am so sure meanwhile that I will need the traces that I don't wait anymore until I have gotten lost in searching for a bug and not even knowing what happens before the crash and what parts of the program may have silently died and what other parts may have waited for which other part. <br><br>These things will be obvious for expert Erlang programmers who have set up applications time and again. But few people using Erlang for productivity reasons will <i>ever</i> come into that position. And for finding bugs: that's exactly the moment when reality doesn't follow your fantasy and a reality check in the form of a trace is one of the first tools to turn to. Is it not?<br><br>So trace-driven development sounds like it could be a useful recommendation. And if it is, a new best practice of waterfalling your application into existence could maybe emerge, similar to what Joe describes in his book (if I remember well) how he almost always starts out.<br><br>I learned a lot in Jesper's tutorial. For example that because Erlang and OTP keep growing, there are now three distinct mechanisms, with respective modules and function calls, to trace and debug. And despite me using traces a lot, I hadn't used any of them, for the wrong reasons it turned out. (And for productivity, a simple io:format can beat getting tied up into using more powerful but less simple minded options.)<br><br>So I am asking this out of honest ignorance:<br><br>Instead of tracing, is there a way to write meaningful, concise tests that are meant or at least good for checking the sequence of process communications? In other words, are there better alternatives to follow traces with the naked eye? I do not mean a heavy construct, or an also-possible use, but a test-package made for that and/or a useful practice that someone is in fact applying?<br><br>And it need not be the visual traces as the image linked to above. A ping-pong output in the terminal may do (if not skewered by delays or re-sequences or contentions in io:format.)<br><br>For trace-driven development, what concrete procedure with which concrete calls and parameters to erl can be a best practice for starting out? I am sure it' s 'obvious' for many, but at least for me, not. What could be the hello world case for a trace-driven approach?<br><br>And finally, how do <i>you</i> approach setting up a new app, finding a bug -- how much tracing does everyone use in these things? And is anyone also using io:format instead of the OTP goodness, if so, for a good reason?<br><br>Best,<br>Henning<br><br><br></span><o:p></o:p></p></div></body></html>