clojure

Jim Newton 2026-03-18T14:17:37.342699Z

Is there a trick I can use to declare an extra variable in a function declaration? In Common Lisp and some other dialects there is a way to put an aux variable in the function declaration. sort of like this (defun x (a b c &aux (d (+ a b))) …) The aux variable cannot be accessed from the call-site, but it saves having to put a let inside the defun. This same &aux syntax is available in anonymous function definitions, and macros, and methods etc.

Jim Newton 2026-03-18T14:18:48.302899Z

one advantage of this syntax is for refactoring later. I don’t have to change the indentation of a function just to add a new local varaible.

dpsutton 2026-03-18T14:20:28.996519Z

Clojure doesn’t have variables so i’m not sure what this would accomplish

Jim Newton 2026-03-18T14:30:09.477639Z

ok, well not variables as such but names bound to values.

borkdude 2026-03-18T14:41:17.332579Z

"save an extra let": why have another obscure way to do it

➕ 3
dpsutton 2026-03-18T15:11:04.186039Z

you can just def some values outside of the body if that’s what it would accomplish? just some constants?

exitsandman 2026-03-18T15:41:07.754279Z

that sounds like a prime place for a macro tbh, if that's your cup of tea

2026-03-18T22:52:34.618249Z

So much negativity! Fellow panelists!! This is a perfect case for a macro. And might be regretted later. But such is the lot of a macro! defn itself is a macro, and could serve as an example.

2026-03-19T02:50:50.861659Z

I think you can use default values like:

(defn x [a b c & {:keys [aux] :or {aux (+ a b c)}}]
  aux)
 
(x 1 2 3) ;;> 6
But I haven't tested. Wouldn't say it's a great idea, cause it would surprise me a bit. And it also lets the caller overwrite the value of aux by optimally passing it as an option like:
(x 1 2 3 :aux 10) ;;> 10

dpsutton 2026-03-19T02:51:25.115299Z

I believe that is heavily discouraged and not officially supported

2026-03-19T02:56:36.481729Z

@dpsutton Might be, but are you sure referring to the arguments is discouraged? Or is it referring to other keys being destructured that is?

dpsutton 2026-03-19T02:57:44.669759Z

yes i believe it is undefined to refer to bound arguments. but maybe it’s more subtle and it is just in maps? i’m not sure

dpsutton 2026-03-19T02:59:53.684159Z

(let [{:keys [a b] :or {b (if (even? (rand-int 2))
                            (+ 1 a)
                            (+ 5 a))}}
      {:a 4}]
  {:a a :b b})
{:a 4, :b 9}
api=> 
(let [{:keys [a b] :or {b (if (even? (rand-int 2))
                            (+ 1 a)
                            (+ 5 a))}}
      {:a 4}]
  {:a a :b b})
{:a 4, :b 5}
stuff like this

2026-03-19T03:00:15.504399Z

I think when referring to other destructured variables the issue is it becomes brittle and order dependent, because the map doesn't really guarantee what keys will be destructured first. I believe. So I can see that being not recommended. But referring to the argument at least should work consistently. Could still be "an implementation accident" they'd rather you not rely on.

dpsutton 2026-03-19T03:02:07.302449Z

https://clojurians.slack.com/archives/C0744GXCJ/p1743795860620099?thread_ts=1743792825.545519&cid=C0744GXCJ perhaps it is just in the same map and not when referring to previously bound things

Jim Newton 2026-03-18T14:36:08.039409Z

I’m using cloverage to examine the code coverage of a suite of tests. I see the following output. What does it mean that line 1006 is yellow, and lines 1007 through 1014 are not colorized at all?

Jim Newton 2026-03-20T07:28:38.568569Z

does coverage instrument the case macro call, or does it macro expand and then wrap the case* call?

lread 2026-03-20T10:02:00.000639Z

good question, we’d have to do dig in to find out

lread 2026-03-20T18:47:29.411829Z

I think it expands and tracks macros @jimka.issy, but it can't map the expanded macro coverage back to your source code, hence the white lines.

✔️ 1
Jim Newton 2026-03-19T12:36:11.838269Z

@seancorfield whats the difference between red and uncolored? My suspicion mean that uncolored lines do not appear in the macro expansion.

seancorfield 2026-03-19T12:38:58.723949Z

Hmm, maybe. I could never get Cloverage working on our codebase at work so I didn't dig into it too deeply.

✔️ 1
Jim Newton 2026-03-19T12:39:22.669899Z

I do not know what it means to have not all branches taken. Shouldn’t that simply be implemented as branches taken in green, and branches not taken in red? Or does it mean that it is a macro which expands to code, and in that expanded code, some lines are covered and some are not?

seancorfield 2026-03-19T12:40:40.971069Z

I guess the project really does need @lee’s documentation additions! 🙂

👍🏻 1
Jim Newton 2026-03-19T14:10:43.143789Z

@seancorfield OK, so I’ve now written explicit tests for this function which explicitly exercises all three cases, asserting that I get false, true, and the default value. The tests pass, so I think that all code paths are being executed. but the coloring in cloverage is still confused. I suspect that cloverage simply doesn’t work for case or maybe it doesnt work for true and false as there’s probably no real code to execute in these case clauses???

lread 2026-03-19T14:28:33.007559Z

I haven't studied the cloverage code yet, but https://github.com/cloverage/cloverage/blob/f3954a6f2533cb0e7aab4e4b0d3e3da7facb1d47/cloverage/src/cloverage/report/html.clj#L136-L140 is probably a good hint:

(let [cls (cond (:blank?        line) "blank"
                          (:covered?      line) "covered"
                          (:partial?      line) "partial"
                          (:instrumented? line) "not-covered"
                          :else            "not-tracked")]
Combined with the https://github.com/cloverage/cloverage/blob/f3954a6f2533cb0e7aab4e4b0d3e3da7facb1d47/cloverage/src/coverage.css#L1-L22:
.covered {
    font-family:  'Bitstream Vera Sans Mono', 'Courier', monospace;
    background-color: #558B55;
}

.not-covered {
    font-family:  'Bitstream Vera Sans Mono', 'Courier', monospace;
    background-color: red;
}

.partial {
    font-family:  'Bitstream Vera Sans Mono', 'Courier', monospace;
    background-color: orange;
}

.not-tracked {
    font-family:  'Bitstream Vera Sans Mono', 'Courier', monospace;
}

.blank {
    font-family:  'Bitstream Vera Sans Mono', 'Courier', monospace;
}
My current best guess is white is blank lines & uninstrumented (not tracked) code. Red is not covered at all. Orange is partially covered ( not all branches executed) Green is covered. I agree that the true meaning of red and white seems confusing in your example above.

Jim Newton 2026-03-18T14:40:14.172149Z

Perhaps this is simply related to the macro expansion? I’ve expanded the case macro callsite and here Is what I see

(let [G__20471 satisfiability]
  (case*
   G__20471
   0
   3
   (throw
    (java.lang.IllegalArgumentException.
     (str "No matching clause: " G__20471)))
   {1 [:indeterminate default],
    2 [:satisfiable true],
    3 [:unsatisfiable false]}
   :compact
   :hash-identity
   nil))

Jim Newton 2026-03-18T14:44:26.462619Z

my guess is that the coverage analyzieris simply not able to map the code in the expanded macro back to lines of user code.

lread 2026-03-18T14:53:07.345289Z

I think it might mean partial coverage? BTW, there is also #cloverage

👍🏻 1
seancorfield 2026-03-18T15:02:19.476739Z

Yellow: partial coverage -- in this case, "not all branches" were taken. Uncolored lines: not executed. Green: executed. In this case it looks like your tests only pass through satisfiability = :indeterminate -- so nothing exercises the :unsatisfiable or :satisfiable cases. (at least, that's what Cloverage things)

lread 2026-03-18T15:16:10.772979Z

I've offered to document this for cloverage: https://github.com/cloverage/cloverage/issues/364

2026-03-18T19:02:57.815219Z

is there a good api in clojure for making terminal-ui's ?

liebs 2026-03-19T12:28:06.737509Z

Also Java with a very Java API, but it's feature-rich: https://codeberg.org/AutumnMeowMeow/jexer

p-himik 2026-03-18T19:10:19.070019Z

"Good" is subjective, but FWIW I've seen https://github.com/TimoKramer/charm.clj mentioned a few times here. bb also bundles https://github.com/jline/jline3, if you'd consider such a thing an indication of quality. It's in Java, but maybe you don't have an aversion to interop.

2026-03-18T19:21:02.218239Z

no, interop is fine for me 🙂

Shantanu Kumar 2026-03-19T00:51:39.694169Z

There's also Lanterna (Clojure wrappers exist, not sure if maintained) and (paintparty) Bling.

2026-03-19T00:53:14.950979Z

I've been using https://github.com/phronmophobic/membrane/blob/master/src/membrane/example/terminal_todo.clj but it felt very limited