This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-07-28
Channels
- # announcements (12)
- # babashka (87)
- # beginners (84)
- # calva (22)
- # circleci (4)
- # clj-kondo (46)
- # cljdoc (6)
- # cljsrn (15)
- # clojure (87)
- # clojure-europe (18)
- # clojure-uk (7)
- # clojurescript (20)
- # community-development (3)
- # conjure (1)
- # cursive (13)
- # datomic (14)
- # events (7)
- # fulcro (27)
- # graphql (31)
- # helix (8)
- # jobs-discuss (1)
- # lsp (43)
- # malli (11)
- # meander (64)
- # off-topic (7)
- # pathom (26)
- # polylith (9)
- # practicalli (2)
- # re-frame (33)
- # reagent (2)
- # reitit (5)
- # releases (2)
- # rewrite-clj (2)
- # shadow-cljs (69)
- # specter (5)
- # sql (1)
- # tools-deps (85)
- # tree-sitter (1)
- # vim (3)
I saw somewhere that *ns*
isn't bound during AOT compilation but I'm wondering if that's true.
In particular, def
's docstring says:
> Creates and interns a global var with the name
> of symbol in the current namespace (*ns*) or locates such a var if
So I guess it must be set?
The compiler seems to be setting *ns*
here: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L7696 (called here: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L7875)
My use case is that I want to automatically define vars based on their "definitions" in a hashmap instead of manually calling def
.
I wanted to use (intern *ns* ...
for that purpose
Something like:
(def config-keys {:key1 {} :key2 {}})
(defn- intern-config-var [[config-key _]]
(intern *ns*
(symbol (name config-key))
(read-env config-key)))
(run! intern-config-var config-keys)
which should produce vars key1
, key2
, etc.A common trick is to have (def my-ns *ns*)
at the top of the namespace and then use my-ns
subsequently.
That way my-ns
is defined to be the actual namespace (at load/compile time) rather than whatever *ns*
is bound to at run time.
So given that I'm calling this immediately (the last line) as a top-level form there shouldn't be any difference, right?
When would this be a problem? If intern-config-var
was public and called from another ns?
The tricky thing is compilation and runtime are interleaved in such a way that people often expect *ns*
to have the same value at runtime as it has at compile time, which is basically only the case in the repl
Maybe not clojure-specific, but anyone has a clever trick for caching Maven dependencies that will survive unrelated changes to project.clj / deps.edn?
mmm, I had forgotten about this https://grep.app/search?q=fallback%20to%20using%20the%20latest%20cache%20if%20no%20exact%20match%20is%20found that's the answer. I think I had worked for a while on projects not featuring that snippet
Tying the maven cache to the sha of the dependencies seems silly. You should share the same m2 everywhere for every build as much as possible
With a high churn in dependencies the cache will be indefinitely growing though. I encountered problems with this in a js project a while back. Restoring the cache took more time than downloading the dependencies at some point. The workaround was including a timestamp in the cache-key.
(clojure.edn/read (
try this
class java.io.BufferedReader cannot be cast to class java.io.PushbackReader (java.io.BufferedReader and java.io.PushbackReader are in module java.base of loader 'bootstrap')
One more level of wrapping might help. PushbackReader constructor instantiates from a Reader - a quick scan of the class shows.
While this works - do you need the inner-most PushbackInputStream? I think the reader can take the httpkit object - which I believe extends InputStream
the documentation of cl-format claims that it is fully compatible with the CL version of format. However, in CL the ~A
directive (print aesthetically) pretty-prints the corresponding argument. For example (format out "~A" some-list)
outputs the same as (pprint some-list out)
However in clojure (cl-format out "~A" some-list)
outputs the contents of some-list all on a single line. Does anyone know whether it is possible to make this work correctly? I've seen the dynamic variable *print-pretty*
which seems to have no effect on ~A
if not, is there a way to tell the default format
to print the corresponding argument as if by pprint
?
according to line 1338 of cl_format.clj
it seems ~A
dispatches to print-str
rather than to some form of pprint-to-str
.. I suspect that is a bug, because I don't see any comment there explaining how the pretty-printer is intended to be triggered here.
It seems like it should use something like (fn [data] (with-out-str (pprint data))
rather than print-str
At this point, it seems like making a post on https://ask.clojure.org/ would be worth it.
voila: https://ask.clojure.org/index.php/10856/bug-format-that-does-not-pretty-print-corresponding-argument
i want to add user keybindings to my emacs config for reloading/starting/stopping my integrant system. cider does not seem to expose any non-interactive functions for evaluating a clojure form. I want an emacs script that finds the system ns and evaluates the start/stop methods. how do i do this?
in other words, i want to be able to do all the cider interactive stuff non-interactively (programmatically in elisp)
Set that in .dir-locals.el and you can ‘hook’ into cider-refresh to stop and start your system
Is there an up-to-date core.cache adapter for Redis? I tried https://github.com/strongh/crache, but that doesn't work with the current Clojure version anymore
TIL about the lib :) last commit isn't too distant so I think the right thing in this case is opening an issue with a repro
I ended up fixing the namespace, updating the dependencies, and opening a pull request 🙂
I’ve got a namespace with this var declaration:
(def yy protocols/ApiAuth)
I start REPL which loads this namespace. I do absolutely no reloads of any kind. And yet:
(identical? yy protocols/ApiAuth)
=> false
how is this possiblewhat does protocols/ApiAuth eval to? I'm assuming a protocol?
I’ve been running into a bit of trouble with protocols lately, and I know that I need to have a clean target folder and if I reload the namespace with the protocol I need to reload all the namespaces with protocol implementations, but this one has been baffling. When I start REPL about a 100 namespaces get loaded due to being included from the core one. It seems that same protocol gets defined multiple times which is odd
protocols are just maps, so you could compare them with clojure.data/diff to find things that are different. I'm guessing the :on key (the interface class) is different
oddly:
(identical? (:on yy) (:on protocols/ApiAuth))
=> true
(identical? yy protocols/ApiAuth)
=> false
well, it was just a guess. you can use clojure.data/diff to narrow it down
I mean, the protocol gets updated as it gets extended, so you might be seeing an older version vs a newer version with different extensions
ah… maybe that’s the problem with my code
(s/def ::auth-token (partial satisfies? protocols/ApiAuth))
when you def yy, you're just getting a point in time, not tracking updates
that spec fails for objects it shouldn’t fail for
I am guess it closes over a version of protocol without the necessary implementations in the map
maybe? you might be better with using an anonymous function there instead so you're not evaluating early
#(satisfies? protocols/ApiAuth %)
worth a try
yeah that works as expected
Yeah, I recently encountered the same thing, using an anonymous function fixed it
well this is definitely a gotcha for most people
if you want to request a FAQ for it, please do... https://github.com/clojure/clojure-site/issues
I think https://clojure.atlassian.net/browse/CLJ-2094 describes the same scenario, would you agree @U66G3SGP5?
(https://clojure.atlassian.net/browse/CLJ-1814 also relates, but from a performance point of view I guess)
it’s not a problem that it works that way, but it’s definitely unexpected by most
I think partial behaviour is not poorly described. What is surprising is that extending a protocol produces a new value…. in most languages type identifiers are immutable singletons and as most people grok protocols as some sort of type/interface abstraction, they get blindsided by this “type” identifier changing as new implementations are defined.
I think that's a good insight. There are two "stateful" runtime constructs in Clojure - protocols and multimethods. As Clojurists we should not be surprised that state creates problems (like temporal coupling)
but you can't have open dispatch systems without managing state over time to allow for late behavior extension
I do think it is not immediately obvious what the tradeoff is in partial vs anon fn wrt evaluation and closures and that probably warrants a faq entry
yeah, I guess there are two different things here (which may or may not be obvious depending on your level of expertise): a) why (partial foo bar) isn't the same as a similar anonymous function (I'd guess this also applies to other HoF's too, like comp) and b) the value of a protocol may change when it's extended
I remember encountering the a) issue when adding instrumentation to a function foo
, but had already defined some helpers with partial e.g. (def helper (partial foo 1))
-> calling helper
with some incorrect args wouldn't trigger an instrumentation failure
(identical? (:on yy) (:on protocols/ApiAuth))
Hi , I am sending this data in body in a put api
[{"topic":"xyz", "key":"abc", "message": "pqr"}]
I need to parse these params at handler one by one. Can someone suggest the cleanest way to do it?build=> (require '[clojure.data.json :as json])
nil
build=> (json/read-str "[{\"topic\":\"xyz\", \"key\":\"abc\", \"message\": \"pqr\"}]")
[{"topic" "xyz", "key" "abc", "message" "pqr"}]
(defn myFunc
[{:keys [params]}]
(let [
topic (:topic params)
key (:key params)
message (:message params)
])
)
Need to add the for loop to this(defn foo [{{:strs [topic key message]} :params}]
[topic key message])
(foo {:params {"topic" "t" "key" "k" "message" "msg"}})
#_-> ["t" "k" "msg"]
[ {"topic":"xyz", "key":"abc", "message": "pqr"}, {"topic":"xyz1", "key":"abc1", "message": "pqr1"}, {"topic":"xyz2", "key":"abc2", "message": "pqr2"}] ] Would it run for this one?
generally, figure out how to make a function that takes one map with topic, key, and message, and then figure out how to do it multiple times