Fork me on GitHub
#clojure
<
2016-12-22
>
gdeer8100:12:04

When you write code that manipulates deeply nested datastructures and then look at it an hour later and wonder how it came to this. But then all the tests pass so... Ship it!

gdeer8101:12:38

@kenny too late, that mess is in production bowtie

gdeer8101:12:37

I vaguely remember seeing Nathan's talk a while back. Lets see if specter can make this code pretty

wei02:12:39

is there a function where I can wrap a function in the regex replacement? basically (clojure.string/replace s #ā€some-regex" ā€œ$1ā€ f) and the substitution for each match would be f(match).

gfredericks02:12:46

the normal version of clojure.string/replace that takes a function doesn't suffice?

gfredericks02:12:44

e.g., (clojure.string/replace "thomas" #"[aeiou]" #(str % %)) => "thoomaas"

sound2gd02:12:51

how to get java class function's console out put when working in clojure?My java class has System.out.println but I have not seen them in clojure repl. like (.method-that-uses-println (new MyClass)) ,what happened?

gfredericks02:12:20

@sound2gd how are you starting the jvm?

sound2gd02:12:50

I simply use lein repl

gfredericks02:12:14

in a terminal? and you're calling that code from that same terminal?

sound2gd02:12:31

use cider in emacs

gfredericks02:12:46

does the output happen in the terminal window where you called lein repl?

gfredericks02:12:15

but you did call lein repl yourself, you didn't have cider start it for you?

sound2gd02:12:50

I have cider-connect-repl to connect to that terminal's repl

gfredericks02:12:22

if you started it yourself and don't see the output in the terminal, then I don't know.

gfredericks02:12:54

System.out.println doesn't generally go to the same place as (println), especially using editor integration

sound2gd02:12:57

even if I try cider-jack-in, no answer

gfredericks02:12:11

I would try a standalone lein repl without any cider or emacs

sound2gd02:12:16

er...how to re-use your tool-fucntion then

sound2gd02:12:35

I mean writing functions in repl

gfredericks02:12:07

I wasn't suggesting you permanently give up emacs & cider, I mean just to debug your current problem

sound2gd02:12:35

tks ,worth a try

sound2gd02:12:31

cider cause it ,I call (.println java.lang.System/out "12345") and don't see the output,but in terminal I get it ,thanks @gfredericks

wei06:12:33

didnā€™t know that existed. awesome

alexisvincent07:12:42

Does anyone here use Spectre? Can you give a brief experience report? Yay or Nay? If its anywhere as good as Haskells lens lib, Iā€™m sold šŸ˜„

sveri08:12:49

@alexisvincent I can not compare it to any other lens lib, but for me it is a definit yay as soon as my maps gain a depth > 2

roelof08:12:40

my homepage looks like this. The first page can be found with just / . Next pages are found with /pages=x . Must I make two seperate routes or can one route handle both cases

alexisvincent08:12:47

@sveri and performance? It seems significantly slower when uncompiled

alexisvincent08:12:19

I wonder actually if the author wouldnt be able to cache compiled paths from inline usagesā€¦ Shouldnt be hard?

sveri08:12:23

@alexisvincent I only do personal stuff for me and never had to take care of that, so I can not answer your question. That said, in general, wait and see if you hit performance problems within your application at all and if so, if they are specter related.

mpenet10:12:58

+1 for specter

mpenet10:12:39

I was sceptical at first but now I am sold for deep transformations

nathanmarz10:12:39

@sveri @alexisvincent inline caching was implemented in Specter awhile ago, and it's blazing fast

nathanmarz10:12:47

no need for manual compilation anymore

nathanmarz10:12:53

in many cases it's actually difficult to write code that's faster than specter

sveri10:12:47

Whoa, it is even faster than clojures update-in?

sveri10:12:54

Did I read that right?

nathanmarz10:12:49

yes, update-in in 1.8 and below is quite slow actually

puzzler10:12:55

@alexisvincent Specter is a generalized approach to transforming and updating immutable data structures, encompassing things like get-in, update-in, assoc-in, map, filter, and a lot more. To get my feet wet, I decided to use it for a day in place of all the spots where I'd typically use get-in, update-in, or assoc-in (in many cases, Specter is faster than the Clojure built-ins, so there's no reason not to do that). Before I knew it, I was seeing all sorts of other places in my code that could be made more elegant with Specter. I'm not 100% convinced that Specter has been distilled down to the simplest possible set of composable navigators - the fringes of the library still seem pretty complicated to me. But even if you stick with the core, bread-and-butter navigators of Specter and ignore the parts you don't understand, it's definitely a win over vanilla Clojure. Only real downside I can think of is that because it puts the navigator as the first input rather than the data structure, and doesn't take extra optional inputs for the transform, it's not as swap! friendly as update-in.

nathanmarz10:12:15

update-in is improved for 1.9 but specter is still 30% faster

puzzler10:12:53

@sveri To better understand intuitively why Specter is faster than update-in, basically update-in with something like [:a :b: :c] as the keypath is dynamically traversing that sequence every time it is called, whereas Specter analyzes it once and figures out that it can just rewrite the code as (:c (:b (:a m))).

sveri10:12:57

@nathanmarz @puzzler Ah, my first guess was that you are doing some native Java stuff underneath, but instead, you transform it to a different AST, right?

robert-stuttaford10:12:16

we use enlive pretty heavily. i wonder how much of a boost a specter based system would give us

robert-stuttaford10:12:39

since enlive is really just a dsl for manipulating a nested map structure with a small set of known keys

puzzler10:12:24

If you call it with a general keypath that's in a variable like path, Specter can't do as much with that so it falls back to a strategy like update-in. At least, that's my understanding. Nathan's the expert, of course.

nathanmarz10:12:05

not exactly, actually it's super fast in pretty much all cases

puzzler10:12:15

@nathanmarz In theory, if you only are using a given callsite once, are you paying a slight perf penalty?

nathanmarz10:12:27

unfortunately I don't have a single up-to-date resource on how the implementation works

nathanmarz10:12:50

@puzzler yea, but it's extremely minor

nathanmarz10:12:01

two getfield's basically

robert-stuttaford10:12:07

nice to see transducers in the perf comparisons

nathanmarz10:12:18

oh you mean with the compilation

nathanmarz10:12:34

yes, the first time through will be slower

puzzler10:12:37

yeah, the analysis time is what I meant.

alexisvincent10:12:16

@nathanmarz thanks šŸ™‚ nice lib šŸ™‚ I watched your video earlier and thought you were still doing explicit path compilation

alexisvincent10:12:46

@puzzler Thanks for the experience report

riseremi10:12:42

Hello everyone! Does anyone use this library? https://github.com/Otann/morse

riseremi10:12:28

I'm new in Clojure and I have some problems trying to create my bot. It silently stops right after the lein run. I've copied the code from the readme but nothing works.

alexisvincent10:12:09

@riseremi It might be that it starts in another thread. So you need to block your main thread so that it doesnā€™t exit

riseremi10:12:43

@alexisvincent I'll try that, thank you!

sveri10:12:35

@nathanmarz Impressive, all in all, not only the lib, but also the posts about the technical details šŸ™‚

riseremi10:12:46

@alexisvincent it works. Thanks a lot :thumbsup:

alexisvincent11:12:13

@riseremi This bit me when I started with clojure as well šŸ™‚

nathanmarz12:12:07

@sveri @alexisvincent feel free to drop by #specter if you have any questions

dpsutton14:12:37

@nathanmarz i remember you said you were working on spectre with graphs but it wasn't ready for primetime. Has that been implemented yet?

nathanmarz14:12:19

@dpsutton I have an extensive set of navigators built on top of Loom that I have not open-sourced

dpsutton14:12:31

i remembered you saying that in seattle

nathanmarz14:12:32

I want someone from the community to make an open source version (with my guidance)

nathanmarz14:12:43

so far there haven't been any takers

dpsutton14:12:45

what do you mean?

dpsutton14:12:42

are there multimethods or protocols that are available for extending?

nathanmarz14:12:57

yea, specter is completely extensible

dpsutton14:12:01

so you can easily make "plugins" or additional navigators for other structures?

dpsutton14:12:04

oh that's really cool

dpsutton14:12:10

that's some really well designed stuff

dpsutton14:12:23

you also made spark, did you not?

nathanmarz14:12:28

no, i made storm

dpsutton14:12:33

ah apologies

Aron14:12:52

i am trying to find the respective documentation for this https://nodejs.org/api/modules.html#modules_all_together in clojure. My issue is that I am not even aware of the accurate keywords too google in this case, could someone give me some pointers please?

sveri14:12:57

@ashnur I suspect you want to find all packages / namespaces of the clojure library

Aron14:12:03

that's not that

sveri14:12:31

Ok, than I misunderstood the question.

Aron14:12:43

this is more like about the build processes, what are my options on where I can "require" from, I realize that in clojure there is no unique "require" and build process but as I said, i am not even sure what to look for

sveri14:12:27

Ok, maybe if we approach it differently. What do you want to achieve?

Aron14:12:55

so when you are writing something there has to be a number of options on how to require dependencies, the link i shared contains the accurate description how the string is interpreted that is given to require. I am trying to find the same solutions in clojure land, at the same level of detail

Aron14:12:18

that certainly helps, thank you, however my problem with these stackoverflow answers that i can not be sure they are exhaustive

Aron14:12:59

yes, i that too, thank you

sveri14:12:24

99% of the time I only need require.

sveri14:12:50

I am not sure if you are asking because you want to write documentation or something similar or just need some practical advice for day to day work.

Aron14:12:04

i am asking because i want to know šŸ™‚

Aron14:12:44

not sure why everyone is suggesting beginners to write clojure documentations, no wonder it looks how it looks

sveri14:12:38

Tbh. I have not found any documentation on the point for your question. At least none that says: these are all the options you have.

sveri14:12:45

Here is something that comes close I guess: http://clojure.org/api/cheatsheet

sveri14:12:59

Look at "Loading"

Aron14:12:36

well, the environment is more complicated than in node, it would be unfair to ask for the same thing, i am just collecting all the relevant docs and hopefully it will be somewhat complete šŸ™‚

sveri14:12:56

*Cough *Cough Uhm, nope

Aron14:12:18

what do you mean?

sveri14:12:14

My personal and subjective opionion is that node is the developers hell where writing assembler is the land of the sanes compared to it. And I find the clojure sphere way easier to understand and get into.

sveri14:12:39

The cheatsheet also has a link to a very exhaustive tutorial

sveri14:12:52

While all you need to know in this respect, as a beginner, is, just use "require"

sveri14:12:17

I hope I dont sound to arrogant or so, I really do not want to be that.

tbaldridge14:12:21

@ashnur the documentation on clojure.core/require and clojure.core/import are going to be the two best places to find what you're looking for

tbaldridge14:12:43

The clojuredocs site copies that verbatim ^^

Alex Miller (Clojure team)16:12:25

I find https://stuartsierra.com/2016/clojure-how-to-ns.html to be a pretty useful overview of the parts of ns that you should probably use 99% of the time

roelof16:12:34

my homepage looks like this. The first page can be found with just / . Next pages are found with /pages=x . Must I make two seperate routes or can one route handle both cases

sveri16:12:51

@roelof I would suggest you take a look at: https://github.com/weavejester/compojure/wiki/Routes-In-Detail this should answer your question šŸ™‚

roelof16:12:44

it seems that I have to make 2 seperate routes @sveri

sveri16:12:18

@roelof Are these the same "site" or two different sites?

roelof16:12:32

It's the same site . The homepage exist of multiple pages

roelof16:12:57

and I want the first page to be avaible as / and the rest as /pages=n

roelof16:12:16

where of course / will the same as /pages=1

joakimmohn17:12:39

im trying to save an array of images to my postgres db. This is the ring handler:

(POST "/file" []
                 :multipart-params [files :- [TempFileUpload]]
                 :current-user user
                 (doseq [file files]
                  (db/save-image! user file))
                 (ok))
If the images are small (< 50kb) all the images gets stored to postgres no problem, but if the images are bigger the operation takes too long and i get batchupdate exception. How can I ensure that the image is stored before the next image is processed?

sveri17:12:40

@roelof Usually pagination is applied as parameter, so it would be "/?page=3&per_page=10" or something similar.

sveri17:12:03

From my point of view thats one route then which takes extra parameters, where the parameters can be empty of course and take a default value then.

roelof18:12:41

@sveri then I have to find out how that works.

agile_geek18:12:15

@roelofw actually you can do it with one route.

agile_geek18:12:29

if it's a query param

roelof18:12:15

oke, sveri told me that I could do it with a optional parameter

roelof18:12:28

just reading how to do that.

sveri18:12:59

@roelof Actually we mean the same. The query parameter can be ommitted, and if it is, you want to deliver the first page and x images

roelof18:12:03

now Im confused

roelof18:12:03

The route is now (GET "/" [] (home-page))

sveri18:12:30

@roelof You need to read more about the topic in general. Read up on designing APIs with parameters.

roelof18:12:33

and I need a route (GET "/?page=3 ) `

sveri18:12:45

You are confused, because you lack knowledge.

roelof18:12:47

oke, I will google for some info

agile_geek18:12:48

@roelofw try stepping back for 30 mins and reading about compojure routes. Then think about what if the parameter was nil what could you do to provide a default (presumably page 1)

agile_geek18:12:43

It's better to try and understand the topic of routing in general than look for a specific answer that way you can figure out what to do in a different scenario.

roelof18:12:32

Im finisched reading compojure routes in detail

roelof18:12:40

so if I make a routes like this (GET "//?page=:page" [page] (home-page))

dpsutton18:12:13

let's head into #beginners

noisesmith18:12:08

@sound2gd @gfredericks - cider puts java output in a hidden server buffer, this is considered "won't fix, working as designed" by the cider team. The fixes are using cider connect to a repl running in a regular terminal, or checking the automatic hidden buffer that cider puts your output in

noisesmith18:12:51

I always forget what the name of that hidden buffer is though

gfredericks18:12:11

@noisesmith I thought of that but @sound2gd kept saying that they started lein repl manually

noisesmith18:12:33

but then mentioned cider-jack-in - I assumed it was a miscommunication of some sort

noisesmith18:12:19

oh, I just misread, sorry for the noise

tdantas21:12:10

good night everyone. Iā€™m trying to do a hashmap with all prefixes from an argument my solution was:

(defn prefixer [word]
  (first (reduce (fn [[out prefix] current]
                   (let [entry (str prefix current)
                         updated (update-in out [entry] #(if %1 (inc %1) 1))]
                     [updated entry]))
                 [{} ""]
                 word)))
that will outputs
(prefixer "olivia")
=> {"o" 1, "ol" 1, "oli" 1, "oliv" 1, "olivi" 1, "olivia" 1}

tdantas21:12:18

any more elegant way to do that ?

manutter5121:12:48

@oliv are you familiar with the reductions function?

tdantas21:12:15

let me check the doc

manutter5121:12:38

I donā€™t know if thatā€™s helpful or not, but thatā€™s what the shape of your output reminded me of

tdantas21:12:56

thank you so much

tdantas21:12:05

just saw the doc, looks really like my output

mokr21:12:06

Hi, I'm looking for advice on how to get output of eg. tcpdump into a core.async channel. clojure.java.shell doesn't look like the right tool. Anyone?

mokr21:12:19

"tcpdump" could be replaced by "tail -fā€ or anything else that gives an ā€œendlessā€ stream of output.

mokr21:12:39

Thanks, I will have another look at it.

noisesmith21:12:59

it's also quite straightforward to use ProcessBuilder to make a Process yourself - sometimes treating input as a stream is actually easier than treating a lazy-seq that comes from a stream as a stream

noisesmith21:12:16

especially since your destination is a channel

nikki23:12:45

wondering if it's a good idea for booleans-as-function to be if

nikki23:12:57

like (if (nil? x) a b) becomes ((nil? x) a b)

noprompt23:12:19

@nikki that wouldnā€™t work without direct support in the compiler since both a and b would need to be evaluated.

nikki23:12:25

oh i forgot about that part lol

nikki23:12:08

i guess the compiler would not know at macro-time whether what (nil? x) is meant to be

nikki23:12:26

but at macro-time it knows statically that if is a macro

noprompt23:12:53

if isnā€™t a macro though, itā€™s a special form.

nikki23:12:00

oh yeah oops

nikki23:12:35

but if there was some other conditional special form and if wasn't you could impl as a macro to do no-eval of a or b too still

noprompt23:12:37

you could write a macro to do something like rewrite the code with thunks everywhere like so

noprompt23:12:39

(let [ret (nil? x)
      a-thunk (fn [] a)
      b-thunk (fn [] b)]
  (if (boolean? ret)
    (if ret
      (a-thunk)
      (b-thunk))
    (ret (a-thunk)
         (b-thunk))))

nikki23:12:31

that's neat

nikki23:12:37

clojure is awesomeeeeee

nikki23:12:11

so excited lol, reading through the first part of Living Clojure and hoping to do the 7 week program thing soon but might compress it to less than 7 weeks šŸ˜›