Debugging Erlang

On November 27, 2011, in Erlang, by bryanhunter

In 2007 when I keyed my first “HelloWorld.erl” in Notepad, I remember a general uneasiness descending over me.

I’m typing code in Notepad.
Notepad doesn’t have syntax highlighting.
Notepad doesn’t provide error squiggles.
Notepad doesn’t provide IntelliSense.
Notepad doesn’t have a “Build Solution”.
How am I supposed to set a breakpoint from Notepad?
How am I supposed to debug this stuff?
Oh, dark night of the soul! What am I getting into here!?

Well here’s an answer to at least the debugging bit…

This screencast is a simple demo of debugging (stepping through) a recursive function in an Erlang module. For grins, and to make it clear that no IDE magic is involved, the code is edited using Notepad.

My plan is to release a new “Erlang for .NET Developers” screencast each week. Most will follow this simple “answer to common questions” format. In the next one, I’ll show my Emacs Erlang rig (with syntax highlighting, error squiggles, auto-completion) in action. From there I will work down a list of questions that O.J. Reeves (@TheColonial) and I have accumulated. The two of us are drafting a book with the working title “Erlang for .NET Developers”. If you are a .NET developer and learning Erlang, we would love to see your questions. Please post them as comments or via Twitter.

Tagged with:  
  • Anonymous

    This is great! I’m really looking forward to seeing these screen casts.

  • http://ifandelse.com Jim Cowart

    Great post Bryan! I can’t wait until you post on rebar – so clueless n00bs like me can benefit from your battle-earned experience.

    Also, it might be worth mentioning why the “locals” section of the debugger showed “2c” instead of [50,99] as you stepped through the code – the integers in the list being interpreted as ASCII numeric code for corresponding symbols, and then displayed as a string. I know that kind of thing has left me scratching my head (the “RCA dog” moment, as I call it) as I’ve played with Erlang.

    I’m very excited to hear about the book you and O.J. are working on! Keep this kind of stuff coming!

    • Anonymous

      Thanks Jim!

      Well spotted about the debugger showing the variable T as “2c” instead of “[50,99]” at around six minutes into the screencast. As you note, it is being displayed as a string. ASCII 50 is “2″ and ASCII 99 is “c”.

      Strings in Erlang are lists of integers. If you display a list of numbers and each number in the list falls within the range of ASCII printable characters (32 through 126) *, Erlang will assume you want to display a string. The list [10, 22, 50, 99] doesn’t entirely fall within the printable range so it is displayed as “[10, 22, 50, 99]“. The list “[50, 99]” does so it’s displayed as “2c”.

      * To make it more confusing, some ASCII Character Escape Codes (e.g. 9 for tab, 10 for return, 13 for line feed) are considered printable.

      If you have a list in your code you can display it however you see fit, but the debugger uses the default (sometimes unwanted) formatting.

      Also, great idea about covering rebar. What in particular would you like to see covered?

      • http://ifandelse.com Jim Cowart

        I’ve only worked with rebar a limited amount, so the things that are of interest to me are: 1.) different types of “projects” (for lack of better descriptions) that rebar can generate structure for + when/why you’d use them, 2.) releases, 3.) best practices in managing dependencies….

        Some non-rebar (or at least, not necessarily rebar-only) interests for me would be how other Erlang-ers are managing deployments, standing up erlang processes (daemons?), etc.

  • http://twitter.com/7sharp9 Dave Thomas

    Nice into to debugging, its quite scary coming from something like Visual Studio! I’m very much used to having an elaborate environment

  • Andy Collins

    Nice video, but I wonder why you didn’t take advantage of the actual bug – dvide by zero when the calculate function is passed an empty list – in the calculate module?

    • Anonymous

      Hey thanks Andy, and well spotted on the empty list. I remember considering putting a guard to handle the empty list case, but then thinking it might be a distraction to the debugger show-and-tell. Debugging the “[] case” would have meant making a code change, recompiling and debugging again. For grins, here’s a more defensive version:

      -module(average).
      -export([calculate/1]).

      calculate([]) ->
      0;
      calculate(X) when is_list(X)->
      calculate(X,0,0);
      calculate(_) ->
      {usage, “calculate expects a list of numbers”}.

      calculate([H|T], Length, Sum) ->
      calculate(T, Length+1, Sum+H);
      calculate([], Length, Sum) ->
      Sum/Length.

      • Askingalot

        Thanks for fleshing out the example I’m really impressed with the way pattern matching lets you seperate the input validation code from the actual work being done.

        It’s a lot cleaner than having a list for these at the top of each method:

        if (arg == null)
        throw new ArgumentNullException(“arg”);

        I wonder about the Calculate(_) clause though. Is that strictly necessary?