Skip to content

Missing an empty surround operator? #5

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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