Fork me on GitHub

Just wondering, are there any projects that heavily uses 'funcool/cats'? It seems pretty okay if you don't want any exception.


(ns accounts)

(def account_keys {:account :identification_id :name})

(def account {:account {:identification_id "11111111111" :name "Tiago"}})

(defn valid_new_account?
  (every? #(contains? account %) account_keys))
In this code only the :account key is found in the account map. Is there a way to check all the keys in the map?


this is what spec is for, and usually asserting that only certain keys are present is a bad idea in clojure


but you could eg. check the keys

user=> (= #{:account} (set (keys {:account :foo})))


that checks both that :account is present, and that other keys are absent


#(contains? account) is wrong too - you want #(contains? % :account) - but really unless {:account nil} or {:account false} is valid, you can just use :account which acts as a function that looks itself up in a map returning the value (any non nil/false is considered "true")


Oh sorry, forgot the % So you think it would be better if I use spec to check the necessary keys present in the map?


this might be a good way to learn the language, but if your real goal is to validate records, that is what the spec library is for yeah


Thanks @noisesmith I’ll take a look into that

Mario C.04:12:51

Is there a function in clojure that checks if a number is effectively 0?

Mario C.04:12:47

I guess I could just round down


What do you mean "effectively 0"?


(< x 0.0001) for however many decimal places you care about

Mario C.05:12:10

Yea thats pretty much it ^


(< x 0.0001) is true for x = -123... you want (< -0.0001 x 0.0001)

👍 4


(keyword "jersey number")
=> :jersey number


Indeed, the keyword function does not validate its inputs and delegates this responsibility to the user. That’s it 🙂


thank you all


you can create keywords the reader can't parse


or is there a reader trick for keywords with evil spaces in them?

Eamonn Sullivan13:12:55

Hi all, I'm trying to get my head around some simple specs. I wrote a very simple predicate that returns true for a sequence of exactly one element: (defn single? [lst] (and (sequential? lst) (not (empty? lst)) (empty? (rest lst)))) Seems to work, interactively on the repl. So I tried writing a spec for it (the following assumes (require '[clojure.spec.test.alpha :as test]) (require '[clojure.spec.alpha :as s]) so that I could generate some tests: (s/def ::single-sequence (s/coll-of any? :count 1)) (s/fdef single? :args (s/cat :lst any?) :ret boolean? :fn #(= (:ret %) (% :args :lst ::single-sequence))) I really struggled with that last bit (the :fn). The documentation is extremely sparse and examples are hard to find. But basically, I'm trying to say that the return should be true if (and only if) the provided arg is a single-sequence. But I can't really tell if it is working, because when I try to test this: (test/check single?)` I get a very large stack trace, but buried within it is "Unable to construct gen at: [] for: clojure.spec.alpha$spec_impl$reify__2059@6320ff48" Am I missing something simple and obvious? I bet I am... I can't even instrument the function: clojure-utils.core> (test/instrument single?)` [clojure-utils.core/single?] clojure-utils.core> (single '(1)) Execution error (NullPointerException) at clojure-utils.core/eval571538 (form-init5892131410628118783.clj:358). null clojure-utils.core> I must be missing a step. It looks like something's not set up correctly.

Eamonn Sullivan14:12:03

This is what my code looks like now:

Eamonn Sullivan14:12:06

I can run (s/exercise-fn single?) but when I try to run (test/check single?) it's trying to run the function with a ridiculous value (e.g., [(())] or [(0)]) that would fail even run by themselves. So perhaps I'm not spec'ing the argument correctly?

Eamonn Sullivan15:12:50

FYI, in case someone else needs this, I eventually got it working with something like this. It's probably way more convoluted than necessary.

AJ Jaro14:12:10

I periodically run into an issue running lein ring server with HTTPS and then attempting to stop the server. For some reason on shutdown sometimes it won’t let go of the port and I’m required to restart my computer. This doesn’t seem to be an issue if I use the HTTP URL primarily. Has anyone else ran into this or similar issues?


how are you stopping lein ring server?


there are a few things that could happen, lein ring server runs two jvms (the lein jvm and your project jvm) and you could be causing the lein jvm to exit and not the other which hodls the port. the project jvm may also not be cleanly exiting which depending on the os, can cause the port to be listed as in use for a surprising amount of time in whatever datastructure your os uses to track that kind of thing, but usually that will clear eventually (and there tend to be os settings to fiddle with how long that takes)

AJ Jaro18:12:32

@hiredman I run lein ring server using IntelliJ and stop it using the same on a Mac. Do you have any suggestions on that configuration that could help?


no idea what intellij does there. if you run ps auxwww you should be able to check for java processes hanging around after you stop it.


hint: jps might be easier to use


I'd like to write a small script on windows 10 to bulk rename files using clojure. lein new app seems like overkill, and the clojure cli tools on windows is in alpha. Any suggestions on alternatives?


perfect use cases for babashka and planck, now do either of them work on windows...


lumo seems to try to target windows


though the build is failing 🙂


It seems like babashka and planck will work on wsl, but I'd like to find a solution where I don't have to install wsl.


you're just renaming files? so you need no libraries?


just download the clojure jar and use it using java -jar


do I call it like this? java -jar clojure-1.10.0.jar scriptname.clj


~/C/clj-scratch $ cat src/bfabry/hello.clj                                                                                                                                                                                                                              11:26:04
(ns bfabry.hello)

(defn -main [& args]
  (println "Hello, world"))
~/C/clj-scratch $ java -jar ~/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar -i src/bfabry/hello.clj -m bfabry.hello                                                                                                                                        11:26:08
Hello, world


you need to both tell it to load the file and then to run it. hence both -i and -m


probably someone who understands java classpaths etc better than me could give you a neater way. but it's pretty damn lightweight!


I'm getting this error: Exception in thread "main" java.lang.ExceptionInInitializerError


I made a file called hello.clj with the contents of the cat in it. and ran it with this command: java -jar clojure-1.10.0.jar -i hello.clj -m bfabry.hello


doh, doesn't work with 1.10


so 1.10 depends on clojure.spec.alpha. which I didn't include on my classpath


you'd need to include that jar in the cp somehow


let me try 1.8


that works! Thanks a lot! I'll stick with the 1.8 version. I think there's a switch for java that adds classpath (-cp maybe?) I'll look into that as well


yeah I have a vague idea how to do it but it would be trial and error for me. building up the string that gets passed to -cp is basically exactly what the clj cli tool does


in fact, the clj tool can even tell me what to do

~/C/clj-scratch $ clj -Sverbose -m bfabry.hello                                                                                                                                                                                                                         11:38:29
version      =
install_dir  = /usr/local/Cellar/clojure/
config_dir   = /Users/bfabry/.clojure
config_paths = /usr/local/Cellar/clojure/ /Users/bfabry/.clojure/deps.edn deps.edn
cache_dir    = .cpcache
cp_file      = .cpcache/146930055.cp

Hello, world
~/C/clj-scratch $ cat .cpcache/146930055.cp                                                                                                                                                                                                                             11:39:11


~/C/clj-scratch $ java -cp "src:/Users/bfabry/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar:/Users/bfabry/.m2/repository/com/rpl/specter/1.1.3/specter-1.1.3.jar:/Users/bfabry/.m2/repository/org/clojure/data.xml/0.0.8/data.xml-0.0.8.jar:/Users/bfabry/.m2/repository/org/clojure/spec.alpha/0.2.176/spec.alpha-0.2.176.jar:/Users/bfabry/.m2/repository/org/clojure/core.specs.alpha/0.2.44/core.specs.alpha-0.2.44.jar:/Users/bfabry/.m2/repository/riddley/riddley/0.1.12/riddley-0.1.12.jar" clojure.main -m bfabry.hello
Hello, world


lol. roundabout way of doing things but it's nice to confirm things work the way you think they do sometimes


that's eye-opening. Thanks for running me through it!


no worries. it was helpful for me

AJ Jaro19:12:43

@hiredman ok, it seemed like it was a process that was attempting to stop but was stuck with the E status code and we couldn’t finish