Fork me on GitHub
#beginners
<
2020-01-14
>
johnj01:01:21

What are the issues with place oriented programming (PLOP) Hickey mentions in his "Maybe not" talk?

johnj01:01:04

I'll take look, thanks

andy.fingerhut04:01:57

"The Value of Values" also starts off with some description of places vs. values: https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ValueOfValues-mostly-text.md

seancorfield05:01:23

I love those transcripts. Every time I go back and read one -- even for talks I've watched more than once -- I always pick up some new nuance!

Hi09:01:51

hi! how do I parse this 1578933411031343 (epoch) to something like this "2015-01-11 03:00" ?

mloughlin09:01:20

what's the first number?

mloughlin09:01:30

unix timestamp?

jsyrjala09:01:57

Divide number by 1 000 000, then you’ll get unix timestamp (in seconds)?

Eamonn Sullivan09:01:16

It looks like clojure.java-time can do this (see Legacy Date-Time Types at the bottom of the readme). https://github.com/dm3/clojure.java-time

jsyrjala09:01:19

Typically tools want unix timestamp as seconds or millisecond, and you have in nanoseconds?

Hi09:01:35

I can have

(str (java.util.Date. (System/currentTimeMillis)))
but it is different format than I need.

mloughlin09:01:34

IIRC there's a newer "favoured library" for Date/Time operations than clj-time. Something about removing internal dependencies? I can't remember the name of the lib offhand

papachan11:01:08

@ba somethng linke this?

(f/unparse (f/formatters :date) (clj-time.coerce/from-long (long (/ 1578933411031343 1000))))

Hi11:01:22

what is f ?

papachan11:01:48

its from my require [clj-time.format :as f]

papachan11:01:28

this epoch give me: "2019-01-13"

1
Hi14:01:13

This is perfect! thank you very much 😉

😄 1
bartuka11:01:30

Someone using compojure-api with spec? I want to provide a path-param but I keep getting an error. Current code:

(context "/:status" []
                             (resource
                              {:get {:summary "get information about buyside packages in the system"
                                     :parameters {:path-params (s/keys :req-un [::status])}
                                     :handler (fn [{{:keys [status]} :path-params}]
                                                (contracts/get-buyside status))}}))
and the error:

bartuka11:01:30

1. Caused by java.lang.IllegalArgumentException
   Don't know how to create ISeq from:
   clojure.spec.alpha$map_spec_impl$reify__1997

                   RT.java:  553  clojure.lang.RT/seqFrom
                   RT.java:  533  clojure.lang.RT/seq
       APersistentMap.java:   40  clojure.lang.APersistentMap/cons
                   RT.java:  673  clojure.lang.RT/conj
                  core.clj:   85  clojure.core/conj
                  core.clj: 3049  clojure.core/merge/fn
                  core.clj:  944  clojure.core/reduce1
                  core.clj:  934  clojure.core/reduce1
                  core.clj: 3048  clojure.core/merge
                  core.clj: 3041  clojure.core/merge
               RestFn.java:  421  clojure.lang.RestFn/invoke
                routes.clj:  138  compojure.api.routes/ensure-path-parameters/fn
                  AFn.java:  154  clojure.lang.AFn/applyToHelper
                  AFn.java:  144  clojure.lang.AFn/applyTo
                  core.clj:  667  clojure.core/apply
                  core.clj: 6185  clojure.core/update-in/up
                  core.clj: 6184  clojure.core/update-in/up
                  core.clj: 6186  clojure.core/update-in
                  core.clj: 6172  clojure.core/update-in
               RestFn.java:  445  clojure.lang.RestFn/invoke
                routes.clj:  138  compojure.api.routes/ensure-path-parameters
                routes.clj:  136  compojure.api.routes/ensure-path-parameters
                routes.clj:  173  compojure.api.routes/all-paths/fn/fn
                  AFn.java:  154  clojure.lang.AFn/applyToHelper
                  AFn.java:  144  clojure.lang.AFn/applyTo
                  core.clj:  667  clojure.core/apply
                  core.clj: 6185  clojure.core/update-in/up
                  core.clj: 6184  clojure.core/update-in/up
                  core.clj: 6186  clojure.core/update-in
                  core.clj: 6172  clojure.core/update-in
               RestFn.java:  445  clojure.lang.RestFn/invoke
                routes.clj:  170  compojure.api.routes/all-paths/fn
     PersistentVector.java:  343  clojure.lang.PersistentVector/reduce
                  core.clj: 6827  clojure.core/reduce
                  core.clj: 6810  clojure.core/reduce
                routes.clj:  167  compojure.api.routes/all-paths
                routes.clj:  166  compojure.api.routes/all-paths
                routes.clj:  178  compojure.api.routes/route-lookup-table
                routes.clj:  177  compojure.api.routes/route-lookup-table
                   api.clj:   63  compojure.api.api/api
                   api.clj:   19  compojure.api.api/api
               RestFn.java:  137  clojure.lang.RestFn/applyTo
             Compiler.java: 3702  clojure.lang.Compiler$InvokeExpr/eval
             Compiler.java:  457  clojure.lang.Compiler$DefExpr/eval
             Compiler.java: 7181  clojure.lang.Compiler/eval
             Compiler.java: 7635  clojure.lang.Compiler/load
                      REPL:    1  user/eval24737
                      REPL:    1  user/eval24737
             Compiler.java: 7176  clojure.lang.Compiler/eval
             Compiler.java: 7131  clojure.lang.Compiler/eval
                  core.clj: 3214  clojure.core/eval
                  core.clj: 3210  clojure.core/eval
                  main.clj:  414  clojure.main/repl/read-eval-print/fn
                  main.clj:  414  clojure.main/repl/read-eval-print
                  main.clj:  435  clojure.main/repl/fn
                  main.clj:  435  clojure.main/repl
                  main.clj:  345  clojure.main/repl
               RestFn.java:  137  clojure.lang.RestFn/applyTo
                  core.clj:  665  clojure.core/apply
                  core.clj:  660  clojure.core/apply
                regrow.clj:   18  refactor-nrepl.ns.slam.hound.regrow/wrap-clojure-repl/fn
               RestFn.java: 1523  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   79  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:   55  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:  142  nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
                  AFn.java:   22  clojure.lang.AFn/run
               session.clj:  171  nrepl.middleware.session/session-exec/main-loop/fn
               session.clj:  170  nrepl.middleware.session/session-exec/main-loop
                  AFn.java:   22  clojure.lang.AFn/run
               Thread.java:  748  java.lang.Thread/run

bartuka11:01:30

It seems :status in the URI is not valid. But, it should be by some examples I saw in the repo/compojure-api

Hi13:01:41

can test see private functions?

alexmiller13:01:50

It can, via the vars #’my-ns/the-private-thing

alexmiller13:01:40

If you invoke a var that references a function, it will invoke the function

teslanick14:01:13

I feel like I’m making a dumb mistake or misapprehension. I’m in an nrepl session playing with core async and trying to figure out what’s going on here:

(go (println "HERE")) ; #object[clojure.core.async.impl.channels.ManyToManyChannel ...
But it doesn’t print "HERE"

teslanick14:01:25

Instead:

(<!! (go (prn "HERE"))) ; #object[clojure.core.async.impl.channels.ManyToManyChannel
"HERE"

teslanick14:01:18

The docs don’t say anything about go blocks being lazily evaluated, but that seems to be the case in practice? Could this be an artifact of the REPL environment?

markmarkmark14:01:55

@teslanick using println and related functionality is a poor way to test concurrent things. Due to the way that println prints and then adds a newline, wacky stuff can happen. For instance, when I ran (go (println "HERE")) the first time my output was

here#object[clojure.core.async.impl.channels.ManyToManyChannel 0x79b9cd42 "[email protected]"]
Note the 'here' at the beginning of the line with no newline

markmarkmark14:01:14

I ran it again and the here printed on the next line, I ran it again and the here printed at the end of the line, etc

ghadi14:01:15

@teslanick two things 1) nREPL doesn't always convey prints that happen in background threads 2) don't do I/O in go blocks

markmarkmark14:01:35

try doing something like

(def a (atom []))
(go (swap! a conj "HERE"))

markmarkmark14:01:56

and see if the atom is updated

ghadi14:01:06

you can send data to a logging channel, that's a good alternative.

👍 1
ghadi14:01:54

go blocks are scheduled into a thread pool, and doing raw I/O in that pool can starve the pool

teslanick14:01:12

This is an incremental step toward something, but it sounds like this isn’t the right tool. I want to spread a bunch of network requests across several threads, is core.async not appropriate for that?

ghadi14:01:52

sure -- use async/thread to make the requests

ghadi14:01:06

inside async/go the only blocking you can do is channel operations

teslanick14:01:13

Ok, it does appear to be an idiosyncracy of my environment because this works:

(def a (atom []))
(go (swap! a conj "HERE"))
(deref a)

dpsutton14:01:44

what's your repl setup?

teslanick14:01:17

Using VSCode to track working state. This is the second time this morning that I’ve noticed it possibly eliding stdout, so I think that must be the source of the problem.

teslanick14:01:20

Sorry, a VSCode plugin, which has an nREPL and an eval command as a feature. Which apparently isn’t perfect 😛

pez15:01:38

I hope that is not Calva? (Which isn't perfect, but anyway 😀)

zignd15:01:21

Hey guys, I need some help regarding building an uberjar. Currently my personal project runs find through lein run , I can also compile it through lein uberjar, but there's probably something wrong in this compilation, that it because when I try to run it I get the following error message:

zignd15:01:57

Here's is my project.clj:

zignd15:01:16

I believe there might be something wrong in the :profiles {:uberjar {}} section, but I couldn't find much online, can anyone help me?

zignd15:01:05

Do I need to add some sort of exception for the schema.core namespace so that during the compilation it adds it to the uberjar?

Hagenek16:01:56

(defn error-message [severity] (str “OH GOD! IT’S A DISASTER WE’RE ” (if (severity :mild) “MILDLY INCONVENIENT!” “DOOOOOOOMED!“)))

Hagenek16:01:06

Results in “OH GOD! IT’S A DISASTER WE’RE DOOOOOOOMED!” in the repl. when I call the function with (error-message :mild). But it should be “Mildly convenient.

Eamonn Sullivan16:01:39

(= ...)?

☝️ 3
yogidevbear16:01:41

I think you want (if (= severity :mild)...

Hagenek16:01:34

I found the typo yeah! Thanks

Hagenek16:01:41

Sorry, I am a total beginner 😛

Eamonn Sullivan16:01:27

I only spotted it immediately because that's exactly what I would have done...

😂 1
bartuka17:01:04

I can't make compojure-api to handle decimals in post request. any ideas? I am using :coercion :spec and a spec map validating decimals? in one field

noisesmith18:01:51

@georghagen btw this works: (if (#{:mild} severity) ...) - but it's more useful if you want to match multiple things in one check

noisesmith18:01:24

this is because sets work as functions that try to look up their args in themselves

mss20:01:28

anyone know of any examples of gracefully shutting down a component system in the main thread of my program? I’m using Runtime/addShutdownHook but my process is exiting before the actual shutdown fns are called for each component

noisesmith20:01:33

@mss you could put -main's body in a try block and shut down the component stystem in the finally clause?

mss20:01:25

that would exit as soon as the start-system call returned, no?

mss20:01:38

(defn -main [& args]
  (let [env (or (keyword (System/getenv "ENV")) :dev)]
    (timbre/merge-config! (make-logging-config env))
    (let [system (make-system (make-config env))]
      (component/start-system system)
      (.addShutdownHook (Runtime/getRuntime) (Thread. (fn []
                                                        (timbre/log :info "SHUTTING DOWN SYSTEM")
                                                        (component/stop-system system)))))))

noisesmith20:01:38

but some things are outside the VMs control - eg. a forced kill will prevent the program from exiting cleanly period and the jvm can't change that

mss20:01:46

what my -main fn looks like

noisesmith20:01:01

the idea would be to block at the end of -main

noisesmith20:01:50

a useful idiom for that is @(promise) - you can see instantly that that can only exit if forced to

noisesmith20:01:48

of course this also means using something other than -main in the repl (or only running it in a background thread)

ghadi20:01:47

if start-system blocks, it's possible that your shutdown hook is never registered

ghadi20:01:06

(not sure what the behavior is, just speculating)

mss20:01:09

so in my case start-system wasn’t blocking and my shutdown hook was def getting invoked. ended up doing the following, which seems to work fine. does this seem idiomatic? am I missing anything?

(defn -main [& args]
  (let [env (or (keyword (System/getenv "ENV")) :dev)]
    (timbre/merge-config! (make-logging-config env))
    (let [system (make-system (make-config env))
          shutdown-promise (promise)]
        (component/start-system system)
        (.addShutdownHook (Runtime/getRuntime) (Thread. #(shutdown-system system shutdown-promise)))
        @shutdown-promise)))

👍 1
mss20:01:19

thanks for the help btw y’all, really appreciate it

noisesmith20:01:15

I'm surprised that the previous version didn't work if this one does though

noisesmith20:01:25

and if you aren't using try with finally you don't need to wait on that promise

hiredman21:01:08

If you all the threads you start are daemon threads, there is nothing stopping the jvm from exiting once the main thread exits