As I use LLMs more in my daily Clojure work, I keep running into the same issue - models often miscount closing parens and produce broken code. And I find long ))))) chains confusing myself too.
For humans there are great tools - paredit (structure editing), rainbow brackets, block highlighting in IDE - that mostly solve this. But for LLMs none of that applies.
I know there’s an existing practice of leaving comments after closing parens:
(defn process-user [user]
(when (:active? user)
(update user :name str/upper-case))) ;; when ;; defn
This does help LLMs track context, but it breaks paredit (it doesn’t move comments with parens), and the marker ends up after the closing paren - when the model has already closed the form and moved on.
I’ve been thinking about using #_ instead:
(defn process-users [users]
(filter
(fn [user]
(and (:active? user)
(> (:age user) 18) #_and) #_fn)
users #_filter) #_defn)
#_ discards the next form at the reader level, this is valid Clojure - no preprocessor, no changes to the compiler. The marker sits inside the form before the closing paren, so the structure of the code is preserved.
The pattern is specific enough that tooling could do interesting things with it:
-
paredit could treat
#_token)as a unit and move them together -
rainbow-delimiters could color
#_tokenthe same as its opening paren - no name matching needed, just depth counter at that position -
IDEs could hide or de-emphasize these markers if you want cleaner visuals
Obviously this adds verbosity, but it’s purely opt-in - useful in deeply nested code, skip it elsewhere.
Has anyone tried something like this?