Fork me on GitHub
#clojure
<
2024-01-01
>
Alex Shulgin17:01:03

Is it possible (or good idea in the first place) to try and catch Clojure compiler exceptions (in tests)? This doesn't seem to work, the exception is not caught:

(eval '(try
         xxx
         (catch Exception e
           e)))

Alex Shulgin17:01:03

(as opposed to (/ 1 0) — that one is caught, as it's runtime)

p-himik17:01:05

Move eval inside try. So it's (eval 'xxx).

Alex Shulgin17:01:29

It worked 👍

Alex Shulgin17:01:59

Do you think it's a good/valid approach to testing macros when they expected to blow up on invalid input?

p-himik17:01:45

Probably, I can't think of any issues with that.

Alex Shulgin17:01:13

Thanks a ton! 🙂

👍 1
phronmophobic17:01:47

I think a better approach is to isolate the data part of the macro. I often start writing my macros using the following form:

(defn my-macro* [args]
  ;; actual logic
  )
(defmacro my-macro [& args]
  (my-macro* args))
It makes life a lot easier.

☝️ 2
phronmophobic17:01:19

In many cases, you can just test my-macro*. It makes writing macros much easier.

p-himik17:01:59

But it won't help that much with testing for compiler errors. Stuff like (let [x]).

Alex Shulgin17:01:38

Sure, my actual defmacro is already a one-liner, all logic is in functions. So the actual question is: does it make sense to have an explicit test for when the macro is supplied with unexpected input that it results in a (nice, expected) exception?

p-himik17:01:30

If it's a nice and expected exception, then it's probably not a compiler exception. In that case, it's a check in one of the functions that you control that you used in that macro. So it would make sense to test those functions instead, without any eval.

1
Alex Shulgin17:01:15

That makes sense, thank you.

Alex Shulgin17:01:14

When using deftest / is how do you approach tests for truthiness? The true?/`false?` preds are actually only for booleans, so nil is not recognized as falsey.

hiredman18:01:02

is is itself an assertion of truthiness (technically that is the default condition of is, it actually comes down to a multimethod where you can add custom kinds of assertions)

2
hiredman18:01:23

if x is a truthy value (is x)

Nundrum22:01:11

Can someone explain why read-string fails on a keyword such as ":@id"? That particular combo doesn't seem to be covered in the "weird characters" page. I'm fetching some JSON data and Cheshire will gladly keywordize "@id" into :@id but then saving/reading that from edn fails. I can work around that, but wanted to understand what is happening.

; eval (current-form): (read-string (str {(keyword "@id") 1}))                       
;  (err) java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

hiredman22:01:52

the set of keywords that the reader will read is significantly smaller than the set of keywords that you can create using something like the clojure.core/keyword function (which is what cheshire uses)

hiredman22:01:46

str is also not the best way to serialize things to be read later, that is pr-str (similar to the diff between println and prn)

Nundrum22:01:24

Right, I have run into the keyword problem before. Just can't figure out why the @ is not allowed or what the reader is doing with it.

hiredman22:01:28

https://clojure.org/reference/reader#_literals has a section on what is allowed in a literal (a readable) keyword

hiredman22:01:50

https://clojure.org/reference/reader#_symbols is the section on symbols which is referenced by the keyword section

hiredman22:01:16

in particular > Symbols begin with a non-numeric character and can contain alphanumeric characters and *, +, !, -, _, ', ?, <, > and = (other characters may be allowed eventually).

hiredman22:01:11

there have been extension proposed to allow for printing and reading otherwise unreadable symbols and keywords, but nothing has been actually implemented

Nundrum22:01:25

Ahhh "a keyword is like a symbol"

Alex Miller (Clojure team)22:01:53

specifically here, @ is a token delimiter in the reader, so it's trying to parse ":" as a symbol or keyword