Erlang Thursday – erl_tidy:file/1

Today’s Erlang Thursday takes a look at the erl_tidy module in Erlang, and we start with erl_tidy/1.

erl_tidy:file/1 takes a filename, and “tidies” up and pretty prints the sourcecode in the file specified.

As I have a quick FizzBuzz solution hanging around in a tmp directory, I will just start with that file, and see what erl_tidy:file/1 does to that file, as I am pretty sure it is not completely pretty.

-module(fizzbuzz).

-export([fizzbuzz/1]).

fizzbuzz(N) ->
    Translations = lists:map(fun translate/1, lists:seq(1, N)),
    lists:foreach(fun(Item) -> io:format("~s~n", [Item]) end, Translations).

translate(N) when N rem 3 =:= 0 andalso N rem 5 =:= 0 ->
   'FizzBuzz';
translate(N) when N rem 3 =:= 0 ->
   'Fizz';
translate(N) when N rem 5 =:= 0 ->
   'Buzz';
translate(N) ->
   integer_to_list(N).

We open up a new Erlang shell and call erl_tidy:file/1 with the fizzbuzz.erl.

erl_tidy:file("fizzbuzz.erl").
% fizzbuzz.erl:6: replacing call to `lists:map/2' with a list comprehension.
% fizzbuzz.erl:6: changing application of implicit fun to direct local call.
% ok

Looks like it didn’t like the way I was using map in the original file, and it changed the way I was calling translate/1.

Let’s close out the shell, and see what the directory looks like now.

ls -l
total 16
-rw-r--r--  1 proctor  staff  402 Sep  9 22:06 fizzbuzz.erl
-rw-r--r--  1 proctor  staff  405 Sep  9 22:05 fizzbuzz.erl.bak

Let’s take a look at fizzbuzz.erl.bak and see what is in that file, mainly to confirm that it is the content that was originally in fizzbuzz.erl.

-module(fizzbuzz).

-export([fizzbuzz/1]).

fizzbuzz(N) ->
    Translations = lists:map(fun translate/1, lists:seq(1, N)),
    lists:foreach(fun(Item) -> io:format("~s~n", [Item]) end, Translations).

translate(N) when N rem 3 =:= 0 andalso N rem 5 =:= 0 ->
   'FizzBuzz';
translate(N) when N rem 3 =:= 0 ->
   'Fizz';
translate(N) when N rem 5 =:= 0 ->
   'Buzz';
translate(N) ->
   integer_to_list(N).

That does indeed look like the original contents of fizzbuzz.erl.

Now let’s take a look at the updated fizzbuzz.erl file to see what the result of erl_tidy:file/1 is.

-module(fizzbuzz).

-export([fizzbuzz/1]).

fizzbuzz(N) ->
    Translations = [translate(V1) || V1 <- lists:seq(1, N)],
    lists:foreach(fun (Item) -> io:format("~s~n", [Item])
		  end,
		  Translations).

translate(N) when N rem 3 =:= 0 andalso N rem 5 =:= 0 ->
    'FizzBuzz';
translate(N) when N rem 3 =:= 0 -> 'Fizz';
translate(N) when N rem 5 =:= 0 -> 'Buzz';
translate(N) -> integer_to_list(N).

As the message said, we have a list comprehension instead of map, and it is calling the translate/1 function directly, as mentioned in the two output messages.

It also put the end of the fun passed to lists:foreach/2 on a new line, and the list Translations on a new line as well.

And finally, the last three function clauses of translate/1 were combined into single line functions, and the trailing newline at the end of the file was removed.

According to the documentation page, had the fizzbuzz.eerl file had any unused functions, those would have also have been tidied up, along with “updating obsolete constructs and function calls, etc.”

All in all, a nice little tool of an Erlang application that can help your code keep a certain style and cleanliness to it.

–Proctor

One thought on “Erlang Thursday – erl_tidy:file/1

Leave a Reply

Your email address will not be published. Required fields are marked *