This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-05-02
Channels
- # announcements (2)
- # babashka (9)
- # calva (8)
- # cider (2)
- # clj-kondo (3)
- # clojure (113)
- # clojure-austin (1)
- # clojure-dev (27)
- # clojure-europe (11)
- # clojure-germany (2)
- # clojure-losangeles (1)
- # clojure-nl (1)
- # clojure-norway (18)
- # clojure-uk (32)
- # clojuredesign-podcast (4)
- # core-async (16)
- # core-typed (45)
- # cursive (5)
- # data-science (1)
- # datomic (7)
- # events (1)
- # gratitude (2)
- # hugsql (1)
- # hyperfiddle (7)
- # integrant (4)
- # keechma (10)
- # leiningen (4)
- # malli (1)
- # missionary (14)
- # off-topic (62)
- # onyx (8)
- # other-languages (21)
- # pathom (1)
- # reitit (4)
- # releases (2)
- # shadow-cljs (35)
- # squint (1)
- # transit (1)
Did t/Merge
get removed from the library? I have tried using it from typed.clojure
and from clojure.core.typed
and in each case I am getting an error that it cannot resolve it. Specifically "Cannot resolve type: t/Merge"
It should work, the parsing case is there https://github.com/typedclojure/typedclojure/blob/baf4861ab43dbac4b871455e3bf075b34866fa69/typed/clj.checker/src/typed/clj/checker/parse_unparse.clj#L456
(deftest Merge-test
(is-tc-e nil (t/Merge))
(is-tc-err {} (t/Merge))
(is-tc-e {:a 1} (t/Merge '{:a t/Int}))
(is-tc-err {:a :a} (t/Merge '{:a t/Int}))
(is-tc-e {:a 1 :b true} (t/Merge '{:a t/Int} '{:b t/Bool}))
(is-tc-err {:a 1 :b 1} (t/Merge '{:a t/Int} '{:b t/Bool}))
(is-tc-e {:a true} (t/Merge '{:a t/Int} '{:a t/Bool}))
(is-tc-err {:a 1} (t/Merge '{:a t/Int} '{:a t/Bool})))
I'm trying to use it inside of a defalias would that be why?
I'm also using macros like this for calls to pred as so. (defmacro mytype? [x]
((tyc/pred MyType) ~x))` I am doing it like that because I wanted to shorten those checks and if I do it as a def
it doesn't seem to type check. Let me know if there is a better way to do that. Thanks
Oh ok that sounds great i'll try that instead of macros
BTW I forgot that I had integrated runtime checking with Malli. It doesn't cover all types, but it's another alternative to pred
that the type checker understands https://github.com/typedclojure/typedclojure/blob/main/typed/malli/src/typed/malli.clj
it also can parse
values (`conform` in spec). I think in the future I'll be fleshing out this integration.
examples https://github.com/typedclojure/typedclojure/blob/main/typed/malli/test/typed_test/malli.clj
Oh interesting I think I stumbled across that once. Whats the benefit of that vs just using pred?
Also, do you know the best way to supress the unresolved symbol errors kondo complains about when using pred in a def
Ik you can suppress it per form but I was wondering if you know of a way to do it globally for any calls to t/pred for instance
malli has more features like parse
(is (= [:int 1]
(sut/parse (t/U ^{::sut/name :int} t/AnyInteger
^{::sut/name :bool} t/Bool)
1)))
(is (= [:bool true]
(sut/parse (t/U ^{::sut/name :int} t/AnyInteger
^{::sut/name :bool} t/Bool)
true))))
As for clj-kondo, try some things in this document. https://github.com/clj-kondo/clj-kondo/blob/master/doc/config.md#config-in-call
perhaps: {:config-in-call {clojure.core.typed/pred {:ignore [:unresolved-symbol]}}}
That worked perfectly thanks
I'll think about how to add proper support for type aliases with clj-kondo. malli just spits out a static file that clj-kondo can consume, I might do that.
looks like I forgot to add native clj-kondo support for pred, could you open an issue to remind me?
I'm trying to use t/Merge
like so:
(t/defalias UserWithMore
(t/Merge
User
(t/HMap :mandatory {:extra-field1 t/Int :extra-field2 t/Int} :complete? true)))
Then I get "Syntax error macroexpanding tyc/pred" in the pred function I made for that type. This is using the def as well not a macro for the pred
Start checking mynamespace
Syntax error macroexpanding tyc/pred at (file:myfile.clj:174:28).
Found errors
Subprocess failed (exit code: 1)
Thats really all it says
Ok, I'm guessing pred doesn't support Merge. This is probably one of those things that is easy to add support for in typed.malli but a pain for pred.
Hmm ok do you think I should try out the typed Malli approach? I would just use that validate function instead of pred right?
Not really, I think it has even less coverage at the moment. I'll experiment a bit and see if I can make it more useful.
Ok thanks I mean ideally I’d just use pred but if you think it’s too much to add merge support into it I am open to using something else in its place just let me know what you think would be my best option. And for now I’ll just not use merge yet.
Is there any other way I can let the type checker know that i'm returning a map of a certain type? Or is t/pred
the standard way to do so?
@U034ELFSHPS there's lots of ways. t/pred
is just the safest, since it's backed by runtime checks.
Yeah I prefer t/pred
vs those options but good to know about. Thanks.
Also, is there any way to do a generic Result type like in Rust? I know you can simulate a concrete Result Type like (t/U t/Int MyError) but I was wondering if theres any way to make a generic Result type or if its best to use a different approach.
you would use a tagged union in this case.
(defalias Result (TFn [x] (U '{:op ':Ok :result x} '{:op ':Err}))
Ok cool I haven't explored that feature yet looks pretty useful though. How would I return an Ok variant or Err variant from a function? Essentially how do I construct one of those Result types
Interesting i'll try this out
I'm trying this out now and I care about the error so I made the type like this.
(t/defalias Result (t/TFn [x] (t/U '{:op ':Ok :result x} '{:op ':Err :error x})))
However, the type checker cannot resolve it for some reason when I construct it like {:op :Ok :result any-value}
or {:op :Err :result any-error}
.
I get errors like:
Type mismatch:
Expected: my-ns/Result
Actual: (t/HMap :mandatory {:result nil, :op (t/Val :Ok)} :complete? true)
in:
{:op :Ok, :result (:message-id response)}
Type mismatch:
Expected: my-ns/Result
Actual: (t/HMap :mandatory {:op (t/Val :Err), :result String} :complete? true)
in:
{:op :Err, :result full-error}
Type mismatch:
Expected: my-ns/Result
Actual: (t/HMap :mandatory {:result t/Any, :op (t/Val :Ok)} :complete? true)
in:
{:op :Ok, :result result}
And my-ns/Result is just an alias over the result type like (t/defalias Result types/Result)
just so its shorter.
I normally make all my types using HMap and not the short form syntax so I think that is where some of the issues may be. Thanks for any help.I also have never used t/TFn
before so that may be part of the problem as well
Result
here is a "type function", in this case a function that takes a type x
and returns a union type.
Ok cool i figured it was due to me not knowing fully how that works let me test some more