Ppx Aesthetics Discussion

Disclaimer: this post is purely about minor matters of syntax aesthetics. If you don’t want to spend any time on this, please move on to another topic.

Having said that, I’ve always been bothered by how ugly ppx extensions look:

let%lwt x = Lwt.return 1 just seems really unattractive and messy to me – almost unreadable. However, I just realized we can use

let %lwt x = Lwt.return 1 instead, which to my eye looks so much better. We could even add spacing on both sides, with

let % lwt x = Lwt.return 1, but I feel that this is overkill, since it looks too much like an operator, and the extension looks like a variable.

I realize this is essentially a no-op, since the parser already supports spaces, but I’d love for the default formatting to switch to the 2nd version, which is far more elegant and makes ppx extensions look like a proper part of the language.

What do you guys think?

1 Like

tbh none of them looks significantly superior to others. If you are talking about aesthetics, I think lwt x = Lwt.return 1 looks the best to me but it’s from camlp4 age.

2 Likes

In my opinion, the one making it messy is the % sign. It was my reaction too when learning Elixir, because they use it for map syntax (e.g. %{foo: "bar"}). But I came to terms with it eventually.

In this case, having that sign in between ascii characters makes it more noisy indeed. But separating it from let, although indeed giving more breathing room to readers, might make it a bit more confusing, since the concept and semantic is tied more to let than x.

1 Like

I’m pretty new at OCaml but I find the former is more readable to me. It says “this isn’t a let, it’s just something lwt uses that looks like a let.” When I encounter such things in code I understand much faster that I’m looking at a syntax extension.

That said, taste is personal. :slight_smile:

2 Likes

I tend to agree. I think it was an unfortunate choice.

let@lwt x = return 1
let#lwt x = return 1

Either one of these look less messy than

let%lwt = return 1

However, given the choice, I think the space makes it more readable.

That’s true, but I think there needs to be a compromise between readability to new users and aesthetics. Many languages, including OCaml, have a lot of features that are weird initially. object#method looks very odd to newcomers, and perhaps even to OCaml users since objects are so rare. But you learn it and move on. IMO let %lwt x is just far more elegant than let%lwt x. As regular OCaml users, we don’t need the association hinted by the latter compact form after the first few times of coming across the concept.

See above. You’ll get used to the meaning of the syntax after the first couple of instances, but you’ll have to live with the way it looks for as long as you use the language.

I agree about tastes though. That’s the reason for the disclaimer in my original post.

I don’t much like the % here either. Unfortunately, I don’t think add a space is any improvement at all (to my taste). In fact, the space makes it worse in my eyes :frowning:

5 Likes

FWIW I was playing with ocamlformat and Lwt code right now, it turns out ocamlformat formats

let%lwt foo = Lwt.return 1 in
Lwt.return foo

to

[%lwt
  let foo = Lwt.return 1 in
  Lwt.return foo]

So there’s an alternative form! Although I’m not sure if I like it more having seen it just this once. But it seems to get clunky when we have more let%lwts:

let%lwt foo = Lwt.return 1 in
let%lwt bar = Lwt.return 1 in
let%lwt baz = Lwt.return 1 in
Lwt.return @@ foo + bar + baz

becomes

[%lwt
  let foo = Lwt.return 1 in
  [%lwt
    let bar = Lwt.return 1 in
    [%lwt
      let baz = Lwt.return 1 in
      Lwt.return @@ foo + bar + baz]]]

so, uh, I don’t know…

That’s actually the full form. The let%lwt form is syntactic sugar.

let %lwt foo = Lwt.return 1 in
let %lwt bar = Lwt.return 1 in
let %lwt baz = Lwt.return 1 in
Lwt.return @@ foo + bar + baz

Really surprised I’m getting no positive responses to this form (ie. with a space). It looks so much better to me.

Well personnally, with syntactic coloration, I actually find the let%lwt x = ... in quite readable and better than the options with spaces which looks a bit strange to me (but that may be because I’m used to the no-space option).

I overall prefer writing foo bar >>= fun something -> ... without any
ppx, but since you ask about feedback:
among those options I also prefer the no-space let%lwt since it makes it
look more like what it actually is: a totally different keyword;
i.e. if my eyes see a let by itself, I always know it’s a let binding
hence lower mental burden.

3 Likes

Just to repeat, the reason I prefer the let%foo form is because it flags, to my eye, that I’m not looking at a let. To be even more specific, lets take sedlex. It’s nice that match%sedlex, which really is not a match at all but is a way of saying “this is a lexical analyzer specification”, is visually distinct.

But as we’ve all said before, taste is individual, and I can’t possibly claim my preference is objectively correct.

FTR, I can’t say that ocamlformat’s behavior here is, um, intended…