# \#\_ as a semantic block-closing marker for LLM-friendly Clojure

**URL:** https://clojureverse.org/t/as-a-semantic-block-closing-marker-for-llm-friendly-clojure/14851
**Category:** Watercooler
**Created:** [March 4, 2026, 5:48pm UTC](https://clojureverse.org/t/as-a-semantic-block-closing-marker-for-llm-friendly-clojure/14851 "2026-03-04T17:48:20Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![dankinsoid](https://clojureverse.org/user_avatar/clojureverse.org/dankinsoid/32/5848_2.png) [@dankinsoid](https://clojureverse.org/u/dankinsoid)
#### Post date: [March 4, 2026, 5:48pm UTC](https://clojureverse.org/t/as-a-semantic-block-closing-marker-for-llm-friendly-clojure/14851/1 "2026-03-04T17:48:20Z")

</div>

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:

```clojure
(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:

```clojure
(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 `#_token` the 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?

---

<div class="post-metadata">

### Author: ![jm-g](https://clojureverse.org/user_avatar/clojureverse.org/jm-g/32/6138_2.png) [@jm-g](https://clojureverse.org/u/jm-g)
#### Post date: [March 12, 2026, 7:09pm UTC](https://clojureverse.org/t/as-a-semantic-block-closing-marker-for-llm-friendly-clojure/14851/2 "2026-03-12T19:09:48Z")

</div>

You write that you are using an LLM, but if you are using the LLM through an agent tool like claude code or others you could register a post tool hook that corrects parenthesis in the changed code based on the indentation. Because LLMs are quite good at keeping the indentation correct. [`brepl`](https://github.com/licht1stein/brepl) contains such a hook implementation for claude-code and eca.

---

<div class="post-metadata">

### Author: ![maxweber](https://clojureverse.org/user_avatar/clojureverse.org/maxweber/32/2271_2.png) [@maxweber](https://clojureverse.org/u/maxweber)
#### Post date: [March 12, 2026, 8:32pm UTC](https://clojureverse.org/t/as-a-semantic-block-closing-marker-for-llm-friendly-clojure/14851/3 "2026-03-12T20:32:38Z")

</div>

Which model are you using? I’m using Opus 4.6 (and 4.5 beforehand) with Claude Code (no additional tooling) and it almost never struggles with the parentheses and if it does, it is able to fix it on its own.

---

<div class="post-metadata">

### Author: ![Mallo](https://clojureverse.org/user_avatar/clojureverse.org/mallo/32/5336_2.png) [@Mallo](https://clojureverse.org/u/Mallo)
#### Post date: [March 16, 2026, 12:52am UTC](https://clojureverse.org/t/as-a-semantic-block-closing-marker-for-llm-friendly-clojure/14851/4 "2026-03-16T00:52:22Z")

</div>

Maybe you know about Bruce Hauman’s Clojure MCP Light, which despite its name is a way to help LLMs untangle delimiter problems?

> **[GitHub - bhauman/clojure-mcp-light: Simple Clojure tooling for AI coding assistants](https://github.com/bhauman/clojure-mcp-light)**
>
> Simple Clojure tooling for AI coding assistants

> **[Reddit - The heart of the internet](https://www.reddit.com/r/Clojure/comments/1p89mo9/clojure_mcp_light_so_light_its_not_even_an_mcp/)**

Myself, whenever I’ve had delimiter issues I’ve simply asked the agent to refactor the function into smaller composable functions and that’s solved the problem. I personally favor really short functions especially for LLMs. Strong opinion lightly held…

---

<div class="post-metadata">

### Author: ![system](https://clojureverse.org/uploads/default/original/2X/5/51079bf9e4b7d9466242c06cf1e43b9f8bd6da14.png) [@system](https://clojureverse.org/u/system)
#### Post date: [September 14, 2026, 12:53pm UTC](https://clojureverse.org/t/as-a-semantic-block-closing-marker-for-llm-friendly-clojure/14851/5 "2026-09-14T12:53:05Z")

</div>

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.
