chapter nine

9 Greedy iterative pretty printing

 

This chapter covers

  • Defining the “pretty-printing” problem
  • Using greedy algorithms to find nonoptimal solutions quickly
  • Avoiding deep recursion through explicit stacks
  • Separating concerns with the visitor pattern

Modern editors for software developers usually provide automatic code formatting for a variety of languages. This feature is particularly useful for languages with weak rules for using spaces and line breaks. Languages such as C, Java, and C# don’t care at all whether you write terse code like this

double Frob(int x){int y = Qux(x); return Rezrov(y+1);}

or some goofy thing like this:

  double Frob(int x)
{ int y = Qux(  x);
    return Rezrov(y +1 )  ; }

In many languages, programmers have great freedom to format their code as they prefer. But most of us aren’t writing brand-new code for our own amusement; we spend our careers in industry working on existing large codebases with colleagues. The rules for preventing chaos have been the same on every team I’ve ever worked on:

  • Everyone should use the same automatic code formatter to format all new files before checking them in.
  • Never change the formatting of existing files unless the change is only to update the formatting to meet the standard.

9.1 The pretty-printing problem

9.2 Greedy algorithms and making change

9.3 A greedy pretty-printing algorithm

9.3.1 The doc data structure

9.3.2 Visualizing a doc: How deep does it get?

9.3.3 Phase 2: Implementing Fits() without recursion

9.3.4 Phase 2 continued: Implementing Pretty() without recursion

9.4 Phase 1: Transforming parse trees with the visitor pattern

9.4.1 Implementing the visitor pattern

9.4.2 From parse tree to doc

Summary