Fork me on GitHub
#clojure
<
2018-06-28
>
len08:06:29

Morning folks. I have a job system and want to add some callback functions that get called when the job state changes. I am currently persisting these jobs to datomic and am looking for a way to persist these callback functions as well, any suggestion how to do this elegantly ?

Nick Cabral23:06:42

I'm solving something similar at the moment. Thinking I'll use a keyword->func mapping, and relate each job to an entity that consists of a keyword and the function args.

metametadata01:06:57

Function can be persisted as its full var name and then loaded by finding the var dynamically. I did it here: https://github.com/metametadata/byplay/blob/ecafa7694f937d4bb43bcc38edc558c77c466645/src/byplay/core.clj#L130 and more recently here (also works in CLJS): https://github.com/metametadata/aide/blob/21b420982d1f53fa99a9c5374ee798f6823569c5/src/aide/var_event.cljc#L40

👍 4
dominicm08:06:57

Should clojure.core/compile's output include classes for clojure.core? I would expect it would run transitively, but I'm not seeing that at all. I'm only seeing the immediate require of the namespace in AOT (excluding clojure.core)

Alex Miller (Clojure team)11:06:39

Clojure is already compiled

Alex Miller (Clojure team)11:06:19

AOT will transitively compile all clj it loads

Alex Miller (Clojure team)11:06:45

But core will be class files already

jmckitrick12:06:56

For a basic web service, with endpoints, a core app layer, and db access, where (if anywhere) would spec be better than unit tests?

jmckitrick12:06:03

For example, would it be better to wrap unit tests in a transaction and test db access, or to fdef those db access functions and test.check and instrument them?

Andreasp199415:06:15

Hey what is clojure's predicate for long? is it bigdec?

Alex Miller (Clojure team)15:06:25

just longs or integral types?

Alex Miller (Clojure team)15:06:55

or that is int? is fixed precision integral types

Alex Miller (Clojure team)15:06:32

and integer? covers both fixed and arbitrary precision integral types

Alex Miller (Clojure team)15:06:49

there isn’t anything for “just long” other than #(instance? Long %)

Andreasp199415:06:28

It's just long... but integral types will do too.. thanks!

hagmonk17:06:03

@ericnormand with the best explanation of Sets 😂 >>> What if you are coding up a cat university. Each cat has a meow id number. And you're taking attendance. Since a classroom full of cats is notoriously hard to count, you're probably going to count the same one twice. Why not just capture all of the meow ids you can, and ignore duplicates? That's why sets are cool.

👍 4
🐱 12
4
Björn Ebbinghaus17:06:11

@alexmiller Why is:

(s/valid? identity :clojure.spec.alpha/invalid)
=> false
But:
(s/valid? (constantly :clojure.spec.alpha/invalid) :something)
=> true
?

ghadi17:06:01

I could explain why @mroerni but neither are sensible code that would (should) occur in the wild

ghadi17:06:41

in the first case , it's because :clojure.spec.alpha/invalid is never valid

ghadi17:06:35

in the second case, it turns the constantly form into a spec through the predicate path: like in (s/def ::foo string?) or (s/def ::foo ....pred)

ghadi17:06:55

to check a predicate spec, it applies the predicate to the data

ghadi17:06:20

in this case calling (:clojure.spec.alpha/invalid :something)

Björn Ebbinghaus17:06:59

@ghadi Sounds logical. Thanks I have written a conformer, but without (s/conformer) around it. I was really confused about the results. The code above would be a minimal example.

Quest22:06:10

Anyone know how I could have some .clj files in my user directory (outside of the project), but always be able to require/load them from a project's REPL? Went digging around for a way to do this but came up empty. Tried different ideas in the ~/.lein/profiles without any dice. Only remaining idea I have is to add repl/* to src paths in project.clj, and them symlink a directory from my user directory

noisesmith22:06:20

I just use load-file for things like that

👍 8
noisesmith23:06:28

I have a task in my profiles.clj to load-file a clj file that does everything else (including loading some useful namespaces with load-file itself etc.)

Quest16:06:42

This is genius -- I was wondering what the best way to hook into lein is for this. Would you mind sharing the task definition?

noisesmith16:06:00

:user {:dependencies []                                                        
        :repl-options {:init (do (load-file (str (System/getenv "HOME")         
                                                 "/user.clj"))                  
                                 (refer 'user))}
...}

noisesmith16:06:57

the getenv means I can use the same .lein/profiles.clj, controlled via git of course, on multiple logins

noisesmith16:06:59

and of course that user.clj is shared on multiple hosts via git as well

noisesmith16:06:53

normally user.clj is used if found on the classpath, but it's easy for that to go wrong (eg. more than one found, the first is used...) so manually loading the file is more reliable

Quest17:06:49

I get that -- I work on a lot of projects, so being able to flexibly load different swaths of my "REPL utility code" or data schemas is something I want a lot. I'll try to get this working today and report back. An early thanks for the great explanation though @noisesmith 🙂

noisesmith17:06:40

that :init is about all there is to it, beyond niceties about what ns you define things in etc. that you can probably figure out just fine

noisesmith17:06:16

a cool option would be a verision that takes a : separated "SOURCE_LOAD" env var and iterates and loads them all into the starting ns

noisesmith17:06:32

(that might be a nice plugin)

Quest19:07:25

@noisesmith Just wanted to report back: I tried using the above (load-file ...) snippet in my :repl-options :init, but every time I ran cider-jack-in it failed. I think I might've been blowing away the previous value of :repl-options :init, which caused CIDER to spit out the following error

Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol: do in this context, compiling:(/private/var/folders/48/g6krc_l545vcsnd81370njdc0000gr/T/form-init1117316997761838904.clj:1:8390)
error in process sentinel: Could not start nREPL server: {"@timestamp":"2018-07-02T17:41:28.297Z","type":"log","description":"Logging initialized @9546ms","level":"info","thread":"main","namespace":"org.eclipse.jetty.util.log","line":186}
I suspect it has something to do with how Ring hooks into the project and tries to init the repl server itself, probably via those :repl-options I ended up using :injections instead, which still got me what I was looking for.
:injections [(do (load-file (str (System/getenv "HOME") "/user.clj"))
                   (refer 'user))]
Anyway, that wraps that up. Thanks you very much for the help: I've been wanting this for months!

👍 4
Quest19:07:25

@noisesmith Just wanted to report back: I tried using the above (load-file ...) snippet in my :repl-options :init, but every time I ran cider-jack-in it failed. I think I might've been blowing away the previous value of :repl-options :init, which caused CIDER to spit out the following error

Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol: do in this context, compiling:(/private/var/folders/48/g6krc_l545vcsnd81370njdc0000gr/T/form-init1117316997761838904.clj:1:8390)
error in process sentinel: Could not start nREPL server: {"@timestamp":"2018-07-02T17:41:28.297Z","type":"log","description":"Logging initialized @9546ms","level":"info","thread":"main","namespace":"org.eclipse.jetty.util.log","line":186}
I suspect it has something to do with how Ring hooks into the project and tries to init the repl server itself, probably via those :repl-options I ended up using :injections instead, which still got me what I was looking for.
:injections [(do (load-file (str (System/getenv "HOME") "/user.clj"))
                   (refer 'user))]
Anyway, that wraps that up. Thanks you very much for the help: I've been wanting this for months!

👍 4