unison icon indicating copy to clipboard operation
unison copied to clipboard

Destructuring bind gets rendered sometimes with extra `let`

Open pchiusano opened this issue 2 years ago • 7 comments

Noticed by @SystemFw

I'm not sure when this happens exactly since I've also seen it render correctly without the let.

CleanShot 2023-10-13 at 12 54 54@2x

pchiusano avatar Oct 13 '23 17:10 pchiusano

This seems to happen every time there is a tuple binding which isn't the first binding in a definition, so:

a =
 (b, c) = ("hello", "darkness")
 "my old friend"

the above gets rendered as written, but:

a =
 b = "hello"
 (c, d) = ("darkness", "my old")
 "friend"

gets rendered as:

a : Text
a =
  b = "hello"
  let
    (c, d) = ("darkness", "my old")
    "friend"

this is actually very annoying, not so much because of the let, but because you get this extra indentation layer

SystemFw avatar Nov 12 '24 12:11 SystemFw

When is an explicit let actually required? That would help any potential contributors fix the bug accurately.

mitchellwrosen avatar Nov 12 '24 16:11 mitchellwrosen

The only case I'm aware of is #5451: you have a lambda without cases, and need a multiline body for that function (although even in that case, required is arguable, more details in the issue). In the case of tuples, let is not required, the code parses just fine without it, but the pretty-printer inserts it.

SystemFw avatar Nov 12 '24 16:11 SystemFw

Ah, I just came across another:

Some
  let
  (foo, bar) = ...
  baz

The let here is required; this doesn't parse (should it?)

Some
  (foo, bar) = ...
  baz

mitchellwrosen avatar Nov 14 '24 23:11 mitchellwrosen

ah fair enough, I wouldn't expect that to parse without let (unlike a multiline block after ->, which ideally wouldn't require let)

SystemFw avatar Nov 19 '24 10:11 SystemFw

Confirmed (in case it wasn't clear) that this is about destructuring binds in general, not just tuples, I see this in an inner function.

    startView : Epoch ->{Remote} Void
    startView currentEpoch =
      use Map union
      use Remote detachAt
      let
        (Cluster _ _ _ _ getLoglets _ _) = Plan.cluster plan

not super clear why it triggers though, maybe it's because of the appearance of use, but I struggle to get the pretty printer to print use clauses reliably in a self contained example

SystemFw avatar Nov 26 '24 16:11 SystemFw

Just came across this from #5451 — it looks like this is a dupe of #4616 (or vice versa) and should be fixed by #5644 when the next release goes out.

dfreeman avatar Apr 28 '25 14:04 dfreeman