I’d love to have some advice from someone in debugging a subtle problem. I have a macro which expands to a fairly ugly piece of code. The first time that code evaluates, i get an error, because it does indeed have a compilation error. But if I then re-evaluate the same code, I don’t get any such error.
indeed it is not valid to use ^integer? as a type hint. However, if I re-evaluate the same piece of code, the error is not shown a second time.
Here is the complete macro expansion. rte-case/clauses-to-dfa is a normal function, not a macro.
(def f
(let [dfa__51157__auto__ (rte-case/clauses-to-dfa
'([0
(:cat
(rte
(:cat
(and :sigma :sigma)
(and :sigma :sigma)))
(and :sigma :sigma)
(and :sigma :sigma))]
[1
(:cat
(and :sigma :sigma)
(rte
(:cat
(and :sigma :sigma)
(and :sigma :sigma)))
(and :sigma :sigma))]
[2
(:cat
(and :sigma :sigma)
(and :sigma :sigma)
(rte
(:cat
(and Ratio :sigma)
(and :sigma :sigma))))]))]
(fn [& seq__51158__auto__]
(let [fns__51159__auto__ [(fn conv-1 [[^integer? a ^integer? b] c d] 12)
(fn conv-1 [a [b c] ^integer? d] 13)
(fn conv-1 [a b [^Ratio c d]] 14)]
ind__51160__auto__ (rte/match
dfa__51157__auto__
seq__51158__auto__
:promise-disjoint
true)]
(if ind__51160__auto__
(apply
(fns__51159__auto__ ind__51160__auto__)
seq__51158__auto__)
(throw
(ex-info
"No pattern matching given list"
{:sequence seq__51158__auto__})))))))uhhhh. now it gives an error every time. something really bizarre is happening.
OK, i’ll keep trying to reproduce the issue. but it’s really strange.
https://chatgpt.com/share/680b3737-c014-8007-8b8a-bf3daeb5219a
@alexyakushev, yes I already understand why the error occurs. The thing I don’t understand is why the same situation fails to trigger an error other times. I know how to fix the error when it gets reported. However, if the error fails to be reported, the user of my library will not realize that there is an error.
This is related https://clojurians.slack.com/archives/C03S1KBA2/p1745523078201339
That’s a bit strange (long (foo 1)) is that really a type hint or a type conversion?
Conversion
indeed, not a type hint at all.
however, the decompiled code is a bit surprising to me. I was under the (apparently false) impression that the type hint instructed the java compiler to create a seperate code path for the case that the argument is of type Long, which would theoretically allow the JVM to do optimizations specific to that type, but there would always be a default code path in case the run-time object is not of type Long
I discovered something weird about type-hints. A form like the following refuses (justly so) to compile. because integer? is not a valid class name
(fn [a ^integer? b [c d]] nil)
however, the following compiles fine
(fn [a b [^integer? c d]] nil)
is that expected?(fn [a ^integer? b [c d]] nil) macroexpands to (fn* ([a ^integer? b p__59939] (let [[c d] p__59939] nil)))
but (fn [a [^integer? c d]] nil) macroexpands to (fn* ([a p__59942] (let [[^integer? c d] p__59942] nil))) which further macroexpands to
(fn* ([a p__59942] (let*
[vec__59945
p__59942
^integer? c
(nth vec__59945 0 nil)
d
(nth vec__59945 1 nil)]
nil)))
Looks to me like the ^integer? gets left in the declarations vector of the let* and has no effect on the result.Ask this in #clojure as this is language level. I’m sure you will get some help there
Type hints that are not used by the compiler are just ignored. I'm not sure why it's used in your first case, maybe to determine if the function can used primitive argument ?