Fork me on GitHub
#clojure
<
2017-12-27
>
noisesmith00:12:52

also you can recur to a function - loop is just a convenience if the loop bindings shouldn't be your function args

seancorfield00:12:48

The key thing is that recur may only appear in a tail position -- and therefore it is always optimized. The compiler won't allow you to recur in a position that couldn't be optimized.

hawari08:12:02

Hi, just wondering, how do you guys use spec for data validation? Using :pre in defn helps in a way to ensure that the function can't be called with unsuitable arguments. But the resulting AssertionError is not really helpful for composing error message to the user. I mean, I don't want to return "Assert failed: (spec/valid? ::email email)" as the error message to the user. Something like: "Invalid format for email" is good enough for me as of now.

hawari08:12:24

I came across this https://groups.google.com/forum/#!topic/clojure/H9tk04sSTWE It gave me some clarity, but any thoughts here will still be appreciated 🙂

synthomat09:12:24

thank’s for explaining 🙂

xificurC09:12:54

the spec guide https://clojure.org/guides/spec#_testing has a snippet on how to test all spec'ed functions from an ns (-> (stest/enumerate-namespace 'user) stest/check). Where should I add this in a classic clojure.test file? Adding it just like that produces 0 tests. Wrapping it in a deftest produces 1 tests with 0 assertions..

qqq11:12:30

(counted? (float-array [1 2 3]))
(comment
 false)


what is the constant time way to get the size of a float-array ?

noisesmith12:12:46

it dousn't implement clojure.lang.Counted because it's not a clojure type

noisesmith12:12:54

it still supports count in constant time

noisesmith12:12:19

user=> (source counted?)
(defn counted?
 "Returns true if coll implements count in constant time"
 {:added "1.0"
   :static true}
  [coll] (instance? clojure.lang.Counted coll))
nil

octahedrion14:12:24

@seancorfield does the compiler similarly optimize non-`recur` recursion when it's in the tail position ?

noisesmith14:12:33

no, this feature is intentionally missing

octahedrion14:12:38

explicit is better

octahedrion14:12:45

@noisesmith actually, shouldn't recur be called iterate (I know iterate has been used) ? it's not recursion when it's in the tail-position

noisesmith15:12:42

it's still recursion, a tail recursion is trivially translated into a goto

noisesmith15:12:09

but that's an implementation detail - aside from stack usage the behavior is the same as direct recursion

tees15:12:32

👋 I recently converted a clojurescript project to use mostly cljc (to possibly move towards clojure), but now i'm getting a ⛵ load of errors when I boot my cljs project: java.lang.RuntimeException: Unable to resolve symbol: defproject in this context, compiling:(project.clj:1:1) usually starting with that ⬅️ . Strangely enough everything still works. Sound familiar with anyone?

noisesmith15:12:40

is your source path for cljs set up so it would find project.clj?

tees15:12:56

I'm currently using the lein checkouts feature ... and I also have the third party lib cljc thing as a dependency...

tees15:12:45

ie. for my shared cljc lib I have run "lein install", and am now referencing that as a dependency as well as using the lein checkouts sym link features to make use of it. Everything appears to work, but I am seeing these errors on boot.

tees16:12:00

the errors look like so:

Reloading Clojure file "/src/myproject/myfile.cljc" failed.
clojure.lang.Compiler$CompilerException: java.lang.IllegalAccessError: MY-FUNCTION does not exist, compiling:(src/myproject/myfile.cljc:1:1)

alex-dixon15:12:22

Looking for a working proxy middleware for ring. Have tried tailrecursion/ring-proxy but running into errors. Any recommendations?

alex-dixon15:12:52

More specifically looking for a proxy configuration that can work with figwheel: https://github.com/bhauman/lein-figwheel/issues/634

justinlee16:12:44

I don’t have any help for you but just want to say thank you for working on this. This feature would be very helpful.

mping16:12:33

Hi all, can you tell me why tree-seq is flattening my tree? My code is like this:

(defn to-tree [root]
  (let [name (:name root)
        reg  @registry]
    (tree-seq
     #(some? (:childs (get reg %)))
     #(:childs (get reg %))
     name)))
registry is a giant atom map with {"xxx" {:name "aaa" :childs ["yyy" "zzz"]}}

mping16:12:39

I know, it isn’t very functional; I’m calling (to-tree "xxx")

mping16:12:43

but I get a flat sequence ("xxx" "yyy" "zzz")

dpsutton16:12:27

> Returns a lazy sequence of the nodes in a tree, via a depth-first walk. that seems to be what it promises? perhaps you want something in clojure.walk?

mping16:12:53

I was hoping to get something like ("xxx" ("yyy" "zzz" (...))

noisesmith17:12:10

yeah, you want clojure.walk/post-walk for that likely

noisesmith17:12:39

tree-seq is useful if you have no assumptions about the shape of the data, but you know what the thing you want looks like (so you can filter and find it)

noisesmith17:12:55

post-walk / pre-walk / walk are for doing a transformation in the shape of the original collection

borkdude19:12:00

When is the 2017 Clojure survey?

Alex Miller (Clojure team)00:12:26

Justin and I have talked about it a couple times but haven’t buckled down to do it. It’s on my list for January

seancorfield19:12:46

@alexmiller ^ ? Last year it was opened in early-ish December (12th) and the results came out in early February (7th).

dottedmag20:12:57

Folks, what is the better/more idiomatic/shorter way to sort+print a vector of elements than

(doall (map #(-> %
                     format-value
                     println)
                (sort-by some-fn some-vector)))
?

the2bears20:12:21

drop the 'doall' and replace 'map' with 'run!'?

noisesmith20:12:19

also consider (doseq [value (sort-by some-fn some-vector)] (println (format-value value)))

noisesmith20:12:12

also, if using map instead of run! (eg. for clojure version reasons or to take extra args like map does) use dorun instead of doall, since the value returned is not something you want or need (just a sequence of nils)

dottedmag20:12:24

(run! #(println (format-value %)) (sort-by some-fn some-vector)) looks better, thanks.

noisesmith20:12:52

for fancy fp-gangsta points you can replace that function with the equivalent (comp println format-value)

scriptor20:12:57

(->>
  some-vector
  (sort-by some-fn)
  (mapv (comp println format-value)))

noisesmith20:12:22

run! is much better than mapv here

qqq20:12:39

(defn get-data [] 
  ( (str (mnist-config :data-dir) "foo"))
  (doseq [[k url] (select-keys mnist-config [:train-images :train-labels :t10k-images :t10k-labels])] 
    (with-open [in (java.util.zip.GZIPInputStream. ( url))]
      (spit (str (mnist-config :data-dir) (name k)) (slurp  in)))))

(get-data)


is there a better way to write this? in particular, the (spit ... (slurp ...)) seems redundant We're downloading a bunch of *.gz files, gunziping thej,m, and writing it out to file

seancorfield20:12:27

Oh wait, you're slurping an input stream... not sure if copy will do that...

noisesmith20:12:49

you can write an inputstream directly though

noisesmith20:12:54

that is, you can write it to an outputstream, and create the output stream in the with-open call as a second binding

noisesmith20:12:50

something vaguely like (with-open [in …. out (io/output-stream (io/file (str …)))] (.write out in)) but probably also requiring a loop or a byte count on the write

qqq20:12:42

these files are only 60M, I'll deal with the 'memory inefficiency' then

noisesmith20:12:16

it’s just a needless creation of a string, not a huge deal

noisesmith20:12:02

also just to be clear making a string out of a 60 meg file that’s encoded with utf-8 is likely 120megs in memory because java strings are utf-16

noisesmith20:12:50

and definitely don’t use slurp/spit for anything that isn’t text

noisesmith20:12:08

(I don’t know what those “images” in the name refer to just be aware that if they are image data as in bmp or jpeg slurp/spit will turn them into garbage)

wiseman22:12:35

is anyone else able to watch https://www.youtube.com/watch?v=5VAEXYYdfWY (“Zippers - Episode 2”)? it’s not working for me.

wiseman22:12:12

oh, i get a better error message embedded here in slack, sorry! (“This video requires payment to watch”)

haus23:12:15

is there an easy way to list the requires for a given namespace? I was looking for something like ns-refers but for requires

jgh23:12:22

i didnt realize youtube red videos were part of regular youtube

Ryan Radomski23:12:02

I have a lot of .cljc code I'd like to make into a library. Is there a way to make cross platform libraries without rewriting my code twice?