Is there a way to compile my project into a executable jar without lein? I do have a deps.edn
and one of my namespaces has a -main
function.
Check out depstar
@zhuxun2 There's a #depstar channel if you get stuck or have follow-on questions about it.
Can I destruct one of my arguments, while let doing it for another one? The first argument is a string, and the second one a map which I would like to destruct
Using :keys maybe?
@olle142 something like that?
(let [{x :my-string {:keys [a b] #_any-kind-of-destructuring-can-go-here} :my-submap} {:my-string "s" :my-submap {:a 12 :b 34}}]
[x a b])
=> ["s" 12 34]
Yes that is exactly it, thank you very much @cgrand
Is there the concept of NA
or NaN
in clojure? That is, is there a NA
value such that (+ 1 NA)
would yield NA
? nil
doesn't work, as (+ 1 nil)
gives me a null pointer exception...
##NaN
which is really just java.lang.Double/NaN
Thanks. I haven't tried yet, but I'm guessing that nil
works with nicely with missing string arguments. I'm trying some limited incanter
type operations, and I'd like the missing construct.
Beware that (= ##NaN ##NaN)
returns false
for reasons from the IEEE standard for floating point values, and thus ##NaN
used as a set element or a map key will not be able to be looked up successfully, and any collections you might want to call =
on will return false
if either or both of them contain ##NaN
values.
Some examples and discussion here: https://clojure.org/guides/equality#_floating_point_not_a_number
This seems consistent with many constructs, like NULL
in SQL... is there a function that returns true for ##NaN? like a isNaN
function?
Yes there is a Java method:
user=> (Double/isNaN ##NaN)
true
I see from your link maybe I can make (.equals ##NaN ##NaN)
work...
OK, that helps, thanks.
You cannot override the definition of Clojure's =
, or the way it looks up elements in sets or as map keys, without hacking on Clojure's Java implementation.
Got it. I was thinking that if Double/isNaN
didn't exist, I could implement something like (defn isNan [x] (.equals ##NaN x))
... I am much removed from the skill to rewrite internals ๐ ...
I would not recommend it ๐. I was merely answering the possible followup question of whether one could change how those language features work in Clojure.
I'll bring this back to top level... Is this the idiomatic way to parse a list of strings, some of which will parse, and some of which will fail to parse?
(map #(try (Integer. %) (catch Exception e ##NaN)) ["1" "" nil])
Hello everyone, I have a doubt about dependencies in CLJ(S). I have a project where, among other things, I use re-frame@0.10.8 and reagent@0.8.1. I want to upgrade re-frame to 1.1.1, but in the changelong said that re-frame upgrades reagent to 0.10.0 on its version 0.12.0. Should I also upgrade reagent version in my project, or do the libraries compile and use the versions they need from their own dependencies?
sure. although I would probably not keep the nans. not sure what your usecase is but i would probably do (keep #(try (Long/parseLong %) (catch Exception _ nil)) collection)
Thanks. My use case is reading in a CSV, which has a column that should be measurements, but some are missing. Let's say I have two such columns, and I want to average them. If one of the columns has a missing value, I want the corresponding row output to have a missing value. Dropping values means columns won't line up, and keeping nil
values makes arithmetic throw exceptions. So I want to make an output for each row, and if there are missing values, the computation should be missing. I'm coming from R and python-pandas, where I am operating on tabular-shaped dataframes. I have some small subset of those operations I want/need to do in Clojure to be able to leverage other tools in Clojure. Thanks for the help.
I'll add, for posterity, and anyone who stumbles on this: This has a lot of great information as well: https://stackoverflow.com/questions/2640169/whats-the-easiest-way-to-parse-numbers-in-clojure
unless there's a specific reason to stay at 0.8.1, then I would upgrade
Hey I'm working on a web server using ring and jetty, and getting a bunch of 500 errors, with almost no information anyone know how to get more details/a stack trace from that setup?
I'm looking to write some coercion code that expects a string or nil, coerces nil
to ""
and otherwise returns the string
in other languages, I might write (or s "")
. is that idiomatic? is there something more idiomatic?
I canโt think of anything wrong with it
I believe this is considered idiomatic
Looks good to me as well.
cool, thanks
๐
Another option is to call str
on the argument. If itโs nil
itโll coerce it to ""
. Note that str
also coerces all different types of values.
oh, I didn't realize str
coerced nil
to ""
. Thanks. It's for some url handling stuff, so everything is a string or nil
anyway
Having some issues around using sorted-set-by, I'm trying to order a set of strings by their length but it demolishes the entire list to only (I think) one string per length? I want all the lists and for the set-y-ness's to apply to the string not the length, just want to be sorted by length. Please assist.
(def domains
(into (sorted-set)
(map clojure.string/lower-case
(drop-while #(< (count %) 4)
(sort-by count
(re-seq #"(?m)^.*$" (slurp "domains.txt")))))))
(count domains)
;; => 52664
(defn count-comparator [a b]
(compare (count a) (count b)))
(def domains
;; right here vvvvvvvvvvvv
(into (sorted-set-by count-comparator)
(map clojure.string/lower-case
(drop-while #(< (count %) 4)
(sort-by count
(re-seq #"(?m)^.*$" (slurp "domains.txt")))))))
(count domains)
;; => 19
;; should be higher, whats wrong with my comparator? (I assume?)
I'm having trouble upgrading the dependencies for this project
(defn js-dir
"Prefix with full JavaScript directory."
[path]
(str "resources/public/js/compiled/" path))
(defproject onaio/chimera "0.0.13"
:description "Collection of useful Clojure(Script) functions."
:dependencies [[clj-time "0.15.2"]
[com.cognitect/transit-cljs "0.8.264"]
[com.taoensso/tempura "1.2.1"]
;; For CSV->XLSForm
[clojure-csv/clojure-csv "2.0.2"]
[dk.ative/docjure "1.11.0"]
[onelog "0.5.0"]
[org.clojure/clojure "1.8.0"]
[org.clojure/clojurescript "1.10.773"
:exclusions [org.clojure/clojure]]
[org.clojure/core.async "1.3.610"]
[org.omcljs/om "0.9.0"]
[slingshot "0.12.2"]
;; JS
[cljsjs/moment "2.24.0-0"]]
:license "Apache 2"
:url "<https://github.com/onaio/chimera>"
:profiles {:dev {:dependencies [[midje "1.8.3"]]}}
:plugins [[jonase/eastwood "0.2.1"]
[lein-bikeshed-ona "0.2.1"]
[lein-cljfmt "0.3.0"]
[lein-cljsbuild "1.1.2"]
[lein-environ "1.0.1"]
[lein-kibit "0.1.2"]
[lein-midje "3.1.3"]]
:cljfmt {:file-pattern #"[^\.#]*\.clj[s]?$"}
:eastwood {:exclude-linters [:constant-test]
:add-linters [:unused-fn-args
:unused-locals
:unused-namespaces
:unused-private-vars]
:namespaces [:source-paths]
:exclude-namespaces [chimera.async]}
:test-paths ["test"]
:cljsbuild {
:builds {:dev
{:compiler {:output-to ~(js-dir "chimera.js")
:output-dir ~(js-dir "out")
:optimizations :whitespace
:pretty-print true
:source-map ~(js-dir "chimera.js.map")}}
:test
{:source-paths ["src" "test"]
:notify-command ["phantomjs"
"phantom/unit-test.js"
"phantom/unit-test.html"
"target/main-test.js"]
:compiler {:output-to "target/main-test.js"
:optimizations :whitespace
:pretty-print true}}
:prod
{:source-paths ["src"]
:compiler {:output-to ~(js-dir "chimera.js")
:output-dir ~(js-dir "out-prod")
:optimizations :advanced
:pretty-print false}
:jar true}}
:test-commands {"unit-test"
["phantomjs"
"phantom/unit-test.js"
"phantom/unit-test.html"
"target/main-test.js"]}}
:global-vars {*warn-on-reflection* true})
I keep getting this error
Let me create a local lein
project and see what happens with that project.clj
...
Syntax error compiling var at (midje/util/exceptions.clj:75:3).
Unable to resolve var: aviso.exception/*traditional* in this context
Thank you very much @seancorfield
if you have a long block of text, use a snippet CMD-Shift-Enter (on Mac, probably control on Windows). It will even do clojure syntax highlighting
Thanks... good to know
@franklineapiyo How do you run lein ancient
in interactive mode?
The report from lein ancient
only identifies these three deps as being outdated -- is this what you get too?
[dk.ative/docjure "1.14.0"] is available but we use "1.11.0"
[org.clojure/clojure "1.10.1"] is available but we use "1.8.0" (use :check-clojure to upgrade)
[midje "1.9.9"] is available but we use "1.8.3"
yes... I have updated all the other's just now
Have you read this: https://clojuredocs.org/clojure.core/sorted-set-by ?
lein ancient :interactive
The 2nd example seems to be specifically about your problem
That gives me this warning
(warn) option ':interactive' is not applicable for this task.
sorry.. that's not the correct command
lein ancient upgrade :interactive
Oops, youre right thanks!
Okay, the conflict is coming from onelog "0.5.0"
which is bringing in an older version of Aviso:
Retrieving io/aviso/pretty/0.1.12/pretty-0.1.12.pom from clojars
I did lein deps :tree
and looked through to see what was using aviso pretty.
That is earlier than the change to pretty which introduced the *traditional*
var (0.1.15).
And the problem shows up when lein ancient
tries to run your tests after the updates I think...?
yes
Possible solutions: add :exclusions
to the onelog dependency to exclude io.aviso/pretty
; or add a top-level dependency directly on io.aviso/pretty "0.1.37"
alright... thanks will try that.... I didn't think of using lein deps :tree
... that's one new thing I just learned
That still may not work, because onelog may depend on something in the older version of Aviso Pretty but it's worth a try.
I would definitely recommend not using interactive tools that "help" by modifying your project configuration -- do it manually instead.
Thanks you very much... It's pretty late over here... so I'm going to sleep on in though... it's pretty late on this side of the planet... ๐
I personally would also recommend not using Midje. It's considered non-idiomatic and drags in a lot of transitive dependencies that can be problematic.
what do you think is the better substitute for midje?
Just use plain old clojure.test
aaah... alright
Midje isn't compatible with any standard test runners or test tooling.
It's why I created expectations.clojure.test
so there's a fully clojure.test
-compatible version of Expectations. It provides the expressiveness of classic Expectations but still lets you use all the standard clojure.test
tooling built into all the editors and (standard) test runners.
Hi Iโm having a trouble with implementing priority queue with sorted-set-by. I am not able to figure out how to implement โdequeโ operation. first function correctly returns element with lowest priority, but i am not able to get sorted set without the first element using supplied comparator.
(sorted? (rest (sorted-set my-compare [3 1 2 4])))
returns false
Could anybody help?if you're using clojure.core/sorted-set
it takes the elements of the set, not a comparator and a collection as you are using it. what is returned from (sorted-set my-compare [3 1 2 4])
?
did you mean to use sorted-set-by
?
but just kinda doing dimensional analysis on it, the sorting of the set has a custom sorter whereas the call to sorted?
does not use this custom sorter. So most likely they will not agree. EDIT: just read how sorted?
works and this doesn't seem true to me now. the sorted-set will implement clojure.lang.Sorted. but the seq returned from rest won't
but rest
returns a seq, not a set
@michal.kurtak try using disj
perhaps?
sorry iโve used sorted-set-by of course. the thing is, iโve expected that rest function returns same collection type but without the first elemenet
I wonder if sorted-set is a good fit for priority queues; it's gonna drop items if the comparator sees them as equal
yes, i understand your point. i have unique values so i thought it is good enough. The disj trick worked. Thank you
This is the code without comparator (but the same works with comparator)
(let [s (sorted-set 3 2 1 4)]
(sorted? (disj s
(first s))))
BTW, what will you suggest for priority queue? sorted-map?
no idea. my first take would still probably be sorted-set-by, but with some kind of tie-breaker (or, as in your case, a guarantee that there are no duplicates)
or a sorted-map
with sets / vectors for values, depending on what the specific task needs
@michal.kurtak Have you looked at clojure.data.priority-map
? https://github.com/clojure/data.priority-map (I am not the author or maintainer, despite having made the most recent commit)
Hi, thank you for your tip. I think this what i โve been looking for the case with non-unique values (for unique values sorted-set is sufficient). Iโve also managed to use sorted-map with little trick from https://clojuredocs.org/clojure.core/sorted-map-by (you have to wrap sorted-map-by to data that holds both sorted and unsorted map and lookup for value in unsorted map in comparator), but clojure.data.priority-map is better because all standart colletion functions (first, rest, count, containsโฆ) work out of box without wrappers
You could have the sort key be not only the length, but a vector of [length string-value]. That will sort first by the length, and only use the string-value as a tie-breaker for same-length strings.
Note that if your input strings have duplicates of the same identical string, then sorted-set-by will only include one of those in the resulting sorted-set.
If you want to retain duplicates, then it sounds more like what you would want is to sort a sequence, i.e. list, vector, array, etc., and give back a sequence with the same number of items, including any duplicate strings in the input. That cannot be done with a sorted-set unless you somehow make each equal string into different values, e.g. by making it a vector with a unique id for each string or something like that.
It can be done with a vector or array, and you can use sort
or sort-by
with appropriate comparator functions.