This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-01-25
Channels
- # aleph (12)
- # announcements (2)
- # beginners (40)
- # calva (8)
- # cider (26)
- # cljs-dev (71)
- # cljsrn (2)
- # clojure (122)
- # clojure-dev (9)
- # clojure-europe (2)
- # clojure-nl (2)
- # clojure-spec (42)
- # clojure-uk (20)
- # clojurescript (86)
- # cursive (15)
- # data-science (1)
- # datomic (42)
- # duct (4)
- # emacs (33)
- # events (1)
- # figwheel-main (2)
- # fulcro (33)
- # jobs (2)
- # jobs-discuss (46)
- # kaocha (13)
- # leiningen (9)
- # off-topic (62)
- # pathom (75)
- # quil (2)
- # re-frame (6)
- # reagent (13)
- # reitit (3)
- # shadow-cljs (52)
- # spacemacs (3)
- # specter (17)
- # sql (6)
- # tools-deps (2)
- # vim (3)
- # yada (28)
QUESTION: How do you compile only gen-classes ? Like I don't even want to compile the namespace which has the :gen-class in it, but I only want the Java .classes defined by gen-class to be compiled? Using pure Clojure, not with lein.
have your namespace with the gen-class require other code at runtime instead of when it is loaded
example of a java app that uses this a related approach (written so I could use the jsvc app launcher without using gen-class) https://github.com/noisesmith/clj-jsvc-adapter/blob/master/src/java/org/noisesmith/Cljsvc.java
That seems different, you're just avoiding gen-class altogether here, and creating your own Java wrapper no?
right, but it's doing the same thing: require at runtime, then calling functions that should be made available by the required code
you can do the same thing from an ns that uses gen-class (I started out with that, but with that level of java interop writing a java file was cleaner)
It seems more complicated from Clojure, because then you need to have a flag which on compile does not cause things to be required, but does so otherwise
the thing is, clojure is live, so compiling the code has the same effects as loading it (because compiling subsequent code made depend on those effects)
another thing you can do is just generate the bytecode for the class you want without dealing with the clojure compiler at all
@didibus the clojure version of that code looked like:
(ns foo.bar)
(defn -main [& args]
(require 'baz.quux)
((resolve 'baz.quux/-main) args))
you can add gen-class to that, and it won't load baz.quux while compiling, this is directly analogous to what the java code is doing (just much less idiomatic)
Which is why I was thinking something more like:
(ns foo.bar)
(when-not *hypothetical-compiling-flag*
(require '[baz.quux]))
what’s a good name or an option for a map transformation that’s not recursive? no-recurse?
We already had a version that did recursion by default.
what about linear
?
well, we have a convention that options should take nil or false as the default, so I have to invent a name for non-recursive. I’ll probably go with that
Is there a string length function I can use both in clj and cljs? I can use count, but count is slow and generates ton of garbage
Why do you think that count
is slow? And what garbage?
@roklenarcic, you may be thinking of the implementation of count for sequences.
I've improved performance a lot in some of my libraries by replacing count with explicit .length calls
Looking at the newest 1.10 code of count, directly invoking .length saves about 4 if sentences
I’d say that this only makes sense when you have a real bottle neck.
@roklenarcic this seems to work:
(defn str-length [s] #?(:clj (.length ^String s) :cljs (.-length s)))
well obviously I can write my own 😄
I was hoping for an official solution and I'm shocked that clojure.string namespace doesn't have one
hell even substring exists in clojure.core
count
works for both @roklenarcic
Hi everyone, I'd like to get compiler warnings when a variable masks another one So, for example in this case:
(let [[name] ["yay"]]
name)
=> warning: name already refers to clojure.core/name
anyone know if there is a way to turn that on, or if there is an open issue for this? If there is I haven't found via googling. thanksnot that I know. joker (a linter) also doesn’t warn about this, but I think it could be a useful feature for it
@mark540 As explained, count isn't appropriate because it's slow and generates garbage
@borkdude thanks, linters are probably the place to start investigating if it's not in the compiler
What would be useful to me is an option to only warn about shadowing clojure.core symbols, as in the example.
This linter warns about (some cases of) shadowing: https://github.com/jonase/eastwood
Hi. I have an error with my simple module: https://pastebin.com/bBy8htnT error: Exception in thread "async-dispatch-88" java.lang.NullPointerException can anyone tell me why? I've spend on this some time and I really don't know why.
You should check the full stack trace using (clojure.repl/pst)
, but I can see a couple things wrong with that code. When you're using blocking <!!
you shouldn't wrap those in go blocks. Also by putting the "store" in a global def you're defeating the purpose of mount/defstate.
Am I right in thinking libraries shouldn't include org.clojure/clojure
as a dependency? Since it's just going to be provided by the application anyway?
unless you’re making a cljs only lib or a Java-facing AOT-compiled lib, it doesn’t matter I guess
or maybe it does when your lib forces a newer version of clojure than the lib consumer wants to user? hmm. not sure how that is resolved
I've also wondered how this works when multiple dependencies declare dependencies on diff versions of Clojure
In the past, I've usually set the default uncaught exception handler at the top of a -main entrypoint for an application. I am ring uberjar'ing. Will setting the default uncaught exception handler at the top of, say, server.clj
(the location of the ring handler) accomplish same?
(ns server)
(Thread/setDefaultUncaughtExceptionHandler
(reify Thread$UncaughtExceptionHandler
(uncaughtException [_ thread e]
(log/error e "Uncaught exception on" (.getName thread)))))
(def handler ...)
it's a mutable slot on an object, you can set it in any place at any time
top level side effects are run when the ns is loaded (even when using aot)
Can I define a mutation over an ident, instead of declaring all the way walking through the tree?
by ident do you mean symbol or keyword? that's what clojure.core/ident?
checks for, but if that's what you mean your question confuses me
do you mean a nested update as in update-in
or assoc-in
as opposed to a programmatic operation like clojure.walk/post-walk
?
I mean, if I have a normalized table :people/people-list and inside it :person/by-id Can I use a mutation directly for [:person/by-id 1] or do I have to go into [:people/people-list :my-list :person/by-id 1]
@patrickcms your use of the word “mutation” is confusing. If you are asking how to use update-in
/ assoc-in
with a map, then yes you’ll have to put the full path
you could come up with your own function that uses clojure.walk to do what you mean, though. Again, assuming you’re using a map
Thanks @noisesmith and @lilactown anyway
Yes. And I suppose a better question would've been: can you extend via metadata with an interface.
metadata is a clojure thing - you can check metadata via java by using the clojure IMeta api (or using the Clojure api to call clojure.core/meta) but this isn't something you should expect normal java code to be doing, ever
and it's definitely not something that exists on the level of the Closable interface
you can use defrecord
to make a hash-map that is also Closable
that's a change to with-open so it can use things that aren't directly java.io.Closable, it doesn't change or extend Closable itself
what's the motivation for not using java.io.Closable - wanting to extend some class from outside the implementation?
I have an API that returns a map and I wanted to use with-open
in my tests to ensure that parts in that map are closed when the test finishes.
but then you'd be extending closable to map?
you can implement protocols just via metadata?
Right. Wrapping in a record is fine. Just seemed cleaner if it was possible to do it via metadata.
ahh, a new 1.10 feature
Why we can't vote closed issues? https://dev.clojure.org/jira/browse/CLJ-1623
Probably part of the way JIRA works, either by default, or perhaps by custom configuration of this instance, but I don't know which.
Given the conversation on that issue, I would not hold high hopes that it would be implemented in core even if it got a thousand votes.
Votes get attention to an issue sooner, they don't necessarily change the decision made once it has been considered.
My suggestion would be making your own variant of the function that works as you wish, and use that. Given the interest in it by some others, I wouldn't be surprised if Specter can do it, or medley, or one of handful of other utility libraries.
Anyone can patch their own copies of Clojure all they wish, of course. Not nearly as convenient as having it in a place where it can be used without a patch.
@U2J4FRT2T Just refer your update-in and exclude clojure's version. The current behaviour has been useful to me tracking down bugs that would otherwise subtlely succeed but mysteriously trash everything :) (consider, returning a dynamically generated path vs or nil for the second argument)
Your semantics are equally valid of course, but clojure is extremely amenable to hacking, and guardrails are nice in general imo. Particularly in a dynamic language like a lisp.
This is perhaps a different issue, but get-in
does seem inconsistent and I wonder if the fact that it returns the entire map when [] is passed is intentional or it just happens to do that. There is no way to tell from the doc, since it just says "ks is a sequence of keys" and doesn't say whether it can be an empty sequence.
Oops, I meant get-in
not get
, fixed.
My guess is that the behavior with an empty sequence is accidental and the doc should probably say "ks is a non-empty sequence of keys".
That's not to say clojure 2 might not fix this sort of thing, but pretty much everything in 1.x is backwards compatible for practical reasons.
https://www.conj.io/store/v1/org.clojure/clojure/1.9.0/clj/clojure.core/update-in grimoire reports the correct signature though. Not a computer atm, but wonder if that is how it is defn'd
so you could make a new IClosable and a new with-open
or you could pass the relevant vals to the current with-open (it allows N closables)
I suppose. This works for now - not critical. Was just trying to use a new 1.10 feature really 🙂
yeah, extending via metadata is opt-in on a per-protocol basis, interesting