chapter nine

9 Greedy iterative pretty printing

 

This chapter covers

  • Defining the “pretty printing” problem
  • Using greedy algorithms to quickly find non-optimal solutions
  • 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 is particularly useful for languages that have weak rules for use of spaces and line breaks. For example, languages such as C, Java or C# do not care at all whether you write terse code like:

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

or some goofy thing like:

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

In many languages, programmers have great freedom to format their code so that it is readable to them. But most of us are not writing brand-new code for our own amusement; we spend our careers in industry working on existing large codebases with colleagues. The rules to prevent 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 two: implementing Fits() without recursion

9.3.4 Phase two continued: implementing Pretty() without recursion

9.4 Phase one: transforming parse trees with the visitor pattern

9.4.1 Implementing the visitor pattern

9.4.2 From parse tree to doc

9.5 Summary