Fork me on GitHub
#clojure-dev
<
2018-08-27
>
slipset09:08:50

@mfikes has been doing a lot of type-inference in cljs lately,

slipset09:08:02

and thinking of his work and seeing this:

slipset09:08:22

11:26 $ clj
Clojure 1.9.0
user=> (set! *warn-on-reflection* true)
true
user=> (let [x :foo]
(if (string? x)
   (.startsWith x "lol")
   (prn x)))
Reflection warning, NO_SOURCE_PATH:4:4 - call to method startsWith on clojure.lang.Keyword can't be resolved (no such method).
:foo
nil

slipset09:08:34

Sort of surprised me, since we know that the only way we can reach the (.startsWith...) is if x is a String?

mpenet09:08:28

runtime vs compile time

schmee09:08:44

AFAIK, the clj and cljs compiler don’t do data-flow analysis

slipset09:08:59

@schmee the reason I ask is because of the current cljs-tickets @mfikes has been working on, like https://dev.clojure.org/jira/browse/CLJS-2873, which indicates that there is type inference at play.

👍 4
cfleming10:08:58

Clojure only really does what I would call type propagation rather than inference, and only for Java interop.

cfleming10:08:36

It doesn’t do any flow/occurrence typing, which would be required for the (if (string? x) ...) example.

cfleming10:08:16

Which is a shame, Kotlin does use it and it’s really nice. It’s less necessary in Clojure because it’s dynamically typed, but it would allow eliding more type hints in cases such as the string? example.

slipset17:08:06

Which is exactly how I found this example, I was a bit surprised that I had to type hint that code.