Skip to content

Missing an empty surround operator? #5

@gasche

Description

@gasche

@olivier-martinot and myself are writing a pretty-printer for MidML. I got stuck on how to properly pretty-print let ... in, and I think that my final iteration suggests that a new combinator could be useful, but I don't know how to name it.

Specific question

prefix n b empty doc has a short form, jump n b.

What is the short form of surround n b empty doc empty?

Longer story

We want to pretty-print let <lhs> = <rhs> in <body>. All of the subexpressions could be long. The printing discipline we want is as follows:

  • if <lhs> or <rhs> are non-flat, they should be 2-indented on their own lines. (body is not indented)
  • otherwise pack things when they fit

For example we want to allow all of the following:

let <lhs> = <rhs> in <body>

let
  <lhs>
= <rhs> in <body>

let <lhs> =
  <rhs>
in <body>

let <lhs> = <rhs> in
<body>

(Okay, the second example looks very ugly, but (1) this regular structure makes my story applicable to other constructs that contain a mix of keywords and symbols beyond the simple prefix/surround scenarios, and (2) it never occurs in practice, and actually the fact that we never see it probably explains why we find it ugly. I don't want to make the rules or code more complex to forbid it.)

After trying many things, I ended up with the following approach where the code looks simple enough

let print_let_in lhs rhs body =
  string "let"
  ^^ surround 2 1 empty lhs empty
  ^^ string "="
  ^^ surround 2 1 empty rhs empty
  ^^ string "in"
  ^^ prefix 0 1 empty body

The prefix 0 1 empty body form can be simplified into jump 0 1 body.

For lhs and rhs, I would need a version of jump that adds a break on both sides of the main document, not just on the left. Could we have this? What would be a good name for it?

(I don't understand what jump is trying to evoke as a name, how it was chosen.)

Maybe an option would be to add a new parameter to jump for a break on the right: jump n b doc would become jump n b_left doc b_right. The old jump n b doc can be expressed with jump n b doc 0, and my use-case becomes jump 2 1 doc 1.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions