[erlang-questions] Pretty-printing Erlang

Richard O'Keefe <>
Thu Oct 21 02:59:08 CEST 2010


On 20/10/2010, at 8:03 PM, Bengt Kleberg wrote:

> Greetings,
> 
> I have used the module erl_prettypr
> (http://www.erlang.org/doc/man/erl_prettypr.html) to achieve the emacs
> layout prescribed here at work.

That's not exactly what I wanted, but it did lead me to
erl_tidy:dir(), which was.

There are several things I'd like erl_tidy to do for me
which I can't see any options for.

This isn't actually the original code here.  It's the
code after _my_ el cheapo pretty printer finished with it.

-module(agent).
-export([setup_agents/2]).

setup_agents(Agents, 0) ->
    Agents;
setup_agents(Agents, Num) ->
    Agent = init(),
    setup_agents(Agents ++ Agent, Num - 1).

init() ->
    Vision = random:uniform(3),
    Hunger = random:uniform(5),
    Food = random:uniform(8),
    [{agent, Vision, Hunger, Food}].

Here's the code after erl_tidy:dir() finished with it.

-module(agent).

-export([setup_agents/2]).

setup_agents(Agents, 0) -> Agents;
setup_agents(Agents, Num) ->
    Agent = init(), setup_agents(Agents ++ Agent, Num - 1).

init() ->
    Vision = random:uniform(3),
    Hunger = random:uniform(5),
    Food = random:uniform(8),
    [{agent, Vision, Hunger, Food}].

erl_tidy: has introduced two kinds of ugliness:
(1) It has removed a line break after the first arrow,
    making the placement of the body code inconsistent
    between the clauses.

(2) There were two body-level expressions in the second
    clause of setup_agents/2 which were well and properly
    separated, but erl_tidy: has put them on the same
    line, making it rather untidy.

This could be addressed by providing
    {break_after_arrow,boolean()}
    {break_after_comma,boolean()}
options.

It's exam time here, so it will be a while before I can
get around to doing anything about this, but before I even
_think_ of peering inside erl_tidy:, do other people
agree that this would be an improvement?



Of course the best code here would be something like

-module(agent).
-export([set_up_agents/1]).

set_up_agents(N) ->
    [new_agent() || _ <- lists:seq(1, N)].

new_agent() ->
    Vision = random:uniform(3),
    Hunger = random:uniform(5),
    Food   = random:uniform(8),
    {agent,Vision,Hunger,Food}.

but it is beyond the scope of a pretty-printer to make
changes like that.

  Here's some sample
code from a student assignment, after erl_tidy:dir() was
done with it.

setup_agents(Agents, 0) -> Agents;
setup_agents(Agents, Num) ->
    Agent = init(), setup_agents(Agents ++ Agent, Num - 1).

(1) I'd like {break_after_arrow,boolean()}
    to get consistent placement of code after arrows.

(2) I'd like {break_after_comma,boolean()}
    to put the two expressions in the second clause
    on separate lines.

setup_agents(Agents, 0) ->
    Agents;
setup_agents(Agents, Num) ->
    Agent = init(),
    setup_agents(Agents ++ Agent, Num - 1).

It is beyond the power of a 



> 
> The code I write has 1 tab per level instead of the variable amount of
> space/tab that emacs prescribes.
> 
> 
> bengt
> 
> On Wed, 2010-10-20 at 04:59 +0200, Richard O'Keefe wrote:
>> I have been marking some student Erlang code and could have used
>> a pretty-printer.  There's a crude one I wrote, for tidying up
>> basically good code, but something a bit stronger seems to be
>> appropriate.
>> 
>> Any recommendations?
>> 
>> 
>> ________________________________________________________________
>> erlang-questions (at) erlang.org mailing list.
>> See http://www.erlang.org/faq.html
>> To unsubscribe; mailto:
>> 
> 
> 
> ________________________________________________________________
> erlang-questions (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:
> 
> 



More information about the erlang-questions mailing list