Fork me on GitHub
#beginners
<
2018-02-27
>
avi00:02:28

OK, thanks... can you suggest a way to do what I want? I figure I could create a macro but I wonder if there’s another way.

greglook00:02:36

(source doc) - you could use the same methods it does internally

seancorfield00:02:56

(doseq [s [`doc `+]] (#'clojure.repl/print-doc (meta (resolve s))))

seancorfield00:02:15

(although doc is substantially more complicated)

seancorfield00:02:36

(looks like you could use ' instead of backtick there)

avi00:02:10

I thought of that, but print-doc looked private

seancorfield00:02:01

It is. But Clojure lets you call private functions.

avi00:02:12

Ah right

seancorfield00:02:12

And access private variables' contents.

avi00:02:22

OK, I’ll try that. Thanks!

seancorfield00:02:33

(the code above works -- I tested it in the REPL first)

avi00:02:51

Very cool, thank you!

nakiya03:02:38

I get these errors in a heroku app log (after following re-frame lein template instructions)

2018-02-27T03:28:46.620804+00:00 app[web.1]: Setting JAVA_TOOL_OPTIONS defaults based on dyno size. Custom settings will override them.
2018-02-27T03:28:46.626435+00:00 app[web.1]: Picked up JAVA_TOOL_OPTIONS: -Xmx300m -Xss512k -Dfile.encoding=UTF-8 
2018-02-27T03:28:52.373794+00:00 app[web.1]: No :main namespace specified in project.clj.
2018-02-27T03:28:52.374621+00:00 app[web.1]: Error encountered performing task 'trampoline' with profile(s): 'production'
2018-02-27T03:28:52.374755+00:00 app[web.1]: No :main namespace specified in project.clj.
Anyone familiar with this? I see that some other people ran into this problem but didn’t encounter any solutions

noisesmith03:02:37

does your project.clj have a :main key?

nakiya03:02:12

@noisesmith: I’m don’t see one. I will paste the entirety of the file below.

(defproject npuzzle "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [org.clojure/clojurescript "1.9.908"]
                 [reagent "0.7.0"]
                 [re-frame "0.10.5"]
                 [garden "1.3.2"]
                 [ns-tracker "0.3.0"]]

  :plugins [[lein-cljsbuild "1.1.5"]
            [lein-garden "0.2.8"]]

  :min-lein-version "2.5.3"

  :source-paths ["src/clj" "script"]

  :clean-targets ^{:protect false} ["resources/public/js/compiled" "target"
                                    "test/js"
                                    "resources/public/css"]

  :figwheel {:css-dirs ["resources/public/css"]}

  :garden {:builds [{:id           "screen"
                     :source-paths ["src/clj"]
                     :stylesheet   npuzzle.css/screen
                     :compiler     {:output-to     "resources/public/css/screen.css"
                                    :pretty-print? true}}]}

  :repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}

  :profiles
  {:dev
   {:dependencies [[binaryage/devtools "0.9.4"]
                   [day8.re-frame/re-frame-10x "0.2.0"]
                   [figwheel-sidecar "0.5.13"]
                   [com.cemerick/piggieback "0.2.2"]]

    :plugins      [[lein-figwheel "0.5.13"]
                   [lein-doo "0.1.8"]]}}

  :cljsbuild
  {:builds
   [{:id           "dev"
     :source-paths ["src/cljs"]
     :figwheel     {:on-jsload "npuzzle.core/mount-root"}
     :compiler     {:main                 npuzzle.core
                    :output-to            "resources/public/js/compiled/app.js"
                    :output-dir           "resources/public/js/compiled/out"
                    :asset-path           "js/compiled/out"
                    :source-map-timestamp true
                    :preloads             [devtools.preload
                                           day8.re-frame-10x.preload]
                    :closure-defines      {"re_frame.trace.trace_enabled_QMARK_" true}
                    :external-config      {:devtools/config {:features-to-install :all}}}}


    {:id           "min"
     :source-paths ["src/cljs"]
     :compiler     {:main            npuzzle.core
                    :output-to       "resources/public/js/compiled/app.js"
                    :optimizations   :advanced
                    :closure-defines {goog.DEBUG false}
                    :pretty-print    false}}

    {:id           "test"
     :source-paths ["src/cljs" "test/cljs"]
     :compiler     {:main          npuzzle.runner
                    :output-to     "resources/public/js/compiled/test.js"
                    :output-dir    "resources/public/js/compiled/test/out"
                    :optimizations :none}}]})

noisesmith03:02:00

so, what that message is telling you is that it doesn't know how to run your project because project.clj doesn't specify a main for leiningen to run

noisesmith03:02:01

your code doesn't appear to have any back end element though - does it define any server, or is it just cljs served by figwheel during development?

nakiya03:02:59

@noisesmith: Yeah, just figwheel

noisesmith03:02:16

if you have no backend code, you could just upload an index.html and js etc. to a CDN - you don't even need any server side process other than serving the files

noisesmith03:02:08

anyway that's why heroku doesn't know what to do - it expects to start a back-end clojure process and you have none, all you really seem to need is a generic static web host

nakiya03:02:52

Ok, thanks @noisesmith

mschaef15:02:27

Any suggestions for more idiomatic ways to achieve this?

(defn connect []
  (swap! connection #(or % (open-connection))))

ghadi15:02:12

idiom aside, swap! can retry, so you might have extra connections

ghadi15:02:46

considering idiom, connection seems like a global var

mschaef15:02:43

@ggallohernandez… it is, for two reasons. 1) (open-connection) calls into a library that itself maintains lots of global state.

mschaef15:02:52

2) Meant to mainly be called from REPL.

mschaef15:02:32

(def connect
  (let [ connection (delay (open-connection) ) ]
    (fn []
      @connection)))
maybe better?

dmitryn15:02:30

I suggest to look at the https://github.com/tolitius/mount or Component library

mschaef16:02:37

Nice… thanks for the suggestion

nakiya16:02:50

Is there any collection in clojurescript akin to C++ multimap? (Should be ordered, and able to contain multiple equal keys)

nakiya16:02:26

Trying to implement A*, need a data structure for the open list

nakiya16:02:05

Or I need to manually maintain vector/list for each key instead of a single item using a sorted-map?

Cayetano Soriano18:02:08

Does anyone using datadog with clojure ring instrumentalization?

rymndhng18:02:31

@neoshadybeat have not, what metrics would you be ineterested in instrumenting, out of curiosity?

Cayetano Soriano18:02:07

Firstly Requests and response

rymndhng18:02:13

i'm wodnering if you're looking for response times or status codes?

Cayetano Soriano18:02:56

Response time and status code

Cayetano Soriano18:02:07

Also db connection

Cayetano Soriano18:02:22

Between anothers

rymndhng18:02:06

gotcha, i haven't seen a ring middleware to do all that yet. We've written a wrapper for dogstatsd (wraps the java one) if you'd build something ontop of it: https://github.com/unbounce/clojure-dogstatsd-client

rymndhng18:02:29

i can definitely see value in creating ring middleware for response time & status code

Cayetano Soriano18:02:10

I was working once it

Will19:02:06

If I have a map of vectors a which equals [{:a 1 :b 2 :c 3 :d 4} {:a 5 :b 6 :c 5 :d 8}] and another vector b which equals [{:a 1 :c 3 :d 10} {:a 1 :c 2 :d 3}] how would I compare these two and return any results where the attributes :a and :c are equal, but :b is not equal

noisesmith19:02:04

compare by index, or compare every pair?

noisesmith19:02:23

if the latter, something like (for [x v1 y v2 :when (and (= (select-keys x [:a :b]) (select-keys y [:a b])) (not= (:c x) (:c y)))] [x y])

Will19:02:10

Compare by every pair

noisesmith19:02:22

yeah, for is the easy way to do that

noisesmith19:02:49

@josmith2016 I think I am misunderstanding you, because nothing in the second vector even has :b so you'd be getting no results if you compare

Will19:02:08

I have two different vectors that have different kinds of maps with similar data but different properties. I know what properties I want to compare in each map and want the results where for example property :a in vector a equals property :b in vector b but property :c in vector a doesn't equal property :din vector b

noisesmith19:02:04

@josmith2016 OK - so something like this - I wasn't sure because it didn't return anything interesting with your example data and rules http://ix.io/Qkw

Will19:02:34

Thanks @noisesmith 😁

noisesmith19:02:05

for comparing :a in x and :b and y and visa versa this is a neat trick: (apply = (map :a [x y]) (map :b [y x])) - maybe too clever but it works

Elena19:02:09

I have a dataset that I give as an input to a function I am spec'ing. This dataset can be either of two types, let's call them A and B. How would I go about spec'ing it?

Elena19:02:33

Type A is an atom, and I can dereference it, and type B is a PersistentArrayMap.

mfikes20:02:51

@elena.caraba The general idea would be to use s/or. If the value is an atom, is your intent to validate the atom's contents? And, is the atom A expected to hold a map that satisfies to the same spec that B would?

Elena14:02:04

Thank you! The answers are yes and yes

mathpunk21:02:30

I have some time data to work with. I pulled in clj-time. To my surprise, (inst? (time/now)) is not true, as time/now gives a org.joda.time.DateTime object. I don't know anything about Java time and date libraries; is there a reason to prefer one over another? I.e. should I write my own predicate for a spec or have a chosen a weird option for representing times?

mfikes21:02:16

@mathpunk If you only need to timestamp things, you could get away with (Date.)

mathpunk21:02:18

@mfikes I have a mix of timestamps, and date stamps (no time)

mathpunk21:02:33

so I brought in org.joda.time.LocalDate

mathpunk21:02:07

I have heard that dealing with time and computers is...... challenging 🙂

mfikes21:02:29

Ahh, what I meant by that: If you only need to tag things with an instant in time, you could use (Date.), but if you need to start to manipulate time values, or access their sub-parts, then the question of "Which library?" becomes relevant.

mfikes21:02:24

For example Clojure/(Script) #inst "2014" and inst? for very simple time stamping is sufficient for many use cases, and in that case you can just rely on what is in the core language.

mfikes21:02:59

It is surprising that cljs-time hasn't extended the Inst protocol to their "instant-like" time values. Hrm.

alexmiller21:02:54

well that’s new in 1.9

seancorfield21:02:53

@mathpunk I'm one of the maintainers of clj-time but I'd recommend looking at clojure.java-time which is a wrapper around the built-in Java Time stuff (added in Java 8).

seancorfield21:02:59

boot -d clojure.java-time repl
...
boot.user=> (require '[java-time :as jt])
nil
boot.user=> (inst? (jt/instant))
true
boot.user=>

seancorfield21:02:51

boot.user=> (jt/instant)
#object[java.time.Instant 0x21b0ad22 "2018-02-27T21:23:15.358Z"]
boot.user=> (jt/java-date (jt/instant))
#inst "2018-02-27T21:23:24.058-00:00"
boot.user=>

mfikes21:02:43

@alexmiller Hah. Extremely valid point. I forgot. Looking it up in ClojureScript inst? and Inst have evidently been there since mid-2016.

jimbob22:02:19

Is there a way to pass in an arbitrary function into project.clj? example. I have on env variable that contains both a username and password for a private maven repo. I want to be able to get user and pass from this one env var. Is there any way to do this?

jimbob22:02:33

currently:

:repositories [["maven" {:url ""
                           :username :env/mvn_repo_login_user
                           :password :env/mvn_repo_login_pass }]]

jimbob22:02:01

:repositories [["maven" {:url ""
                           :username (get_env_user)
                           :password (get_env_pass)}]]

noisesmith22:02:51

@ben.borders if the code can be found, ~(foo) evaluates foo inline in the template

noisesmith22:02:29

you might need to insert a ~(do (require 'my.tool.ns) ...) in there

noisesmith22:02:57

or, alternatively, you could implement a plugin, those can do whatever they like to update the project task before other things run

jimbob22:02:32

excellent. thanks for the help!

noisesmith22:02:54

@ben.borders of course if all you are doing is literally getting from env: ~(System/getenv "MAVEN_USER") etc.