This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-01-30
Channels
- # announcements (14)
- # aws (2)
- # beginners (167)
- # calva (25)
- # cider (124)
- # cljs-dev (2)
- # cljsrn (7)
- # clojars (2)
- # clojure (113)
- # clojure-europe (2)
- # clojure-italy (6)
- # clojure-spec (30)
- # clojure-uk (90)
- # clojurescript (20)
- # code-reviews (16)
- # cursive (28)
- # data-science (2)
- # datomic (89)
- # duct (97)
- # emacs (4)
- # figwheel-main (12)
- # fulcro (37)
- # graphql (3)
- # java (3)
- # jobs (2)
- # juxt (3)
- # kaocha (37)
- # leiningen (2)
- # luminus (2)
- # off-topic (30)
- # onyx (2)
- # pathom (3)
- # qlkit (1)
- # re-frame (7)
- # reagent (2)
- # reitit (62)
- # remote-jobs (9)
- # shadow-cljs (26)
- # tools-deps (19)
- # vim (1)
- # yada (8)
Like, if I want to get some sample data via gen/sample or gen/generate and work on qualified specs, but turn that output into plain unqualified maps?
If you know you have a flat map, with no nesting, (reduce-kv (fn [m k v] (assoc m (keyword (name k)) v)) {} my-map)
will probably do. Never mind, just realized you explicitly asked about a nested hash map. But there's an argument for not nesting maps like that...
beware that you can introduce collisions if you have something like {:database/id 4 :somethingelse/id 6}
(indeed)
also, be aware of keywords in values. {errors/ui [:error/missing-payer]}
should that become {ui [:missing-payer]}
or {ui [:error/missing-payer]}
how offended do people feel about the idea of composing server-side “components” (a la component/integrant/mount states) using hiccup?
Hi, I have a question about defmulti
and defmethod
in different namespaces. It seems that if you use defmethod
in a separate namespace from defmulti
then something in your app has to require this namespace, so defmethod
actually runs. Is this true? And if yes, is there a best practice to avoid circular dependency in this case? Can't find the answer in docs or somewhere else...
Yeah I believe all ns’es that define defmethod
s for a defmulti
must be require
d for the branches of the multi to be available
It does work when you require "branch-namespaces" but you can't require them from the namespace where defmulti
is, due to a circular dependency. Requiring them elsewhere creates an implicit dependency that will eventually break with some changes.
Kinda puzzled how to overcome this.
Right, why do you want to use the defmethod
that you are dynamically extending in the namespace that you are defining it in
could you maybe resolve that
I have few text formats that I serialize/deserialize to the filesystem. They aren't all defined at this point and will evolve as an application evolves. So, my idea was to define multimethod for every operation and implement it for each format in the separate namespace.
right, I am not challenging the use of a multimethod. What I think what could resolve your circular dependency is moving the definition of the multimethod away from its use.
Yes, but then namespace where I use the multimethod has to require both the definition and the implementation namespaces?
or am I missing something?
i don't think that's actually true. the namespace needs to require the defmulti
ns but it does not need to require the ns where the defmethod
is defined. That namespace has to have been required already, but not necessarily here.
^right, that is true, thanks for that clarification
so you could require all of the implementing namespaces in your start up and be assured that they are all ready to go
that will solve the problem, I'm just concerned that later someone can remove this "require" because they won't be explicitly used in startup namespace.
That what I meant by implicit dependency.
Also, I think my suggestion would work, I would have a ns use
that depends on the namespace define
+ all namespaces extend
, where each extend
namespace depends on define
. I don’t think there is a circular dependency there, but I am lacking some paper to draw it out ^^
If there is no better way, I can live with this solution of course.
Yes, that will work. Thanks, @lennart.buit and @dpsutton
hey i have a question about letfn
as i search around, i knew that letfn
is for use of function that is not defined yet. (something like mutual recursion)
but, if i try mutual recursion with let
, it perfectly works!
why does this work?
(let [odd? (fn [n]
(if (zero? n)
false
(even? (- n 1))))
even? (fn [n]
(if (zero? n)
true
(odd? (- n 1))))]
(odd? 5))
so if letfn
supports ahead-of-defintion use of function and let
doesn't that code shouldn't work
i got it
btw, then letfn
doesn't use existing function if there is definition in it?
gonna play with repl 🙂
yup it ignores existing function
(letfn
[(odd? [x] (even? x))
(even? [x] true)]
(odd? 5))
;= true
it has weird naming but nvm
Hi. I am looking for an elegant way to construct a map based on multiple conditions. This is what I have:
(defn build-foo []
(let [m {}
m (if cond-1?
(merge m {:foo 1 :bar 2})
m)
m (if cond-2?
(merge m {:x 1 :y 2})
m)]
;; continue with cond-3 ... cond-n
m))
(use three backticks to format code spanning multiple lines)
(cond-> m (foo? x) (assoc ....) (bar? y) (assoc ..))
or (cond-> m (foo? x) (conj ....) (bar? y) (conj ..))
imho merging with (only) 2 args is quite often a smell, especially when you are sure the first arg is a map (non nil)
Hm, so it seems clojure.trace/trace-ns
doesn't accept a namespace as a string. I currently have a list of namespaces in a list with strings. I would like to pass them to trace-ns
inside a doseq
, but always get "No namespace: n found" (`n` is the name of my variable, seems trace-ns
doesn't read the value of the var but instead the symbol itself)
user=> (find-ns (symbol "user"))
#object[clojure.lang.Namespace 0x386f0da3 "user"]
user=> *ns*
#object[clojure.lang.Namespace 0x386f0da3 "user"]
So it probably works when you map symbol
over your list of strings
(map symbol namespaces)
hi folks, I have a clojure project that has been packaged with lein jar
, how do I run it? 😄 I've only ever used lein uberjar
are you running it with lein or separately? if the former, lein run probably does the right thing. if the latter, you need to include the jar and all transitive dependency jars on the java classpath, then run the main class. java -cp my.jar:foo.jar:bar.jar my.mainns
I am using lein. Does lein run
use java classes in :java-source-paths
? I was thinking the instruction to use lein jar
(from the creator of the project) was to also include a separate java class.
I think lein run includes the class output target dir in its path and Clojure will use the classes if it finds them (before the .clj)
oh, sorry you asked about java classes
I would expect it to only find java classes in the target output, not in java source paths
I have a vector of hash-maps that I wish to namespace qualify, and I'm curious about how to do this idiomatically (`(map #(reduce-kv ...))`?), and why the first example here does not work:
(reduce-kv #(assoc %1 #:ns{%2 %3}) {} {:k "v"}) ;; => CompilerException java.lang.RuntimeException: No such namespace: ns etc..
(reduce-kv #(assoc %1 :ns/%2 %3) {} {:k "v"}) ;; => #:ns{:%2 "v"}
(reduce-kv #(assoc %1 (keyword "ns" (name %2)) %3) {} {:k "v"}) ;; => #:ns{:k "v"}
the #:ns{} syntax is a literal map syntax. that is, it’s not a property of the map, it’s just a syntactic alternative when writing literal maps.
similarly, :ns/%2 is a keyword whose name is literally %2
both of these are things happening at read time, with no eval
the last one seems like a fine solution
there are some common utility functions (often called map-keys
or map-vals
) that apply a function to all of the keys or vals of a map and that might be an easier way to think about it. You can find those functions in many of the utility libs (medley, useful, etc)
something like (map-keys {:k "v"} #(keyword "ns" (name %)))
excellent, thank you
Is there any way to get a list of loadable classes on the classpath easily without relying on a library like compliment
? The code in compliment
is surprisingly complicated and this feels like something that the JVM should be able to do natively via the Classloader interfaces or something?
classloaders generally don’t have a notion of what can be loaded, just what has been loaded
the classloader interface intentionally abstracts the notion of “where classes come from” and they could come over the network where there is no way to enumerate them all
or out of a database (I did one of those once)
Hi all. I have a problem in my application. Some sort of classloader memory leak. I see that amount of classes is constantly increasing and heap dump is dominated by entries like clojure.core$eval100009
with no instances. How can I figureout what is generating this classes?
but not explicitly apparenlty. My code have only one call to eval and it is not in any sort of tight loop...
I would drop any library that uses eval outside some sort of start-up DI type scenario, runtime eval is a code smell
you can (for debugging / local purposes only) replace clojure.core/eval with a function that logs stats about usage (including stack trace) then calls the real eval
regarding how to replace eval with logging version, alter-var-root
is pretty straightforward to use
yes, functions compile to code that looks up vars - the gotcha is if eval was provided as an arg to a first class function - which is rare
agreed with @hiredman and logging eval usage would expose that this is the issue as well
I doublechecked my usage of eval - it only happen once during initial app compilation
and a caveat that Clojure core itself is direct linked compiled so calls within core won’t see changes from alter-var-root
(ins)user=> (alter-var-root #'eval (fn [v] (fn [& args] (println "calling eval on" (pr-str args)) (apply v args))))
#object[user$eval151$fn__152$fn__153 0x158a3b2e "user$eval151$fn__152$fn__153@158a3b2e"]
(ins)user=> (eval '(+ 1 1))
calling eval on ((+ 1 1))
2
@alexmiller true but I think we can trust that clojure.core isn't using eval in a sloppy way
@noisesmith let me try that
Java profilers can also help you with stuff like this (YourKit, JProfiler, etc)
I found what is causing my issue. Thanks @noisesmith. Now have to think how to avoid that. Btw culprit is dynamic sql generator from yesql
I would be surprised if whatever yesql is doing couldn't be replaced by a higher order function rather than using eval, I'm disappointed to hear it's doing things that way
also, hugsql is newer and supposedly addresses some design issues from yesql
(but works similarly)
even yesql's readme mentions hugsql and the fact that hugsql is actively maintained unlike yesql
Well, problem is little bit deeper than yesql. I attached template engine (comb) to yesql that give me dynamic sql generation (yesql can't do that out of the box) and this lib is actually main culprit. I like this feature a lot, though I need to use it more carefully because of this problem... Hugsql is way too much rewrite for me, maybe I'll consider this later
maybe walkable? http://walkable.gitlab.io/
@alexmiller Ah that's interesting. I guess that's why compliment
has all the code it has for finding jars and class directories and such and just lists them?