PrettyPrinting: optimal layout for code and data

07/29/2021, 5:40 PM5:50 PM UTC
Blue

Abstract:

PrettyPrinting is a library for formatting composite data structures. PrettyPrinting optimizes the layout of the data to make it fit the screen width.

Out of the box, PrettyPrinting can format Julia code and standard Julia containers. It can be easily extended to format custom data types.

Description:

If you use Julia REPL to work with JSON or other nested data structures, you may find the way the data is displayed unsatisfactory. If this is the case, consider using PrettyPrinting. Compare:

<pre> julia> data = JSON.parsefile("patient-example.json") Dict{String, Any} with 14 entries: "active" => true "managingOrganization" => Dict{String, Any}("reference"=>"Organization/1") "address" => Any[Dict{String, Any}("line"=>Any["534 Erewhon St"], "dis… "name" => Any[Dict{String, Any}("family"=>"Chalmers", "given"=>Any[… "id" => "example" "birthDate" => "1974-12-25" ⋮ </pre> <pre> julia> using PrettyPrinting julia> pprint(data) Dict( "active" => true, "managingOrganization" => Dict("reference" => "Organization/1"), "address" => [Dict("line" => ["534 Erewhon St"], "district" => "Rainbow", "use" => "home", "postalCode" => "3999", "city" => "PleasantVille", "period" => Dict("start" => "1974-12-25"), "text" => "534 Erewhon St PeasantVille, Rainbow, Vic 3999", "type" => "both", "state" => "Vic")], "name" => [Dict("family" => "Chalmers", "given" => ["Peter", "James"], "use" => "official"), Dict("given" => ["Jim"], "use" => "usual"), Dict("family" => "Windsor", "given" => ["Peter", "James"], "use" => "maiden", "period" => Dict("end" => "2002"))], "id" => "example", "birthDate" => "1974-12-25", ⋮ </pre>

PrettyPrinting optimizes the layout of the data to make it fit the screen width. It knows how to format tuples, named tuples, vectors, sets, and dictionaries.

PrettyPrinting can also serialize Expr nodes as Julia code. It supports a fair subset of Julia syntax including top-level declarations, statements, and expressions.

The ability of PrettyPrinting to format Expr nodes makes it easy to extend pprint() to user-defined data types. Indeed, it is customary to display a Julia object as a valid Julia expression that constructs the object. This could be done by converting the object to Expr and having pprint() format it.

For example, let us define a type MyNode modeled after the standard Expr type.

<pre> julia> struct MyNode head args MyNode(head, args...) = new(head, args) end </pre>

The default implementation of show() is not aware of the custom constructor. Moreover, it dumps the whole object in a single line, making it difficult to read.

<pre> julia> tree = MyNode("1", MyNode("1.1", MyNode("1.1.1"), MyNode("1.1.2"), MyNode("1.1.3")), MyNode("1.2", MyNode("1.2.1"), MyNode("1.2.2"), MyNode("1.2.3"))) MyNode("1", (MyNode("1.1", (MyNode("1.1.1", ()), MyNode("1.1.2", ()), MyNode("1.1.3", … </pre>

We implement function quoteof(::MyNode) to convert MyNode to Expr. We can also override the default implementation of show() to make it use pprint().

<pre> julia> PrettyPrinting.quoteof(n::MyNode) = :(MyNode($(quoteof(n.head)), $((quoteof(arg) for arg in n.args)...))) julia> Base.show(io::IO, ::MIME"text/plain", n::MyNode) = pprint(io, n) </pre>

Now the output is correct Julia code that fits the screen width.

<pre> julia> tree MyNode("1", MyNode("1.1", MyNode("1.1.1"), MyNode("1.1.2"), MyNode("1.1.3")), MyNode("1.2", MyNode("1.2.1"), MyNode("1.2.2"), MyNode("1.2.3"))) </pre>

Internally, PrettyPrinting represents all potential layouts of a data structure in the form of a layout expression assembled from atomic layouts, vertical and horizontal composition, and the choice operator. The layout cost function estimates how well the layout fits the screen dimensions. The algorithm for finding the optimal layout is a clever application of dynamic programming, which is described in Phillip Yelland, A New Approach to Optimal Code Formatting, 2016.

Platinum sponsors

Julia Computing

Gold sponsors

Relational AI

Silver sponsors

Invenia LabsConningPumas AIQuEra Computing Inc.King Abdullah University of Science and TechnologyDataChef.coJeffrey Sarnoff

Media partners

Packt Publication

Fiscal Sponsor

NumFOCUS