This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-05-08
Channels
- # announcements (1)
- # babashka (28)
- # beginners (13)
- # calva (10)
- # clerk (18)
- # clj-on-windows (39)
- # clj-otel (1)
- # cljdoc (17)
- # clojars (12)
- # clojure (40)
- # clojure-austin (11)
- # clojure-brasil (1)
- # clojure-europe (23)
- # clojure-nl (3)
- # clojure-norway (16)
- # clojure-uk (2)
- # clojurescript (28)
- # clr (4)
- # conjure (1)
- # emacs (14)
- # hoplon (6)
- # hyperfiddle (59)
- # interop (2)
- # leiningen (1)
- # off-topic (37)
- # pathom (1)
- # polylith (5)
- # portal (7)
- # reagent (9)
- # releases (3)
- # shadow-cljs (22)
- # spacemacs (6)
- # tools-build (12)
- # tools-deps (51)
- # web-security (6)
- # xtdb (7)
What would be the most appropriate way to write a spec for a map that:
• Must have a key :x
with a long
• May have a key :y
with a string
• Has 0 or more other keys that are all vectors and point to vectors
Examples: {:x 1, :y "y", [1 2] [3]}
, {:x 2, [] [:x]}
.
The best I could come up with:
(s/def ::x integer?)
(s/def ::y string?)
(s/def ::spec (s/and (s/keys :req-un [::x] :opt-un [::y])
(s/coll-of (fn [[k v]]
(or (keyword? k)
(and (vector? k) (vector? v))))
:kind map?)
> Isn't there a map-of
spec?
Yeah, but it won't enforce "vector and vector" pairs since it doesn't correspond a particular value to a particular key. And it will ruin conforming because I'll have to use s/or
- forgot to mention but I also want for the input to remain a proper map after conforming.
> you can clean up the second part by using a conformer
What do you mean? Can you give a brief example?
Ah, it'll remove the keyword keys when I want to not only validate but also conform the value. :)
Yeah, I have my eyes on Malli (dealing with spec, even with spec-tools, hasn't been all that great) so will definitely check it out once I've got enough time.
In malli, I think it’s something like
(require '[malli.core :as m])
(require '[malli.generator :as mg])
(mg/generate
[:map
[:x :int]
[:y :string]
[::m/default
[:map-of
[:sequential :int]
[:sequential :int]]]])
Anyone ever used RabbitMQ streams in Clojure? I am struggling with advanced interop https://github.com/rabbitmq/rabbitmq-stream-java-client.
have you looked at https://github.com/michaelklishin/langohr ?
@U4GEXTNGZ Any specific issues, I did Java interop here and there, so maybe I can help you out with stuff?)
You might also want to look into https://fundingcircle.github.io/jackdaw/, solving a similar problem based on Kafka - not having worked with it, it’s hard to assess. The general idea is the same, so there might be some clever abstractions atop replicated append-only logs no matter what tech stack you’re building upon. And from those abstractions, work your way towards the rabbit-mq stream java client.
If you got a github repo wrapping the java client and meaningful tests not compiling / failing, feel free to share it.
Do we have any definitive official doc on the combo of CLJC and macros? Looking for the latest supported solutions, btw, cuz it has been evolving in good directions. I was under the impression that it had gotten as simple as, in a .CLJC file:
(ns tiltontec.cell.base
#?(:cljs (:require-macros [tiltontec.cell.base]))
...etc...)
(defn my-fn ...)
(defmacro my-macro ...)
...and then we could in another .CLJC just:
(ns tiltontec.cell.integrity
(:require
[tiltontec.cell.base
:refer [my-fn my-macro]]))
Is that the case? Or is that wishful thinking? :rolling_on_the_floor_laughing:There’s a trap for macros that return different things in clj and cljs. The reader macro for :clj
during a cljs build will be true, because cljs macros are built in clojure. This library’s readme has more info + fixes: https://github.com/cgrand/macrovich
Hmm, I have a lot of code like:
(#?(:clj ref :cljs atom) 42)
Are you saying that evaluates to (ref 42)
in CLJS?@U0PUGPSFR Do you mean inside a macro?
I removed the uses of macrovich from all my cljc libraries at some point -- I didn't think it was still an issue at this point?
No, @U04V70XH6 this would be inside a function, defined in a .cljc. Kinda vanilla usage,
macrovich
looks interesting, @U051GFP2V, thx, but right now I am just trying to see if there is a definitive Clojure/CLJC answer. I am getting diff results in figwheel vs shadow and I thought step one should be to find out the official standard.
@thheller got me sorted out, @phill. No need for a separate CLJ. This is fine in a CLJC:
(ns tiltontec.cell.base
#?(:cljs (:require-macros [tiltontec.cell.base
:refer [un-stopped without-c-dependency]]))
n.b. the explicit :refer
. That was the bit I was missing.
Now we can ditch the refer-macros
in a client:
(ns tiltontec.cell.integrity
(:require
[tiltontec.cell.base
:refer [un-stopped ....]]))
More good stuff: https://code.thheller.com/blog/shadow-cljs/2019/10/12/clojurescript-macros.html> Now we can ditch the refer-macros
in a client
It is the case with separate CLJ+CLJS files as well, even without :refer
. At least, with shadow-cljs.
Yep. I did not mean to exclude that. Thx for the clarification. 🙏 To any lurkers, the back story is that Matrix is a CLJC state management library intended for use either from CLJS or a pure CLJ app, so CLJ+CLJS would not have worked in my particular use case.
It's still fine to use CLJ+CLJS in a cross-platform project though. It's just that all cross-platform parts will have to be repeated in those files or moved to a separate CLJC file. When writing cross-platform code, I usually use CLJ files for a JVM implementation and CLJS for a JS implementation in cases when reader conditionals start wrapping whole functions instead of tiny parts of them.
@U0PUGPSFR I found the https://clojurescript.org/guides/ns-forms#_macros pretty good. I was at one point very confused by how macros worked in self-hosted ClojureScript and https://github.com/lread/info-clj-cljs-variants, but I don't think you are exploring that road...
Thx, @UE21H2HHD! That is good doc, but you are right, CLJC introduces new concerns -- I cannot just have a final CLJS target without, as @U2FRKM4TW notes, duplicating everything in a CLJ file for a CLJ app to consume. Not a maintenance joy. 🙂 So CLJC solves that, and fortunately the compilers supports that, so I can have DEFMACRO forms in a CLJC file without and the compiler (my understanding) sorts that out on its own. Life is good (and CLJC and CLJS are impressive!). 🎉
@thheller got me sorted out, @phill. No need for a separate CLJ. This is fine in a CLJC:
(ns tiltontec.cell.base
#?(:cljs (:require-macros [tiltontec.cell.base
:refer [un-stopped without-c-dependency]]))
n.b. the explicit :refer
. That was the bit I was missing.
Now we can ditch the refer-macros
in a client:
(ns tiltontec.cell.integrity
(:require
[tiltontec.cell.base
:refer [un-stopped ....]]))
More good stuff: https://code.thheller.com/blog/shadow-cljs/2019/10/12/clojurescript-macros.html