clojure

samwagg 2025-10-15T17:52:53.824759Z

Any thoughts on testing predicates like (is (pred? x)) vs (is (true? (pred? x)) or (is (= true (pred? x))) ? What about functions that have sort-of predicate-ish truthy semantics that may return nil? (is (not (...))) vs (is (nil? (...))) My instinct is to explicitly check for nil (this is a test after all), but I have gotten pushback in the past that it's not very idiomatic. And it does seem a little inconsistent that I tend toward is (pred? x)) or (`is (not (pred? x)))` for predicates.

p-himik 2025-10-15T18:03:15.812929Z

Why would you want to use anything apart from (is (f x)) and (is (not (f x))) if all the users of f care about is truthyness of its return value? When testing for, say, set equality, you usually just do (= #{1 2 3} x) instead of

(and
  (= #{1 2 3} x)
  (instance? clojure.lang.APersistentSet x))

seancorfield 2025-10-15T18:51:56.218649Z

It's pretty widespread convention in Clojure that predicates -- functions that end in ? -- always return strictly true or false, so maybe your tests should be (is (boolean? (pred? x))) if you want to verify it doesn't return anything else? Otherwise, as Eugene says, just (is (pred? x)) and (is (not (pred? x))) would be the idiomatic tests.

samwagg 2025-10-16T15:30:11.939689Z

Thanks for the feedback! What about functions that aren't strictly predicates, but are often used like predicates, like clojure.core/some . Obviously for the non-nil return values the exact value tends to matter. But for the nil case do you similarly use not and not nil? Looking at Clojure itself, it does seem like there are at least a few examples where nil? is used in such cases e.g. https://github.com/clojure/clojure/blob/6a4ba6aedc8575768b2fff6d9c9c7e6503a0a93a/test/clojure/test_clojure/parse.clj#L25 (in other cases, like for some itself, nils are checked explicitly, but in a context like (are (= x y)... so not exactly the same thing.)

seancorfield 2025-10-16T16:08:54.639699Z

It really depends what you're trying to test. If a function is supposed to have a specific return value given specific input, then test for that exact value. If a function is just documented to return truthy/falsey, then test (is (f ...)) and (is (not (f ...)))

seancorfield 2025-10-16T16:13:52.008729Z

For some, you'd want to test you either got nil or (pred x) for some x, where (pred x) returns truthy. So there's a particular case where (pred x) is false for each supplied x but some should return nil -- not false. So that's part of its contract.

seancorfield 2025-10-16T16:14:44.560689Z

For the most part tho', you'll just see (is expr) and (is (not expr)) in tests where only the truthiness of expr matters, rather than its actual value.

seancorfield 2025-10-16T16:18:20.079859Z

Then there are some value tests that have idiomatic alternatives in Clojure: zero? instead of = 0, true? instead of = true, false? instead of = false, (seq x) instead of (not (empty? x))

2025-10-15T23:57:51.178429Z

Hi, I'm running into an issue with clojure.data.xml 0.2.0-alpha9 where it is generating a namespace prefix for my default namespace as follows:

(require '[clojure.data.xml :as xml])
(def soapenv-ns-uri "")
(def default-ns-uri "")

(xml/alias-uri 'default-ns default-ns-uri)

(xml/emit-str
 (xml/element :soapenv:Envelope
          {:xmlns default-ns-uri
           :xmlns:soapenv soapenv-ns-uri}
          (xml/element :soapenv:Header nil)
          (xml/element :soapenv:Body nil (xml/element ::default-ns/Foo nil ["bar"]))))

"<?xml version=\"1.0\" encoding=\"UTF-8\"?><soapenv:Envelope xmlns:b=\"\" xmlns:soapenv=\"\"><soapenv:Header/><soapenv:Body><b:Foo>bar</b:Foo></soapenv:Body></soapenv:Envelope>"
Is there any way to stop it from generating the "b" prefix?

2025-10-16T00:43:29.038769Z

if you remove the b: namespace it'll be incorrect xml

Alex Miller (Clojure team) 2025-10-16T00:43:32.837659Z

There is an example of this at https://github.com/clojure/data.xml?tab=readme-ov-file#namespace-support if that helps

1
2025-10-16T00:47:10.097819Z

My use case is slightly different in that I have two namespaces. I note that the following does as expected (where only one namespace is involved):

(xml/emit-str (xml/element ::default-ns/Foo {:xmlns default-ns-uri} ["bar"]))

"\">bar"

grzm 2025-10-16T08:08:00.486019Z

I think the issue is the use of syntax like :xmlns:soapenv and :soapenv:Header instead of :xmlns/soapenv and ::soapenv/Header , as well as not providing an alias for 'soapenv.

(require '[clojure.data.xml :as xml])

(def soapenv-ns-uri "")
(def default-ns-uri "")

(xml/alias-uri 'default-ns default-ns-uri)
(xml/alias-uri 'soapenv soapenv-ns-uri)        ; <= alias-uri for soapenv

(xml/emit-str
  (xml/element ::soapenv/Envelope              ; <= ::soapenv/Envelope, not :soapenv:Envelope
               {:xmlns default-ns-uri        
                :xmlns/soapenv soapenv-ns-uri} ; <= :xmlns/soapenv, not :xmlns:soapenv
               (xml/element ::soapenv/Header nil)
               (xml/element ::soapenv/Body nil (xml/element ::default-ns/Foo nil ["bar"]))))
;; => "<?xml version=\"1.0\" encoding=\"UTF-8\"?><soapenv:Envelope xmlns=\"\" xmlns:soapenv=\"\"><soapenv:Header/><soapenv:Body><Foo>bar</Foo></soapenv:Body></soapenv:Envelope>"
I'm not quite sure why the the b prefix is getting emitted in your example, but I think what I've got is actually what you likely intended.

💯 1
grzm 2025-10-16T08:12:08.711089Z

The mapping of prefixes and aliasing of namespaces is something that often takes me a moment to think through, particularly when using alias symbols (used when namespacing element keywords) and the prefixes (used when emitting XML) are spelled the same. Here I've used different spellings to make the distinction between the two clearer:

(xml/alias-uri 'soapenv-alias soapenv-ns-uri)

(xml/emit-str
  (xml/element ::soapenv-alias/Envelope
               {:xmlns default-ns-uri
                :xmlns/SOAP-PREFIX soapenv-ns-uri}
               (xml/element ::soapenv-alias/Header nil)
               (xml/element ::soapenv-alias/Body nil (xml/element ::default-ns/Foo nil ["bar"]))))
;; => "<?xml version=\"1.0\" encoding=\"UTF-8\"?><SOAP-PREFIX:Envelope xmlns=\"\" xmlns:SOAP-PREFIX=\"\"><SOAP-PREFIX:Header/><SOAP-PREFIX:Body><Foo>bar</Foo></SOAP-PREFIX:Body></SOAP-PREFIX:Envelope>"

2025-10-16T08:50:20.169249Z

This is indeed what I was after. Thank you !!