Is there any way to get at the 'data representation' of a type error? It feels strange to interact with core.typed primarily by reading the std output of the typechecker, instead of being able to somehow inspect it as data at the REPL.
Any easy way of trying this out? I tried referencing it as a gitlib in my deps.edn but that didn't work
(figured it out - I cloned the repo and used :local/root)
For the gitlib, you need to depend on the checker itself. The root deps.edn is just for local dev https://github.com/typedclojure/typedclojure/blob/main/typed/clj.checker/README.md#releases-and-dependency-information
yes, I haven't ported them to typed.clojure yet but try clojure.core.typed/check-{ns,form}-info
the docstrings should describe how to use the output
hmm, I can't seem to get anything like what's printed to stderr from the return value of those functions. For example:
(clojure.core.typed/check-form-info '(+ 1 "oops"))
This prints:
Type Error (/Users/yuhan/scratch/typed_example/minimal.clj:13:40)
Function + could not be applied to arguments:
Domains:
Long :*
(t/U Double Long) :*
t/AnyInteger :*
t/Num :*
Arguments:
(t/Val 1) (t/Val "oops")
Ranges:
Long
Double
t/AnyInteger
t/Num
in:
(+ 1 "oops")
I want to obtain a data structure containing the above information, is this possible?Poking around in the returned map only gets me the location of the errors:
(-> (clojure.core.typed/check-form-info '(+ 1 "oops"))
:ex
(ex-data)
:errors
(nth 0)
(ex-data))
;; => {:type-error :clojure.core.typed.errors/type-error,
;; :env
;; {:line 15,
;; :column 44,
;; :file "/Users/yuhan/scratch/typed_example/minimal.clj"},
;; :form (+ 1 "oops")}
whereas I'm after something (isomorphic to)
{:cause "Function + could not be applied to arguments"
:form (+ 1 "oops")
:function clojure.core/+
:domains #{[Long :*]
[(t/U Double Long) :*]
[t/AnyInteger :*]
[t/Num :*]}
:arguments [(t/Val 1)
(t/Val "oops")]
:ranges #{Long
Double
t/AnyInteger
t/Num}}Ah, yes that's not available. That information is thrown away after the error msg is generated. I'll have a look at where that can be attached.
I'll have to go through all the different kinds of errors and make a data format for each.
Thanks! It would be a huge deal if users could access and manipulate that data - e.g. at the very least being able to customize the verbosity of the output format
For some more context, I'm looking to provide type-based validation and user feedback for a custom DSL, and seeing if it's possible to build it on top of some other static analysis framework like Typed Clojure or clj-kondo.
You might probably be familiar with Malli's approach towards error messages which very neatly separates the concerns into explain and humanize phases – are there technical reasons why Typed Clojure could not operate in that manner? (apart from the large amount of refactoring it would undoubtedly take)
I was a naive undergrad when I wrote it
spec was a huge revelation, but postdated this code
should be trivial to surface the information, I can do some cases now
Yup, I imagine also that this "dump info to stderr" approach is the norm for type checking facilities in most other languages, my expectation of having first-class access to the analysis data is probably a cultural thing :P
yes it was transliterated from Typed Racket.
spot on
it would be pretty cool if I could return enough information to restart type checking via a continuation with different types 🙂
but I have no idea how to do that
a little box pops up that lets you try plugging different types
Yeah - it would be nice being able to leave a placeholder and having the type checker suggest possible values to fill it in with, something you see all the time in strongly typed languages
although Clojure's probably too dynamic in general to be able to narrow things down to something useful, but it's one of my goals for the DSL which operates in a much more constrained domain
Made some progress, I'll give it a bit more thought and let you know how I go.
Amazing, thanks! I definitely wasn't expecting such quick turnaround
One more tiny bit of feedback - the entry point functions in typed.clojure could probably do with expanded docstrings explaining their arguments or linking to another var which does, eg. for t/check-ns-clj
See `typed.clj.checker/check-ns` for available keyword arguments
Made a data representation for the two most common errors https://github.com/typedclojure/typedclojure/blob/main/doc/errors.md