This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-08-26
Channels
- # announcements (6)
- # beginners (88)
- # calva (12)
- # cider (13)
- # cljs-dev (27)
- # cljsrn (2)
- # clojure (68)
- # clojure-argentina (2)
- # clojure-dev (10)
- # clojure-europe (1)
- # clojure-greece (1)
- # clojure-italy (5)
- # clojure-nl (15)
- # clojure-spec (33)
- # clojure-switzerland (1)
- # clojure-uk (10)
- # clojurescript (121)
- # clojutre (3)
- # code-reviews (2)
- # core-async (1)
- # cursive (10)
- # data-science (1)
- # datomic (21)
- # emacs (10)
- # events (1)
- # fulcro (25)
- # graphql (6)
- # joker (4)
- # kaocha (12)
- # lambdaisland (3)
- # music (2)
- # off-topic (112)
- # om (2)
- # re-frame (25)
- # reagent (29)
- # reitit (93)
- # rewrite-clj (2)
- # shadow-cljs (18)
- # slack-help (4)
- # spacemacs (8)
- # tools-deps (1)
- # vim (2)
- # yada (5)
How do you deal with cond expressions where one expression is too long so you have to break the line. Do you put the result for the predicate on a line below, and the other expressions on one line, or do you make it consistent.
my example
(defn m-tree [leaves concat-fn initial]
(loop [[l r & rest :as nodes] leaves
result initial]
(cond
(and (empty? nodes)
(< (count result) 2)) result
(empty? nodes) (recur result [])
(and
(and l (not r))
(seq result)) (recur (conj result l) [])
(and l (not r)) nodes
(and l r) (recur rest (conj result (concat-fn l r))))))
(cond (pred-1)
(expr-1)
(pred-2)
(multi-line expr
more stuff))
I find cond
very hard to read when the expressions follow predicates on the same line, unless they are all vertically aligned.
(so I find your cond
hard to read and would complain about it in a Pull Request review 🙂 )
(cond (and (empty? nodes)
(< (count result) 2))
result
(empty? nodes)
(recur result [])
(and
(and l (not r))
(seq result))
(recur (conj result l) [])
(and l (not r))
nodes
(and l r)
(recur rest (conj result (concat-fn l r))))
Better
Well, apart from not being aligned under the first arg (and (empty? nodes) ,,,)
I found this a bit harder to read, only because you can't just pop in any part and quickly know if it's an expression or a predicate
but yea, it does align consistently
In a long cond
I often insert blank lines between the pred/expr pairs.
ok, yeah that's what I naturally want to do
(cond (and (empty? nodes)
(< (count result) 2))
result
(empty? nodes)
(recur result [])
(and
(and l (not r))
(seq result))
(recur (conj result l) [])
(and l (not r))
nodes
(and l r)
(recur rest (conj result (concat-fn l r))))
gotcha 👍
you can also consider doing core.match
when your stuff starts getting crazy
I personally like the "what you see is what you get" data approach whenever possible... FWIW, etc, etc...
Anyone have advice for resolving functions from symbols in edn?
For example, datomic’s ion-config.edn lets you provide fully qualified function names as symbols
and at runtime, your ns is required and those functions are hooked up
I can think of several ways to do it, some really stupid
I guess ns-resolve is probably the move?
requiring-resolve
lol, there we go
Thanks @alexmiller 🙂
which is what Datomic does
Clearly I need to start skimming clojure.core after every release
https://github.com/clojure/clojure/blob/master/changes.md is a good place to check
was added in 1.10
we've been working towards making vars rehydratable references too (Java serialization support is there now) and that's another future option for this
Very cool!
right now, many people run into this and then need selectively resolve symbols in their data. edn vars (tagged literal representation prob) would be a way to have that happen automatically on read
We were very happy to see requiring-resolve
added -- it's been very useful for us!
is it possible to attach an error handler on a lazy collection so it will be executed when something goes bad when realizing an element?
I should have figured this wouldn't work
(ins)user=> (defn lazy-basket [coll] (lazy-seq (when-let [c (seq coll)] (cons (try (first c) (catch Exception e :oops)) (lazy-basket (rest c))))))
#'user/lazy-basket
(cmd)user=> (lazy-basket (map / (rest (range 11)) (range 10)))
Error printing return value (ArithmeticException) at clojure.lang.Numbers/divide (Numbers.java:188).
Divide by zero
hey folks, I have a question about AOT compilation and require
and how they interact with each other. My question, specifically, is - if I AOT compile my Clojure code as part of a mixed language Java/Clojure project, but then require
a Clojure namespace from Java (e.g. Clojure.var("clojure.core", "require").invoke(Clojure.var("clojure.core", "symbol").invoke("a.namespace"));
), will that require
call re-compile that namespace, or will it use the AOT compiled class(es)?
require
prefers a .class
file when there are no .clj
nor .cljc
resources with corresponding names, or when both suffixes exist but the time stamps of the .class
files are more recent than the source files.
If anything you ever try to require, either directly, or indirectly via one of the things you require also doing its own require recursively, etc., does not find a .class
file, or only finds a .class
file with a time stamp earlier than the corresponding source file, then the source file will be compiled.
Reference: The clojure.lang.RT/load method: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L427-L464
Thanks, that’s pretty helpful. What kinds of actions would cause the timestamp of a .class
file to change? On the surface I would only expect compilation to modify those timestamps?
I believe the main action that causes a .class
file to be written in Clojure is compile
, which can occur as part of evaluating a require
expression.
If you are creating a JAR file with a mix of Clojure source files and .class
files (whether those .class
files are produced by Java compilation or Clojure compilation), then you can look at the timestamps of all of the files inside the JAR file, to see what they are. There might even be an existing tool that would warn if .class
files exist with the same name as a source file, but older modification times, but I am not aware of one.
> f you are creating a JAR file with a mix of Clojure source files and .class
files (whether those .class
files are produced by Java compilation or Clojure compilation)
I am, and I think it’s possible this has bitten me once or twice
@seancorfield if you encountered an error 'Caused by:ClassNotFoundException overtone.core' what steps would you take to help the compiler find the class?
Sounds like you don't have the correct dependency in your project
YES cool thanks! That led me to realize that deps.edn relies on clj deps to find dependencies. I had been using lein but I'd abandoned the project.clj for a deps.edn
I'm unsure of what to make of "Exception in thread "main" java.io.FileNotFoundException: deps (The system cannot find the file specified)"
What command gives you that error?
Sounds like clj deps
(which is not a thing, unlike lein deps
).
(! 642)-> clj deps
Execution error (FileNotFoundException) at java.io.FileInputStream/open0 (FileInputStream.java:-2).
deps (No such file or directory)
Like that?clojure
/`clj` does not need a deps
command (nor does lein
to be honest -- it is a legacy command that used to be needed in the early days, before Leiningen changed to track stale dependencies and automatically re-check them for you).
That’s interesting. I’ve been using lein deps
when changing versions because I thought it was still necessary.
@UGTAV6LR2 It hasn't been necessary for quite a while but a lot of tutorials etc never got updated. At one point Phil said "If you find you need lein deps
for anything, it's a bug and I'll fix it!" 🙂
If you want to see what dependencies get pulled in: clj -Stree
and if you feel like you need to override/refresh the dependency cache: clj -Sforce
Yeah, clj deps is what caused it. I'll put both of those on my cheat sheet. If clj deps isn't required, though, that means that not using that wasn't the root problem of the absent dependency.
clj deps
means "run the script called deps
" -- which is not what you intended @norilinoriginal 🙂
I want to make a dev tool that wraps every function in a list of namespaces with some AOP style/defadvice around like functionality that records every input and output received and produced into a database. The idea would then be editors could query the db by symbol and add static typing like i/o signatures (and even replay old i/o - benefit of unit tests and spec without any dev overhead). Is there anything like this out there atm?
the only thing I know of that comes close, robert.hooke, is disrecommended by the author
that said, for one off local dev stuff, you can just iterate on the values referenced by the ns - these are available via public methods and easy to use
user=> (->> (all-ns) (mapcat ns-publics) (rand-nth) key)
bigint
the corresponding val is the var attached to that symbol in its ns