This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-10-14
Channels
- # announcements (7)
- # aws (1)
- # babashka (1)
- # beginners (19)
- # calva (9)
- # clj-commons (4)
- # clj-kondo (64)
- # clj-on-windows (27)
- # cljsrn (12)
- # clojure (127)
- # clojure-bay-area (3)
- # clojure-europe (25)
- # clojure-hungary (7)
- # clojure-nl (1)
- # clojure-norway (9)
- # clojure-spec (5)
- # clojure-survey (2)
- # clojure-uk (22)
- # community-development (5)
- # core-async (19)
- # cursive (29)
- # datascript (8)
- # events (1)
- # fulcro (2)
- # graalvm (3)
- # jobs (1)
- # lsp (155)
- # malli (18)
- # nbb (6)
- # off-topic (86)
- # pathom (2)
- # rdf (18)
- # re-frame (9)
- # releases (2)
- # scittle (24)
- # shadow-cljs (33)
- # xtdb (4)
Hello, How can I implement an async side effect as a pure function in Clojure? (Like wrapping async side effects in monad in other functional languages)
there are some libraries for that for example - https://github.com/adambard/failjure
in clojurescript my favorite take on this is how re-frame encourages you to have pure event/effect handlers
Sorry this does not fully answer your question (others might have use cases they can supply), but in most Clojure application code, no reason at all.
If you are adding features to Clojure itself, and/or developing IDE kinds of tools, or Clojure debug utilities, maybe then it might come in handy sometimes.
in our braintree code at work we have
(doseq [^java.lang.reflect.Field field (.getDeclaredFields Transaction$Status)
:when (not= "$VALUES" (.getName field))
:let [value (.get field nil)
predicate-name (symbol (str "transaction-" (.replaceAll (.toLowerCase (.getName field)) "_" "-")
"?"))]]
(intern *ns* predicate-name (fn [^Transaction braintree-transaction]
(= value (.getStatus braintree-transaction)))))
which generates predicates for all the transaction statuses:thinking_face: So, I guess it's letting you dynamically create a var name from a value?
dynamically is a little vague, it is a top level form in a file, so it is running at code load time
we also have a more complicated case that generates tests (programatically making the same things deftest makes, which interning is part of) for different possible states of a google play subscription. I dont entirely recall why that makes different tests instead of doing a doseq in a single test, but I think it was to take advantage of existing fixtures that reset shared state between tests
Well, I guess I just mean that (def some-name some-value)
doesn't really offer a way for some-name
to be anything other than literally some-name
, while by interning you can generate the name and fill it in.
Doesn't seem like the linter would be very happy about this though. Are you able to get clj-kondo
to recognize the new symbols when you use them?
if you would use a macro to write a def, you can use intern instead. sometimes one is better than the other (a macro has limitations that functions do not)
I use intern
in expectations.clojure.test
to "import" several Vars from clojure.test
into Expectations, preserving metadata etc (with Imported from clojure.test
appended to the docstring!), so that users of Expectations don't need to require
clojure.test
to get at those useful functions: https://github.com/clojure-expectations/clojure-test/blob/develop/src/expectations/clojure/test.cljc#L540-L566
