#clojure log - Dec 12 2015

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

0:00 justin_smith: ,(let [in [1 2 3 [4 5]]] (into (pop in) (peek in)))

0:00 clojurebot: [1 2 3 4 5]

0:01 justin_smith: that of course relies on knowing that the last item is the thing to merge with the rest

0:01 amalloy: justin_smith: (partial apply list*)

0:02 justin_smith: aha!

0:03 ,(apply list* [1 2 3 [4 5]])

0:03 clojurebot: (1 2 3 4 5)

0:03 justin_smith: nice

0:14 TEttinger: justin_smith: wow cmd is terrible

0:14 cmd /S /C " java -jar %HOME%/.m2/repository/org/clojure/clojure/1.7.0/clojure-1.7.0.jar -e "(println \"hell

0:14 o world\")" "

0:14 that's what it took

0:14 justin_smith: aha

0:14 TEttinger: (yeah it took me over 20 minutes to figure out what odd tweaks it needed...)

0:15 it is pretty fast though

0:15 justin_smith: but hey, bright side is you have the basis for running clojure from a script :)

0:15 TEttinger: another cool option: make an uberjar containing all the deps you would use in a shellscript

0:16 TEttinger: also fun: $help time -> Displays or sets the system time.

0:16 justin_smith: then write a clojure ns as a shebang - remember #! on the beginning of a line is a comment

0:16 haha

0:16 so wait, was /S or /C the thing that showed the time elapsed?

0:20 TEttinger: you overestimate my abilities with cmd

0:20 the /C tells it to execute another command, the /S tells it don't mess with quotes in it

0:20 justin_smith: oh - so you didn't get it to time

0:20 TEttinger: yep

0:21 I have a timer utility somewhere

0:21 justin_smith: you could implement it with clojure using clojure.java.shell/sh :)

0:29 TEttinger: wow this was just wonderful

0:29 apparently the timer itself may do some redirection

0:29 C:\dev\TIMETHIS java -jar %HOME%/.m2/repository/org/clojure/clojure/1.7.0/clojure-1.7.0.jar -e \"(println \\\"hello world\\\")\"

0:29 only the triple backslashes seemed to escape quotes properly in code

0:30 justin_smith: wow

0:31 TEttinger: nethack 3.6 came out, btw

0:31 TEttinger: I saw!

0:31 have not played yet

0:31 justin_smith: among other things it has the new amusing message "it won't come off its hinges" - bet you can figure out how to make that one happen

0:31 TEttinger: I heard someone died to "a gnome lord wielding 5 daggers"

0:32 not sure how that happens

0:34 justin_smith: TEttinger: looks kind of like wolverine, but 3 foot high, wearing a pointy red cap

0:35 TEttinger: I was thinking he was very good at juggling

0:35 justin_smith: oh yes, gnomes are good jugglers

0:36 and a gnome lord with 5 daggers, well he can juggle them right up to your jugular!

0:36 TEttinger: I wonder where Raynes is

0:36 I had a question/possible complaint about a refheap behavior

0:37 (pasting large amounts of text, even with plain text syntax highlighting, freezes the browser)

0:37 justin_smith: TEttinger: is line length a factor there?

0:38 TEttinger: it was something like https://gist.githubusercontent.com/tommyettinger/9079f8f882db658f301f/raw/eb452cd90915c558cd9ece03ee30af829dda059e/layer-dungeon.txt

0:38 240 char wide lines

0:39 ,(* 121 16) ;; lines

0:39 clojurebot: 1936

0:39 TEttinger: ,(* 121 16 241)

0:39 clojurebot: 466576

0:39 TEttinger: so half a megabyte

0:43 oh haha utf-8

0:43 right so much more than half a MB

0:45 justin_smith: TEttinger: utf8 is fairly compact - 590k

0:45 TEttinger: I just downloaded and measured

0:47 TEttinger: nice

0:47 ...hm

0:48 justin_smith: utf8 is the best

0:48 TEttinger: thinking about the ol' hilbert curve

0:50 I wonder what ways there are to compress text

0:50 all the compression work I've done is very specialized and meant for spatial data

0:54 justin_smith: TEttinger: what about trying to make a path that optimized the run length of a given token when walking the 2d space of that file

0:54 different curves should end up with different average run lengths (and thus different compression ratios in run length encoding)

0:58 TEttinger: I think one size opt that could be done on most UTF-8 text is to use a "custom unicode codepage" of 256 chars that are only the most frequently used in the document

0:59 justin_smith: TEttinger: for sure, - and for docs like yours, you could even reduce it to like 3 bits per char, because that's enough to encode every char you use uniquely

1:00 err, make it 4 bits, oosp

1:01 TEttinger: not sure 16 items would do it

1:02 yeah, I think I'm like 3 over

1:02 justin_smith: TEttinger: oh? 6 for the solid walls, one for empty space, one for dug out, one for lit space?

1:02 oh

1:03 TEttinger: solid walls are 11 chars

1:03 justin_smith: I forgot the ts

1:03 TEttinger: 

1:03 ,"

1:03 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading string>

1:03 TEttinger: come on IRC!

1:34 justin_smith: TEttinger: woah, I spammed myself out of my client - I hope I didn't accidentally paste any dungeon before the client went down

1:35 TEttinger: ha, nope

1:35 justin_smith: TEttinger: sometimes paste is a terrible mistake

1:35 half a meg of dungeon ascii, heh

1:35 TEttinger: unicode!

1:46 justin_smith: TEttinger: ever see this? it's a curated list of "nasty" strings for fuzz testing https://github.com/minimaxir/big-list-of-naughty-strings/blob/master/naughtystrings/internal/resource.go#L530

1:46 could be the basis of a simple unit test helper lib

1:56 TEttinger: neat

3:37 BRODUS: whats the most succinct way to tell if a number is between a range?

3:37 opqdonut: ,(< 1 2 3)

3:37 clojurebot: true

3:37 opqdonut: ,(< 1 4 3)

3:37 clojurebot: false

3:45 BRODUS: opqdonut: thanks

3:55 conprehendant: How do I destructure an array of this: http://pastebin.com/1TgZL1PV ?

5:19 oracle: hi

5:19 hji

5:19 BRODUS: yo

5:19 oracle: (transduce (comp (take-while true?)

5:19 (map (fn[x] (println x) true))

5:19 )

5:19 conj

5:19 []

5:19 (map inc (range 4)))

5:19 why that code doesn't print anything?

5:20 since the map always return true, so take-while consume all the data

5:20 so I expected it to print 1,2,3. But it doesn't print anything, and the result is emtpy of []

5:24 allenj12: Hey has anyone here tried clojure in the atom editor? Im doing alot of stuff in windows lately and i dislike emacs in windows

5:25 MJB47: i use ST3, is that close enough?

5:25 oracle: anyone know transduce in clojure 1.7?

5:26 allenj12: MJB47: not really an nrepl for sublime like there is in emacs is there?

5:26 MJB47: there is sublimeREPL

5:26 but

5:26 its pretty shit

5:27 allenj12: MJB47: gotcha, maybe i should try emacs in windows, or just suck it up and reboot everytime i need to switch back and forth

5:27 MJB47: you could also try cursive

5:29 allenj12: MJB47: I thought about that and will probably try it but i wanted something more general cause i work in multible languages

5:29 MJB47: yeah i hesitate for the same reason :(

5:51 allenj12: MJB47: welp the atom repl looks shitty to

5:51 MJB47: :(

5:56 oracle: (transduce (comp (take-while true?)

5:56 (map (fn[x] (println x) true))

5:56 )

5:56 conj

5:56 []

5:56 (map inc (range 4)))

5:57 sorry, pasted wrong

5:59 keep_learning: Hello everyone

5:59 Pardon me if I sound stupid.

5:59 I am planning to do some work with stanford nlp

6:01 and planning to use [me.arnaudsj/corenlp "3.5.2"]

6:01 My job is very much similar to extracting the dependencies http://stackoverflow.com/questions/5449098/stanford-parser-how-to-extract-dependencies

6:02 from a syntax

6:02 so I am wondering if I can do this with current version of corenlp "3.5.2"

6:08 oracle: for tranducer, why the following code doesn't print anything?

6:09 http://paste.lisp.org/display/166410

6:09 I also asked in in stackoverflow: http://stackoverflow.com/questions/34238843/transduce-why-this-transduce-doesnt-print-anything

6:28 justin_s1ith: ,(transduce (comp (map (fn [x] (println x) true)) (take-while true?)) conj [] (map inc (range 4))) ; oracle

6:28 clojurebot: 1\n2\n3\n4\n[true true true true]

6:30 justin_s1ith: oracle: when you call comp on the transducer arg, it isn't composing the functions, it's composing the transduction - which effectively means it is reversing the args to comp

6:30 oracle: because a transducer takes a function as an arg, and returns a new function

6:30 the function that gets returned is what finally sees the collection

6:35 sunset-shimmer: hello, guys!

6:42 I have a complex structure (vector of maps) and I need to "remove" the given item from it. I can accomplish this with (->> [{:a 1} {:b 2}]) (remove PRED)) form. Lets say I need to remove item where :a is 1, is there a concise way to write a predicate?

6:43 It seems like I can use deconstruction here.

6:44 or just #( (= (:a %) 1) ) is the best way?

6:44 justin_smith: ,(remove (comp #{1} :a) [{:a 1} {:b 2}])

6:44 clojurebot: ({:b 2})

6:45 justin_smith: that version is probably only better if you have more than one relevant value - eg. if it was #{1, 3, 4}

6:50 sunset-shimmer: justin_smith: great! It looks better and I didn't aware of this function. I'll check its description. Thank you.

6:51 BRODUS: would anyone be willing to code review my solution to this 4clojure problem: https://www.4clojure.com/problem/94 ?

6:54 link to solution: http://pastebin.com/wYAHRSQm

6:54 justin_smith: sunset-shimmer: #{} is the literal syntax for sets

7:08 sunset-shimmer: okay, I see! and then you check if the given set contains element that we extract from map by property. Now I can articulate more complex predicates for finding exact items in a vector of maps like (#{{:color lavender :type unicorn}} {:color lavender :type unicorn}) or just find what I want by id, if I'll decide to use identifiers. It was very helpful!

7:41 BRODUS: ,((fn [& args] (count args)) nil nil nil)

7:41 clojurebot: 3

7:49 justin_smith: ,((comp count list) nil nil nil)

7:49 clojurebot: 3

8:54 jonathanj: how does one usually handle errors with something like core.async?

8:54 have a separate channel for putting errors on?

9:13 sunset-shimmer: Is it fine to generate unique ids with (keyword (gensym)) construct? :)

9:17 zamaterian: sunset-shimmer, only if the are not persistet, they are probably not unique across jvm invocations. better use uuids

9:49 C4K3: Is it not possible to use anonymous functions in the -> macro? For example (-> 2 (fn [x] (+ x 1))) throws an error, but if I make a named function that does the same thing, then it works fine

9:52 MJB47: ,(-> 2 ((fn [x] (+ x 1))))

9:52 clojurebot: 3

9:52 C4K3: I see, thanks

9:55 uptown: i am trying to build a local jar which does not have a main and install it in my maven repo for reuse. what do i put in my jar manifest? (i use boot if that changes things)

11:47 Trioxin: if I have a random number generator and I'm calculating times that the numbers are seemingly more non-random, would the non-randomness be considered lower entropy?

11:55 C4K3: How do I pass a list to recur, without doing (recur (first mylist) (second mylist)) and so on? If I try (apply recur mylist) then it says Unable to resolve symbol: recur in this context.

11:56 MJB47: you could just past the list as normal, and then within the body of whats being looped, desctructure it with let

11:57 you could also just have 2 arguments and do head-tail recursion, (recur (first mylist) (next mylist))

11:57 unless i am misunderstanding the problem

12:06 C4K3: I don't understand the second solution, what's head-tail recursion?

12:12 Sorry I lost connection, if you responded I didn't see it

12:39 MJB47: C4K3: (loop [i 0 r (range 3)] (println i) (if i (recur (first r) (next r)) "done"))

12:39 like this

12:44 justin_smith: uptown: what info does boot want for the jar manifest? (I'm used to lein where it's auto-generated, and it doesn't really matter whether I have a main)

13:05 C4K3: also, a loop/recur that always visits every item in a collection in order can be replaced with reduce (using a collection if you need more than one accumulator value)

14:00 Go3afahb: So say I want to write cljs client(browser)-server(nodejs) app, does it mean that I have to run 3 (cider, figwheel client, figwheel server) java instances in order to get decent dev env?

14:03 justin_smith: Go3afahb: cider is usually 2 java instances as well

14:04 Go3afahb: Oh, so it's 4 javas for a project that actually doesn't use java at all, right?

14:04 justin_smith: right

14:05 domgetter: I'm writing a mandelbrot viewer in Clojure, and I'm wondering if it's a "bad idea" to store a (make-array Integer/TYPE 185000) in an atom so that I can update it mutably. Is that a proper use of atoms?

14:05 MJB47: there is the clojurescript compiler in clojurescript project

14:05 but idk how mature it is

14:05 justin_smith: domgetter: arrays are already mutable

14:05 domgetter: mutable objects inside atoms are terrible - because of retries

14:06 domgetter: ooh, okay, I'll go revisit my implementation then

14:06 so I should just store in a plain old variable?

14:06 justin_smith: domgetter: with immutable objects, retries on swap are no problem - you just keep the last one

14:06 domgetter: (def my-array (make-array ...)) ?

14:06 justin_smith: domgetter: with arrays - your update could run any number of times

14:06 Go3afahb: justin_smith: all right, I guess I just should buy more RAM and stop grumbling.

14:07 justin_smith: domgetter: sure, if it needs to exist at the top level

14:07 MJB47: Go3afahb: how much ram do you have?

14:07 Go3afahb: MJB47: it's 2 (two)

14:07 justin_smith: Go3afahb: you can use lein trampoline to reduce the number of vms used, but clojure is not a lightweight language ram wise, no matter what

14:08 MJB47: this might be my first-world-problem side talking but i dont understand how you can survive on 2gb o.0

14:08 domgetter: justin_smith: Got it. Yea, I'm writing to the array and then letting Swing use the integers to blit to the screen, so I want access to the array to be as fast as possible

14:08 justin_smith: Go3afahb: really though - with one figwheel you can switch targets (switch-to-build client) / (switch-to-build server), and you don't actually need cider

14:09 so you could pull it off with one instance of "lein trampoline figwheel"

14:11 Go3afahb: justin_smith: well actually it's pretty lightweight - never had any problems with it memory-wise, and I humbly hoped that it will be even much more lightweight in its cljs incarnation, but, um, yeah.

14:11 justin_smith: I guess it possible, but not that convenient, yes.

14:11 justin_smith: Go3afahb: the cljs compiler code is not lightweight, and immutable data means your heap usage goes up fast as your app scales up

14:12 Go3afahb: don't want to start a flame war, but it doesn't necessarily mean that, does it?

14:12 justin_smith: in my experience, at least

14:13 Go3afahb: the amount of heap used to store N items in a vector is a lot more than the amount used to store the same number in an array

14:13 the only 1-1 comparison would be LinkedList on the java side and lazy-seq on the clojure side

14:14 Go3afahb: unlike arrays and hash-maps in the java versions, clojure vectors and immutable-hash-maps have a tree structure - trades performance on immutable updates for increased heap usage

14:15 it's an intentional choice of the implementation - to get more speed, plus immutability, by consuming more memory space

14:15 and by "more speed" we mean "a bit closer to as fast as mutable data"

14:16 I love programming with immutable data, and I love using clojure, but we have to be realistic that this design decision exists and has consequences

14:16 Go3afahb: Yes, but it's still incorrect to say that immutable data means higher memory usage.

14:16 justin_smith: Go3afahb: the implementation is guaranteed to use more heap space to store the same amount of data

14:16 even leaving update out of the picture

14:17 Go3afahb: Is it because they are immutable though? And what about sharing?

14:17 justin_smith: Go3afahb: no, it is not because they are immutable - it is because of the internal structure that optimizes the immutable updates

14:17 eg making conj fast even though you cannot modify the original

14:17 Go3afahb: That is correct.

14:18 justin_smith: sharing can help, but in practice doesn't do a lot

14:18 in my experience at least

14:19 my clojure code uses an order or magnitude or more heap to do the same work a java program would use. I see this as a cost I'm willing to pay given clojure's benefits (and occasionally implement something in java or at least using java data structures if that cost becomes too much)

14:20 Go3afahb: An order of magnitude? Really?

14:20 justin_smith: I've seen servers exceed 10 gigs usage (crunching graph data on graphs with 1000 - 2000 nodes, maybe 5 graphs being crunched at a time)

14:22 perhaps this is because of other problems in our code, but if we switch part of the code to do things java style we see the usage drop much lower for that

14:23 Go3afahb: this isn't just because of immutable data structures, I suspect it also has to do with fp style abstractions in the codebase that are not space friendly as well, but I'm not going to win the "don't be so functional" argument with clojure writing coworkers

14:23 Go3afahb: I thought the difference would not be that much. I've never cared to test it myself, but I recall seeing some benchmarks showing something like 10 or maybe 20 percents of the difference. Of course, such benchmarks are always synthetic and are far away from real world, but yeah, it had to be some other factors played the role

14:24 justin_smith: Go3afahb: sure, 10 percent if it's just directly using the structure, but what if you have 7 or 8 levels of functional programming abstraction, each one taking on that kind of overhead as it operates - it adds up

14:25 I'd be delighted to hear our immense heap usage was unusual and caused by a simple mistake we were making that we could fix - we'd save on server bills for sure. But nobody has been able to show me that simple fix.

14:25 I've extensively profiled, etc.

14:26 MJB47: giff access to server repo

14:26 :P

14:26 justin_smith: :)

14:27 Go3afahb: Well yeah, I can only agree with you here, it's kinda more of a style issue than of some particular implementation detail.

14:27 It's worth it though, right?

14:27 MJB47: your in a clojure channel

14:27 we are gonna be pretty bias :P

14:28 justin_smith: oh yeah! we just pay for more ram, and we get good code with a low frequency of bugs

14:28 MJB47: you're*

14:28 justin_smith: immutability helps with that for sure

14:28 MJB47: also depending on your project, memory might not be your bottleneck

14:28 justin_smith: Go3afahb: but if you stick with clojure, I'd expect to use more than 2 gigs of ram on my dev machine

14:29 Go3afahb: justin_smith: ...unless you have to run 5 lein instances on a 5-year old laptop or whatever. Thank god there is still those crazy folks who use C for developing desktop apps!

14:29 justin_smith: well, it was just enough in the times of 1.2, I swear.

14:30 justin_smith: Yeah, that's where it's a problem. They have different limitations and tradeoffs, of course I am glad that most everything on my machine is coded in C so I have ram left over for my stuff :)

14:31 Go3afahb: I'm definitely not going to say clojure couldn't use lest RAM. But realistically it does use a lot, and clojure is typically used for products and services where using more ram is just a button you click on the hosting console and a few bucks extra on the bill at the end of the month.

14:34 Go3afahb: It's not a problem, I agree. It's just kinda funny that clojurescript hasn't actually made it any more lightweight but has done exactly the opposite. Still not sure it's a problem, but it definitely gives different overall feeling.

14:35 justin_smith: maybe the new self-hosting ability will eventually change things?

14:38 Go3afahb: It was actually quite some time since it was announced, isn't it? David is probably more busy with Om and stuff than with fighting lein dependency (I was tempted to call it illness: lein illnes. Sounds kinda cool to me, eh?).

14:41 justin_smith: since lein is mostly about managing deps and node / js have their own ways of doing this, what's to stop you from skipping lein and using clojurescript.jar directly - just the tooling like figwheel that depends on lein?

14:41 or wait, now I am not even certain figwheel depends on lein

14:43 rhg135: Not really, you can use it without

14:44 Go3afahb: Hmm, indeed.

14:45 I should have called it "java illness".

14:45 rhg135: justin_smith: minor problem with that is if you do depend on stuff on the classpath. Then you can use trampoline or save the classpath.

14:45 justin_smith: rhg135: right, I usually use trampoline, and I usually use a single figwheel and use switch-to-build as I work on different js builds

14:46 or even the occasional build-once

14:46 it's a nice balance of the convenience of figwheel without having to have 3 of them running all the time

14:47 rhg135: I usually forego figwheel as it's not so useful in my case

14:48 I just need a noderepl

14:49 Go3afahb: By the way, I can probably run node server in the node-webkit process...

15:03 Trioxin: can't find any clojure or java webrtc clients

15:06 just android stuff

15:09 justin_smith: Trioxin: how about Kurento https://www.kurento.org/docs/5.1.1/tutorials/java/tutorial-2-magicmirror.html

15:26 Trioxin: justin_smith, that's just a java server. I already have a signaling server setup.

15:27 domgetter: Is it normal for the JVM to eat up 1.5 gigs of ram even if I'm not holding onto data?

15:32 Trioxin: i see there are some ways to convert javascript to java automatically such as https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino/JavaScript_Compiler . Was hoping that someone would have made a non-android webrtc client by now though

15:32 justin_smith: domgetter: the jvm will use up to the max you allow - even if it's not all actively used by the jvm at a given moment

15:33 domgetter: this function will show the specifics if you run it https://github.com/littlebird/conduit/blob/master/src/conduit/status_transmitter.clj#L26

15:34 the :unused key is the amount of memory the vm is holding on to but not currently using

15:39 domgetter: justin_smith: awesome, thank you

15:40 tolstoy: domgetter, justin_smith: That's HEAP related stuff, but there's additional process memory not tracked by those stats, right?

15:40 justin_smith: tolstoy: there's permgen, and yeah, that code is not meant to address permgen

15:40 but permgen doesn't exist any more starting with 1.8 anyway

15:40 domgetter: Well I got the mandelbrot calc down enough for real time zooming :)

15:41 justin_smith: also, total permgen size (for vms that still have it) will typically be a small fraction of total heap usage

15:41 tolstoy: No permgen, but loaded classes takes up space. Is that tracked by getRuntime stats?

15:41 justin_smith: domgetter: cool

15:41 tolstoy: now that permgen doesn't exist, it should be reflected in heap memory

15:41 iirc

15:43 tolstoy: I've got a process that reports 205m used, with heap max at 512m, but top reports RES as 425m.

15:44 justin_smith: tolstoy: yes, my code above addresses the difference between what java calls used vs. what the OS thinks is used

15:44 tolstoy: "unallocated"

15:45 tolstoy: Yes, that's how I'm calculating it, too. 'cept I call it "free".

15:46 justin_smith: wait no - "allocated" is the total memory the jvm has gotten from the os, unused (.freeMemory) is the amount of that it doesn't consider used

15:46 so it's saying .totalMemory is 205, but OS shows it with 425?

15:47 tolstoy: Yeah.

15:47 justin_smith: wow, that's way too much for permgen, or whatever replaces permgen

15:48 I wonder what that's about

15:48 tolstoy: Right. I'm on openjdk8. But the JVM is just a C program. It allocates memory for its own uses, one block of which is the heap, right?

15:49 domgetter: justin_smith: Here's the code if you want to take a glance: https://gist.github.com/domgetter/450182edf3e88da7512f

15:49 justin_smith: I guess - but where could usage that big be coming in? massive usage of large static libraries? the vm itself?

15:50 tolstoy: No idea.

15:51 Maybe thread stack.

15:51 81 threads.

15:52 Some ideas: http://stackoverflow.com/a/20093537

15:52 justin_smith: domgetter: if you used an array of two doubles instead of complex, that might make a difference - but rather than speculating, I'd try profiling. You can use hprof, or visualvm which is free. Yourkit is awesome for this, if you want to try a trial.

15:53 domgetter: justin_smith: I came down to the deftype after a lot of trial and error, but only from using (time ...) I'll check those out to see if I can't squeeze out any performance

15:53 justin_smith: tolstoy: oh cool, that's close to what I was thinking, but clearly better thought out and actually researched :)

15:54 domgetter: yeah - I thought the question had been about memory usage, which is why I said that

15:54 domgetter: but the profilers will help both with memory usage and performance, of course

15:54 domgetter: ah okay

15:55 I was more concerned with speed in this app since it's such a cpu-intensive calculation

15:55 justin_smith: domgetter: have you tried turning on boxed math warnings?

15:56 tolstoy: Hm. On linux, default stack size for a pthread is 2MB, which accounts for 162Mb (if similar on FreeBSD).

15:57 LauJensen: Gents, for the life of me I cant import/instantiate this static class, any hints would be appreciated: https://developers.google.com/api-client-library/java/google-http-java-client/reference/1.20.0/com/google/api/client/json/gson/GsonFactory

15:57 domgetter: justin_smith: you mean warn-on-reflection? or something different?

15:57 tolstoy: justin_smith Maybe track the number of threads on your thing? (.size (Thread/getAllStackTraces))

15:57 justin_smith: tolstoy: if you look at nearby code, I actually dump all stack traces

15:57 but yeah- that's actually a good consideration too

15:58 domgetter: warn-on-boxed http://insideclojure.org/2014/12/15/warn-on-boxed/

15:58 tolstoy: If there's a way to find the default stack size, that can provide an additional "memory" stat (even if actual stack traces are useful elsewhere).

15:59 justin_smith: tolstoy: that's true - my usage here is a lib that dumps full status of a worker in a compute cluster, so I always get both the heap-memory usage and the stacks

15:59 tolstoy: Yeah, post processing is perhaps a better strategy.

15:59 justin_smith: the idea being that if things go wrong we can look at the dumps and figure out what subtask or combination thereof led to the failure

16:00 domgetter: justin_smith: ah okay. I think I can benefit from going back and hinting outputs.

16:00 I think I got most of the inputs

16:00 justin_smith: domgetter: well, if you try using warn-on-boxed it will let you know what you missed

16:00 domgetter: oh, awesome

16:00 justin_smith: the article shows how to do it (there's a shorthand to do it in lein too if you search for :warn-on-boxed in the example project.clj on github)

16:01 domgetter: haha, I got like 20 warnings

16:01 justin_smith: domgetter: well they show warn-on reflection but unchecked-math warn-on-boxed works the same way https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L253

16:02 domgetter: wow, that's good - because you know how to fix them and they each will lead to sped up code :)

16:03 LauJensen: when you run (com.google.api.client.json.gson.GsonFactory.) to construct a new one, what happens?

16:04 LauJensen: java.lang.ClassNotFoundException: com.google.api.client.json.gson.GsonFactory

16:04 @justin_smith

16:04 justin_smith: LauJensen: how are you adding gson to your classpath?

16:07 LauJensen: justin: Its part of the google_analytics_v3.jar

16:07 justin_smith: and how are you adding this to your classpath

16:08 LauJensen: Via :dependencies in project.clj

16:08 And every other class from there imports, just not the inner statics

16:08 justin_smith: odd - have you tried opening the jar and seeing if the class file is actually present?

16:09 LauJensen: I'll have a look

16:09 justin_smith: since it's public, you should have no trouble accessing it if its actually there...

16:10 LauJensen: oh wait, what syntax are you using for inner classes?

16:11 LauJensen: Outer$inner

16:11 justin_smith: OK, that's the right thing (though of course Inner would be capitalized)

16:11 also, the import would look like (:import (foo.bar Baz$Quux))

16:12 it's Baz$Quux is not imported when you import Baz

16:13 LauJensen: (import '(com.google.api.client.json.gson$GsonFactory)) - Would that be the correct syntax?

16:13 justin_smith: no

16:13 because GsonFactory is not an inner class of gson there

16:13 it's a regular class

16:14 gson is just part of its package qualifier

16:15 LauJensen: oh, right you are

16:15 justin_smith: so you just want (import '(com.google.api.client.json.gson.GsonFactory)) but (import com.google.api.client.json.gson.GsonFactory) is equivalent, and if you were importing more then one thing you could use (import (com.google.api.client.json.gson GsonFactory Foo)) but there are no other classes to import in that package I don't think

16:16 class names don't need quoting because they are resolved

16:16 ,java.util.Date

16:16 clojurebot: java.util.Date

16:16 justin_smith: ,(import (java.util Date))

16:16 clojurebot: java.util.Date

16:16 justin_smith: same thing

16:17 LauJensen: RE (import '(com.google.api.client.json.gson.GsonFactory)) -- Clojure doesn't do any actual work, if there is no space in an import statement IIRC

16:17 justin_smith: LauJensen: nonsense

16:17 it imports either way

16:17 but import isn't much - it just changes class lookup rules

16:17 LauJensen: I still get the (GsonFactory.) => Class not found exception

16:17 justin_smith: its accessing the class name that loads it

16:18 LauJensen: did you check if GsonFactory was in the jar that lein downloaded to your m2 cache?

16:19 LauJensen: The jar is downloaded, but I actually cant fint the GSonfactory class

16:19 Still looking though

16:20 justin_smith: that was my suspicion - if the jar is in your deps, and you can't find the class, that makes me think the class might not be in the jar

16:20 other possibility being that the project file is malformed?

16:20 LauJensen: I'll continue searching, but thanks for your help so far

16:21 justin_smith: np, I'm sure there's a simple fix

16:21 LauJensen: what does the dependency vector you are using look like (eg. version string etc.)

16:26 LauJensen: my suspicion is that the class you want actually comes from google-client-api which is required by google_analytics_v3, and in turn google-client-api only requires google-http-client-gson in the "test" scope. So you should require google-http-client-gson explicitly if you want it http://central.maven.org/maven2/com/google/api-client/google-api-client/1.21.0/google-api-client-1.21.0.pom

16:26 the coordinates to get that version are in that pom file in the dependencies section

16:27 sorry, to be pedantic about my own language above I should have said "depends on" rather than "requires" throughout, I appologize for any confusion that might have caused

16:29 LauJensen: [com.google.apis/google-api-services-analytics "v3-rev121-1.21.0"]

16:30 justin_smith: LauJensen: cool - try adding a dep to google-http-client-gson - I think that's your issue

16:31 LauJensen: I'll give it a shot

16:48 justin_smith: which is why I said you should add the dep on google-http-client-gson

16:54 roninhacker: I’ve just found this code in compojure:

16:54 (let [mw (:route-middleware request identity)]

16:55 doesn’t matter what it does w/the bindings

16:55 the important part is

16:55 (:route-middleware request identity)

16:55 (request is a map)

16:55 what does clojure do when a keyword is used as a function, and has two arguments?

16:56 (let [m {:k :v}] (:k m identity))

16:56 ridcully_: ,(:b {:a 1} 666)

16:56 clojurebot: 666

16:56 roninhacker: ,(let [m {:k :v}] (:k m identity))

16:56 clojurebot: :v

16:57 tolstoy: The second parameter is what you return if there's no value in the map.

16:57 roninhacker: ,(let [m {:k 4}] (:k m inc))

16:57 clojurebot: 4

16:57 roninhacker: ah

16:57 ok

16:57 ty

16:57 justin_smith: ,(:foo nil :default)

16:57 clojurebot: :default

16:58 tolstoy: Oooo, my turn!

16:58 ,(:foo {:bar "x"} "y")

16:58 clojurebot: "y"

16:58 justin_smith: ,(:foo :foo :foo)

16:58 clojurebot: :foo

16:58 tolstoy: ,(:foo {:bar "x"} identity)

16:58 clojurebot: #object[clojure.core$identity 0x74e2a4dc "clojure.core$identity@74e2a4dc"]

16:59 justin_smith: ,(def id (partial get get get))

16:59 clojurebot: #'sandbox/id

16:59 justin_smith: ,(id 42)

16:59 clojurebot: 42

16:59 tolstoy: I guess that form is expecting to extract a function out of the request map.

16:59 roninhacker: yeah

17:00 i’m not sure but it hink compojure middleware works by constructing a mega-fn (using comp) in the req map, incrementally adding to the mega-fn

17:01 justin_smith: roninhacker: there's various ways to do it, you can call comp, or use -> to build a nested form

17:01 as long as you get nested functions returning a handler, you're good

17:01 very similar to how transducers work actually

17:01 roninhacker: on that topic actually

17:02 does anyone know of a good resource where i can learn about composing async channels together in cljs for building ui’s?

17:02 sort of like a flapjax approach, where “everything is a stream”, etc.?

17:03 justin_smith: roninhacker: I don't have an example publicly available, but I use sente to abstract websocket communication as core.async channel ops

17:03 each incoming message becomes a message consumed in a go loop, etc.

17:03 roninhacker: oh, i will probably grab that

17:03 i’m doing it manually now w/cljs-ajax

17:04 justin_smith: aha - ajax is slightly more portable, but websockets are great

17:04 also, sente can do ajax too if you set it up right

17:05 tolstoy: The basic idea is that you have a single channel. You consume messages from it to update UI state, and every other thing (event handlers, ajax results, incoming socket data) gets dumped on that channel. Simple! ;)

17:06 I suppose you can use multiple channels and alts! on your state-processing consumer. But, basically, ... ;)

17:06 justin_smith: tolstoy: oh yeah, you could wrap your reagent atom for example, so the only way to update it is via a channel

17:07 tolstoy: The thing that consumes channels messages can delegate to a multimethod, or you could have "defrecord" messages that all implement an "update state" protocol (take a state, return a new state), etc.

17:10 It's been raining like crazy in Portland this past week. Hard to take my dog for a walk.

17:10 justin_smith: it has been rainy

17:11 tolstoy: you ever come to the clojure meetups here?

17:12 tolstoy: No. Well, just twice. Once it was just me and a guy from Simple. The other time, a guy gave a talk: the Kevin cljx guy.

17:12 Is it fun?

17:12 justin_smith: depends on your definition of fun, I often learn a lot

17:12 tolstoy: Kevin Lynnagh? Something like that.

17:12 justin_smith: and get job offers I don't need, heh

17:13 the next one is on om-next

17:13 tolstoy: I can't hear "job offer" without hearing "Work on tickets to lie about at daily stand ups, micro manage, micro manage." Hopeless.

17:14 That might be interesting. I read the tutorial about Om-next. The stuff about "state" being normalized and so on was ... confusing.

17:16 I'm the type that can understand what I read, but then I have to sit down and actually do it. The "doing it" understanding is different than the "reading about it" understanding.

17:22 According to DarkSky, rain non-stop until noon tomorrow.

18:32 LauJensen: Gents, how do I call the Builder constructor from Clojure? https://developers.google.com/api-client-library/java/google-api-java-client/reference/1.19.1/com/google/api/client/googleapis/auth/oauth2/GoogleCredential.Builder

18:32 @justin-smith perhaps you know?

18:41 tolstoy: LauJensen: Try "doto"?

18:42 LauJensen: Doto would only work after instantiation as it just inserts the instance as the 2nd argument to the following forms

18:42 tolstoy: I'm guessing that every method called on the builder just returns the builder, so using doto, which maintains a reference to the original builder would work.

18:42 (doto (GoogleCrededential/Builder) ... )?

18:43 (Well, correct spellering, of course.)

18:43 LauJensen: NoSuchFieldExpcetion

18:46 tolstoy: Try "$".

18:46 GoogleCredential$Builder?

18:46 (new GoogleCredential$Builder) ... ?

18:46 LauJensen: Tried, no luck

18:47 I get an Unable to resolve Classname GoogleCredential$Builder

18:47 tolstoy: You might have to import it.

18:47 LauJensen: And its not a classname, so it makes sense

18:47 Ah right

18:50 No dice

18:52 tolstoy: Is there some version of that in the JDK? I'd give it a try locally.

18:53 LauJensen: I mistook which one was the inner class, I got it now [oauth2 GoogleCredential$Builder) then(GoogleCredential$Builder.)

18:53 Thanks for sparring

18:53 tolstoy: Ah, good!

19:32 Raynes: Hey guys. Just a heads up to those using Refheap that I'm going to be more or less shutting it down soon. I've received complaints from Citibank because folks have posted stolen credit card/security info. As is the nature of pastebins this is unlikely to be an isolated occurrence and as one dude who can't really even maintain the thing in the first place, I don't have the resources to mitigate these sorts of things.

19:33 My plan is to shut off the ability to make new pastes, for starters. I'll leave it running with old pastes for as long as I can so people can retrieve and link to their current pastes for the time being, and regardless I'll be sure to make public data available when the site gets shut down completely.

19:34 But hey, it took like 3 whole years for assholes to abuse the site beyond rando-spam.

19:34 Pretty solid run I'd say.

19:48 justin_smith: Raynes: RIP

19:48 I'll miss refheap :(

20:27 alive876: hi, newbie here, im having a problem at the beginning of this book "Clojure Web Development Essentials", do this "lein new luminus hipstr" cd into hipstr and run "lein ring server" but it comes back "ring not a task"

20:28 any help much apprciated, seems this has happen multiple times in various tutorials, do i have to set my path maybe?

21:01 justin_smith: alcazoid: can you share a paste of the project.clj somewhere? also what version of lein?

21:31 oh, wait, that question was from alive876 who apperently left

21:31 anyway, I can replicate the issue, but it looks like it works with "lein run", and tutorials should be able to specify a specific version of a template because this happens way too often

Logging service provided by n01se.net