Fork me on GitHub
#beginners
<
2016-12-29
>
sneakypeet06:12:56

Hi all. is there a preferred clojure style guide that you would recommend? I found this but not sure how close it is to what the community does https://github.com/bbatsov/clojure-style-guide#naming

roelof06:12:34

I have this code :

defn home-page [page]
  (let [page-num (s/conform ::page page)
        url ""
        options {:as :json :query-params {:key (env :key) :format "json" :type "schilderij" :toppieces "True" :p page-num :ps 10}}]
    (if (s/invalid? page-num) 1 page-num)
    (layout/render
      "home.html" {:paintings (-> (client/get url options)
                                  api/read-numbers
                                  api/fetch-paintings-and-images-front-page)})))defn home-page [page]
  (let [page-num (s/conform ::page page)
        url ""
        options {:as :json :query-params {:key (env :key) :format "json" :type "schilderij" :toppieces "True" :p page-num :ps 10}}]
    (if (s/invalid? page-num) 1 page-num)
    (layout/render
      "home.html" {:paintings (-> (client/get url options)
                                  api/read-numbers
                                  api/fetch-paintings-and-images-front-page)})))  

roelof06:12:26

now I have made a input validation on api/read-numbers

roelof07:12:10

is there a way I can make it work to not apply fetch-paintings-and-images-front-page only when read-numbers returns something otherwise then nil. I could put read-numbers in a if-then but then that function gets executed several times.

curlyfry09:12:52

@sneakypeet That guide is made with help from the community and I highly recommend it!

sneakypeet09:12:21

sweet thank you

Jon10:12:54

I got trouble in optimization, described here https://twitter.com/jiyinyiyong/status/814165501924360192

roelof13:12:42

Why is this one failing on string? :

(s/explain ::objectNumber [{:objectNumber "sk-c-5"}])
val: [{:objectNumber "sk-c-5"}] fails spec: :paintings2.api-get/objectNumber predicate: string?  

roelof13:12:02

sk-c-5 is a string there

roelof13:12:14

see here :

(string? "sk-c-5")
=> true 

dpsutton15:12:44

can you put the spec for objectNumber?

roelof15:12:44

@dpsutton here are all the specs :

(def id-regex #"[a-z]{2}-[a-z]-\d{1,2}")

(s/def ::id-type (s/and string? #(re-matches id-regex %)))

(s/def ::objectNumber ::id-type)

(s/def ::id-list (s/coll-of
                   (s/keys :req-un [::objectNumber])
                   :kind vector?))
 

roelof15:12:10

they are the same as yesterday only ::id is changed to ::objectNumber

dpsutton15:12:39

so object number expects a string of a certain format and you passed it a vector of maps?

dpsutton15:12:54

you shouldn't expect that to pass

dpsutton15:12:07

looks like a valid ::id-list but certainly not objectNumnber

dpsutton15:12:18

look at the output

dpsutton15:12:31

[{:objectNumber "lkajsdf"}] is not a string

dpsutton15:12:35

and I agree with it

roelof15:12:07

you are right. Im mixing things up

roelof15:12:48

How must I change this : (s/keys :req-un [::objectNumber]) so this one will be valid :

(s/explain ::objectNumber-list [{:body{:artObjects{:objectNumber "sk-c-5"}}}]) 

seancorfield18:12:51

@roelof That data structure is not a ā€œlist of object numbersā€. It is a list of maps containing a :body key. And the :body in this case is a map with an :artObjects key. And that in turn would need a spec (that references ::objectNumber). So you need a whole stack of specs here that you can nest to match the overall structure.

roelof18:12:08

oke, so for each step I need to make something like this :

(s/def ::objectNumber-list (s/coll-of
                   (s/keys :req-un [::objectNumber])
                   :kind vector?))  

roelof18:12:00

then I have to find out how I can tell that they all are depend on each other

seancorfield18:12:25

You have to describe the data structure you expect ā€” and you have a nested data structure: it is not just a collection of maps with :objectNumber as a key ā€” it is more deeply nested than that.

roelof18:12:42

I understand , I try to say I have to think well how to describe the nested data structure

roelof18:12:33

I can make a def with one level and and another with the next level but I have to think how I can tell how the second is a part of the first

roelof19:12:10

@seancorfield can you give a hint how I can do that ?

sb19:12:08

Hello, I have a little problem with Clojure-Nginx server config again. Could you help me? My error message here:

sb19:12:38

"handle empty body or null body"

sb19:12:45

but I donā€™t know how to fix it

sb19:12:03

somebody idea?

sb19:12:14

(how can I handle this eg. with compojure? maybe very ugly question..)

roelof19:12:43

Could this trick :

(s/def :animal/dog (s/merge :animal/common
                            (s/keys :req [:dog/tail? :dog/breed]))) 

roelof19:12:56

to make one spec for a nested map structure

seancorfield21:12:23

@roelof Think about it step by step. What would be a spec for the :artObjects sub-expression? Then how would that spec be used to define a spec for :body? Your [{:body {:artObjects {:objectNumber ā€œx-a5ā€}}}] is a coll-ection of :art-object/body data structures, yes? and :art-object/body isā€¦ what? Itā€™s a mapā€¦ so it has keys (well, if it is a map? I would have expected it to be a coll-ection of ::art-object which in turn was a map, with some keys which include ::objectNumber?)

seancorfield21:12:11

(note that Iā€™m using :art-object/body as a spec name to distinguish it from other types of :body data structures you are processing ā€” you can use a namespace qualifier with keys in :req-un to tell unqualified keys apart in different contexts)

roelof21:12:45

@seancorfield thanks for that explanation. I have not looked it that way

roelof21:12:21

I think I can make this work

roelof21:12:35

I have to work from the inside out

roelof21:12:43

Time to experiment

blogscot22:12:36

Hi everyone, I have a quick question.

blogscot22:12:51

I'm trying to require clojure/math.numeric_tower in a file, but I can't figure out the correct syntax. It works in the repl

(require '[clojure.math.numeric-tower :as math])
but
(:require [clojure/math.numeric_tower :as math]
in a file doesn't work šŸ˜ž

dpsutton22:12:57

(ns example.core
  (:require [clojure.math.numeric-tower :as math]))

dpsutton22:12:02

from their documentation

dpsutton22:12:20

note you have a / instead of a .

blogscot22:12:33

I've been hacking various things for a while.

blogscot22:12:57

It seems it works in lein repl but not in cider nrepl. I'll shut everything down and try again.

dpsutton22:12:11

can you explain what you mean by cider nrepl?

dpsutton22:12:20

and did you correct your typo?

blogscot22:12:30

yeah. I copy-pasted your example. cider nrepl is one of the repls that emacs uses.

dpsutton22:12:01

i know. i'm trying to understand why it didn't work

dpsutton22:12:16

so in lein repl, you're typing in the (require ...) form

dpsutton22:12:39

whereas for "cider nrepl" you are editing a file so you're putting the (:require [...]) form inside your ns form?

dpsutton22:12:49

I just want to make sure I'm up to speed on what's going on

dpsutton22:12:07

it works in a repl but not from eval'ing a file

dpsutton22:12:10

is what I think you mean

dpsutton22:12:14

so tell me if i'm way off base

blogscot22:12:35

In emacs I'm trying it in both ways: a) inside a file and b) directly inside nrepl

dpsutton22:12:12

and you added it to your project.clj file?

dpsutton22:12:16

(assuming lein here)

blogscot22:12:55

yeah. I ran lein deps; it seems to be in the classpath too. I also checked the installation folder.

blogscot22:12:23

I restarted emacs...

blogscot22:12:44

It seems happier.

blogscot22:12:45

I started learning emacs yesterday, so screwing things up is par for the course.

dpsutton22:12:48

meaning its up and running?

dpsutton22:12:54

its certainly a lot to take in

dpsutton22:12:59

I think you'll find it rewarding

dpsutton22:12:08

I nervously picked it up a year or so ago and I have loved it

dpsutton22:12:18

did that solve your issues with importing though?

dpsutton22:12:27

just want to make sure you're in a state where you can keep working away

blogscot22:12:28

Everything working now šŸ™‚

blogscot22:12:54

thanks for your help.

dpsutton22:12:08

what the channel is for šŸ™‚

dpsutton22:12:18

Im a big fan of CIDER so i'm glad its workinng for you

dpsutton22:12:31

if you run into weird issues please by all means open up a ticket

dpsutton22:12:42

its also super easy to get started on working on it

dpsutton22:12:48

bug fixes, etc

tosh22:12:31

i have a situation where I run out of memory (an advent of code example where I build up a massive persistent vector over many iterations) now I wonder is there a way to tell clojure to create a ā€˜newā€™ persistent vector every time instead of doing structural sharing?

dpsutton22:12:23

wouldn't that increase memory usage?

tosh22:12:44

i have tried making it transient but then some of the functions no longer work, seems like there is no rseq! or concat! but maybe iā€™m doing sthg wrong šŸ™‚

tosh22:12:42

@dpsutton iā€™m not sure if i understand the behaviour of structural sharing in the data structures but i am basically mutating the persistent vector all the time and turning all values into completely different values with every iteration

tosh22:12:19

so I expect that without structural sharing and with creating an entirely new data structure every time it would use less memory

tosh22:12:01

but iā€™m unclear how to figure out whether my code right now is actually holding on to the data/using structural sharing or not šŸ™‚

dpsutton23:12:19

my understanding is the bits no longer shared can be GC'd so structural sharing is always (TM) as compact as possible

dpsutton23:12:27

but its possible my understanding is a little naive

tosh23:12:33

makes sense, it might also be possible that i just need more memory in general because the vector is simply to large

dpsutton23:12:05

yeah presumably

dpsutton23:12:09

i was looking up invoking the GC

dpsutton23:12:18

and the answer seems to be jvm is smarter than you

dpsutton23:12:24

and will collect

tosh23:12:40

thatā€™s the error iā€™m getting btw šŸ™‚

tosh23:12:51

thanks for the pointer @dpsutton

dpsutton23:12:03

I'm way out of my depth on this one

dpsutton23:12:15

there are some knowledgeable people here who can hopefully help

dpsutton23:12:15

I was hoping sean would look at this but didn't want to ping him

seancorfield23:12:15

@tosh sounds like your code is ā€œholding onto the headā€ of a data structure rather than just processing it?

dpsutton23:12:32

I saw the notification that you were typing

dpsutton23:12:49

I hate pinging people in beginners who aren't actively in the conversation. I was just hoping you could lend your experience šŸ™‚

seancorfield23:12:59

Did a link to the code in question get posted? It may just be runaway recursion or a loop? Although if the data structure truly is ā€œmassiveā€ and needs to be, then maybe itā€™s just a question of raising the JVM heap limit...

tosh23:12:19

i think on a meta level there is probably a more clever way to solve it if i read up on dragon curves (hint in the advent of code riddle description)

tosh23:12:53

i chose to model the problem with a persistent vector containing booleans whereas he is using strings

tosh23:12:01

maybe the advent of code day 16 part 2 challenge is deliberately set up in a way where naively solving it will have you run into memory issues inherently

tosh23:12:38

i added :jvm-opts ["-Xmx4G"] to my project.clj and now it completes šŸ™‚