Fork me on GitHub
#cljs-dev
<
2022-11-16
>
borkdude17:11:10

While fixing something in clj-kondo, I discovered that in .cljs code Exception and String are not found as an unresolved symbol (due to a bug in kondo). I fixed that, but I'm left with some examples like:

(defn foo ^String [x] x)
which does compile in .cljs correctly but I'm not sure if String should be reported here as unresolved. I think in this case it's clear:
(defn wrap-baz [^java.io.File x] (.getName x))
java.io.File
should be reported as something not known in CLJS (although the CLJS compiler doesn't complain on unknown types in hints), but I don't know if String has any special meaning in the CLJS compiler or shadow-cljs. I'm now leaning towards "it's not known in CLJS, so report" but let me know if it should be otherwise

borkdude17:11:11

This happens mostly in .cljc files , so maybe since CLJS is forgiving, the linter should not complain about unknown types in type hints either as far as CLJS is concerned?

thheller18:11:26

IIRC if the resolve fails its just treated as unknown and ignored

borkdude18:11:32

And there is a deliberate choice of not reporting, like e.g. in

cljs.user=> (def x String)
                   ^
WARNING: Use of undeclared Var cljs.user/String at line 1
? Perhaps to make it more convenient to write code in .cljc files?

thheller18:11:22

resolving tags is different than resolving actual code, since JS is so dynamic knowing the actual class is not really important since there is no such thing as reflection

borkdude18:11:19

but users making typos could result in wrong inference?

thheller18:11:21

so in CLJ it is required and used. in CLJS it is optional. any none js tag has no impact on inference

mikerod18:11:31

What would be the use of the tag if it is not going to impact inference or externs? Is it just fully useless on cljs without a js?

thheller19:11:50

not sure I understand the question?

mikerod02:11:21

A tag of something like ^Thing in cljs doesn’t do anything ?

thheller04:11:09

well it does tell the compiler the type of something, but since JS has no types that doesn't really do much at all

thheller04:11:48

in CLJ the type is required since it can directly emit a function call or so. if the type is not known it has to use reflection to call something, figuring stuff out at runtime

thheller04:11:10

in CLJS that doesn't matter since you can just emit a direct function call either way

thheller05:11:47

it can have impacts on protocol calls though. so its not totally useless in certain places, but often it does nothing

mikerod06:11:41

Thanks. That is helpful. I am familiar with clj and the jvm. I know js is more flexible in this regard. But good to understand the nuance.

borkdude18:11:16

there is also a ^clj tag right?

thheller18:11:10

not sure if this is an official tag. don't think so, meaning it doesn't have special meaning besides making externs inference warnings shut up

borkdude18:11:50

right. I thought I'd seen it in the wild but then that may be the de facto way of disabling those warnings - thanks

thheller18:11:37

I might be wrong on this though. there is clj-nil for sure with meaning in the analyzer, just not sure about clj. I just use it to shut up externs inference

borkdude18:11:46

I thought I'd also seen ^number somewhere

thheller18:11:37

numeric IIRC

thheller18:11:59

^not-native also exists and has special meaning

thheller18:11:13

ok its number then

borkdude18:11:04

The not-native type hint works in CLJS in clj-kondo because it's also something in CLJS core

cljs.user=> (doc not-native)
-------------------------
cljs.core/not-native
  nil

borkdude18:11:15

number and js are specially supported

borkdude18:11:15

I'll just make clj-kondo more relaxed about these type hints in CLJS so at least you don't have to branch out in .cljc files to "undo" JVM type hints

1
borkdude18:11:39

which was already the case, but now as a feature instead of a bug ;)

borkdude18:11:54

but hmm, adding JVM type hints in a .cljc file may have the undesirable effect of accidentally adding externs by inference in .cljs right?

borkdude18:11:31

not that anyone will probably have ever noticed this

thheller19:11:59

I'd say thats unlikely given that only js hints add externs

dnolen19:11:53

summary of the above sounds right to me

🙏 2