Fork me on GitHub
Banseok Yeo09:10:38

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 -

πŸ‘ 1

in clojurescript my favorite take on this is how re-frame encourages you to have pure event/effect handlers

πŸ‘ 1
Chester Bushman15:10:51

πŸ‘‹ Hello, team!

πŸ‘‹ 6

What are some reasons why I might ever want to use intern?


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.

βž• 1

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.


when you don’t control a namespace but have to modify its behaviour

πŸ‘ 1

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

🍰 1

: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?


oh, no, linters hate this sort of thing


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)

πŸ™Œ 1

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:

metal 1