alive-lsp icon indicating copy to clipboard operation
alive-lsp copied to clipboard

Non-aligned loop keyword formatting

Open danprince opened this issue 1 year ago • 1 comments

I'm very new to Common Lisp, so watch out for incorrect/naive assumptions!

Following on from this issue about the formatting of conditional clauses in loop https://github.com/nobody-famous/alive/issues/130. Just to recap, here's some real code with a hand formatted loop.

(defun lookup (map value)
  (loop for (dst src len) in map
        when (and (>= value src) (< value (+ src len)))
        do (return (+ dst (- value src)))
        finally (return value)))

When I use Alive as a formatter, it indents the when keyword.

(defun lookup (map value)
  (loop for (dst src len) in map
          when (and (>= value src) (< value (+ src len)))
        do (return (+ dst (- value src)))
        finally (return value)))

Trying to work out why these conditional clauses aren't indented to match the rest of the loop.

Digging into the formatting code I noticed that they aren't actually included in the list of loop keywords.

https://github.com/nobody-famous/alive-lsp/blob/763633bbdaf270bd86e532be3f3d63e46cb44cd3/src/format.lisp#L26-L27

Without going on a deeper dive, I'm not sure whether this happens because the when keyword isn't included in *loop-keys* or some other mechanism.

There are quite a few more loop clauses that are also not included: https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node240.html

As another comparison, here's the "silly" loop example from Practical Common Lisp.
;; Before formatting
(loop for i from 1 to 100
      if (evenp i)
        minimize i into min-even and 
        maximize i into max-even and
        unless (zerop (mod i 4))
          sum i into even-not-fours-total
        end
        and sum i into even-total
      else
        minimize i into min-odd and
        maximize i into max-odd and
        when (zerop (mod i 5)) 
          sum i into fives-total
        end
        and sum i into odd-total
      do (update-analysis min-even
                          max-even
                          min-odd
                          max-odd
                          even-total
                          odd-total
                          fives-total
                          even-not-fours-total))

;; After formatting
(loop for i from 1 to 100
        if (evenp i)
        minimize i into min-even and
        maximize i into max-even and
        unless (zerop (mod i 4))
        sum i into even-not-fours-total
        end
        and sum i into even-total
        else
        minimize i into min-odd and
        maximize i into max-odd and
        when (zerop (mod i 5))
        sum i into fives-total
        end
        and sum i into odd-total
      do (update-analysis min-even
                          max-even
                          min-odd
                          max-odd
                          even-total
                          odd-total
                          fives-total
                          even-not-fours-total))

Getting the nested indentation correct between each if/else/when/end seems quite tricky, but it does seem strange for do to be the only clause that is aligned with for.

I would assume this was intentional behaviour, but if not, would you accept a PR that would fix the alignment?

danprince avatar Dec 06 '23 20:12 danprince

Yeah, I never quite finished that. I got to where the nested if syntax was the next thing to do and decided to work on other features instead.

PRs are welcome. What I tend to do with PRs is try everything I can think of to break them. If it all works fine, then I'll merge it.

nobody-famous avatar Dec 13 '23 15:12 nobody-famous