#clojure log - Jan 26 2016

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

3:48 solatis: hmmm, from the erlang world i am familiar to doing this: `{_, _, bar} = foo()`, as in, a kind of pattern matching / variable construction in one. is this also possible in clojure? I know about core.match, but that seems to be more code bloat / not exactly the same

3:49 MasseR: solatis: not exactly no. I think the best you can do is destructuring

3:49 solatis: ok

3:49 MasseR: For example if you have a list with 3 elements, you can destructure it into variables

3:49 But no full blown pattern matching

3:50 solatis: i think that's sufficient for what i want

3:50 seems like "destructuring" was the term i was looking for

3:53 kwladyka: solatis https://gist.github.com/john2x/e1dca953548bfdfb9844

3:54 solatis: kwladyka: thanks!

3:55 (let [{a :a d :d} my-hashmap]

3:55 (println a d))

3:55 that seems to do exactly what i want!

3:56 ridcully_: there is also {:keys [a d]} if you just want the same names

3:58 noncom: http://emojilisp.com/

3:58 autogen_: Hey guys. I went to a clojure meetup and I suppose that's got me pumped to use clojure more. I wonder if there's any kind of live-programming interface for music composition and the likes

3:59 CStorm: haha noncom

3:59 noncom: autogen_: sure, there's like overtone, did you try it?

3:59 a new era of visual programming, right :D

3:59 CStorm: speaking of meetups, anyone going to clojured in berlin next month? im looking forward.

3:59 autogen_: I'll check it out :D

4:00 noncom: autogen_: also https://www.youtube.com/watch?v=wDcN7yoZ6tQ

4:01 autogen_: and https://www.youtube.com/watch?v=M-s1mIp1DQk

4:01 autogen_: well, and google/youtube has many videos on this kind of stuff

4:02 autogen_: i also look at the minim java sound library and some time in the past i also looked into the beads java library

4:14 kenrestivo: autogen: overtone

4:20 autogen_: so much.. much gratitude! :D

5:54 neoncontrails: Having trouble understanding how string/replace works. Can you construct a regex pattern dynamically?

5:54 Something like this doesn't work

5:54 ,(str/replace ":K:FOO1FOO" #(apply str "(?<!:)" "FOO") ":FOO2")

5:54 clojurebot: #error {\n :cause "No such namespace: str"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: No such namespace: str, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "No such namespace: str"\n :at [clojure.lang.Util runtimeException "Util.java" 221]}]\n ...

5:55 luma: ,(str/replace ":K:FOO1FOO" (re-pattern (str "(?<!:)" "FOO")) ":FOO2")

5:55 clojurebot: #error {\n :cause "No such namespace: str"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: No such namespace: str, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "No such namespace: str"\n :at [clojure.lang.Util runtimeException "Util.java" 221]}]\n ...

5:56 luma: ,(clojure.string/replace ":K:FOO1FOO" (re-pattern (str "(?<!:)" "FOO")) ":FOO2")

5:56 clojurebot: ":K:FOO1:FOO2"

5:56 neoncontrails: luma: ah ha! Thank you

6:03 spuz: luma: what is the re-pattern call doing?

6:04 hmm i think i see why you are building the pattern with (str) - i guess you want to replace "FOO" with a variable

6:05 neoncontrails: spuz: that's the idea, yeah. I got it working with re-pattern with a small modification

6:07 This won't compile here without the dependencies, but it does basically the same as the above just mapped over a vector of substrings: (str/replace word (re-pattern (str "(?<!:)" (first substrings))) (apply str (first (cmudict (first substrings)))

6:07 m1dnight_: How can I check if, in Clojail, the result in a sandbox or a value?

6:07 Im thinking of istypeof operations..

6:14 owlbird: how to use a local nexus as repositories, I didn't find a clear introduction. It seems lein will download some jars from maven' cental and others from clojars.org ?

6:14 do I need to config serval mirros in projects.clj ? or ~/.lein/profiles?

6:15 george_: hi, im wondering if anyone can help me find a sollution to a UVA problem online. I have to find a few different ways of doing the problem but im completely new to clojure if someone could help me with one sollution i might be able to figure out other methods of doing it

6:15 its the problem here: https://uva.onlinejudge.org/external/5/571.html

6:24 ridcully_: owlbird: have a look at `lein help sample` and look for `:repositories`

6:27 m1dnight_: ,(def x 5)

6:27 clojurebot: #'sandbox/x

6:27 m1dnight_: ,x

6:27 clojurebot: 5

6:27 m1dnight_: ,source

6:27 clojurebot: #error {\n :cause "Can't take value of a macro: #'clojure.repl/source"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Can't take value of a macro: #'clojure.repl/source, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Can't take value of a macro: #'cl...

6:28 chaos_: ip cloak

6:28 m1dnight_: This is lazybot, right?

6:29 george_: anyone able to help me with finding a sollution to this problem in clojure? https://uva.onlinejudge.org/external/5/571.html

6:35 m1dnight_: Hm, I cant seem to spot it in the code of lazybot either, how the sandbox is persisted.

6:37 MJB47: its not lazybot

6:37 its clojurebot

6:37 https://github.com/hiredman/clojurebot

7:21 CStorm: ,(+ 1 1)

7:21 clojurebot: 2

7:21 CStorm: thats pretty cool.

7:22 qsys: CStorm: did you expect to see 3 as a result? :p

7:22 CStorm: haha

7:23 just havnt seen the bot before

7:23 thats why

7:23 qsys: :)

7:25 oracle123: how to pickup 2 element from a map? such as from {:a 1 :b 2 :c 3}, I want to get the element for :a and :b, so the result should be [1 2]

7:25 schmir: (juxt :a :b)

7:26 justin_smith: ,((juxt :a :b) {:a 1 :b 2 :c 3})

7:26 clojurebot: [1 2]

7:26 justin_smith: ,(map {:a 1 :b 2 :c 3} [:a :b])

7:26 clojurebot: (1 2)

7:26 oracle123: great. thanks :

7:27 map is easier to understand.

7:27 justin_smith: ,((juxt inc dec) 0)

7:27 clojurebot: [1 -1]

7:28 justin_smith: ,((juxt first last) "hello")

7:28 clojurebot: [\h \o]

7:29 oracle123: ok, thanks for the example, understand now.

7:34 lokien: which function is first called in comp?

7:36 ridcully_: ,((comp #(doto :a (println "second" %)) #(doto :b (println "first"))))

7:36 clojurebot: :b first\n:a second :b\n:a

7:39 lokien: so, lifo? thanks

7:44 justin_smith: princeso is gone, but their code has been running in criterium for 9.5 hours and counting

7:44 amazing

8:02 lokien: justin_smith: what does his code do?

8:02 noncom: justin_smith: who's that?

8:02 m1dnight_: afaik there was something about clojail

8:09 justin_smith: lokien: (crit/bench (eval '(defn f [x] (+ 1 x))))

8:09 lokien: I've been benchmarking it for about 10 hours now

8:09 still going

8:09 Bronsa: justin_smith: what

8:09 justin_smith: I'm guessing this is a bug in criterium, but now I'm just morbidly curious how long it will keep on

8:10 lokien: justin_smith: and your cpu is on 100% constantly?

8:10 justin_smith: Bronsa: criterium has been using 100% of 1 of my cpus for about 10 hours running that

8:10 lokien: one of my 8, yes

8:10 Bronsa: lol

8:10 justin_smith: do you have a vague idea of how many classes you created during that time?

8:11 justin_smith: Bronsa: I'm guessing eval/defn must do something that prevents criterium from deciding it's done

8:11 Bronsa: rofl, I'm sure it's millions at least

8:11 opqdonut: did you grab a thread dump yet?

8:11 justin_smith: opqdonut: oh, good call, one moment

8:14 opqdonut: thread dump https://gist.github.com/noisesmith/ed887bd7a002eb507540

8:14 lxsameer: how can i run some code on process termination ? ( i want to stop my services properly )

8:15 lokien: not so scary

8:15 opqdonut: justin_smith: right, so it's actually doing the def

8:15 justin_smith: lxsameer: you can add a shutdownhook via the Runtime class, but be aware that some shutdowns will bypass this hook https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html

8:15 opqdonut: lxsameer: well the jvm has exit hooks, but the real answer is to use with-open and the java Closeable interface

8:16 owlbird: ridcully_: I add :mirrors {"central" {..}} to ~/.lein/profiles.clj, then use lein new compojure web, all packages were downloaded from my local mirrors, It works fine. But while I executed 'lein ring server' in the project directory, packages were downloaded from clojars.org again.

8:16 justin_smith: opqdonut: yup, like I asked it to

8:16 opqdonut: yeah, just checking

8:17 owlbird: If I add :mirrors to project.clj, then an exception happened 'Multiple mirrors configured to match repository'

8:17 lxsameer: justin_smith, opqdonut what's with-open ? can you point me to right direction please

8:18 opqdonut: lxsameer: https://clojuredocs.org/clojure.core/with-open

8:18 justin_smith: opqdonut: with-open won't do any cleanup that wouldn't be done automatically at vm shutdown, it's just useful for making sure you don't run out of handles

8:18 opqdonut: I don't see how it helps at all with the vm shutdown case

8:19 when the vm shuts down, the OS takes back all file handles and all memory, whether you explicitly release it or not, even if the vm fails to let it go

8:20 opqdonut: I mean if lxsameer has some code he wants to run on shutdown, and that code is related to some resource (db connection, etc), it might make sense to have a Closeable object for it

8:20 justin_smith: shutdown hooks are for the kinds of cleanup that the OS can't predict or provide

8:20 opqdonut: but it's going to close on shutdown, there's no way it would not be

8:20 opqdonut: justin_smith: yeah but maybe he wants to log something, flush something, commit something, whatever

8:20 justin_smith: clean shutdown of resources is great if you want to stay running a long time though

8:20 opqdonut: the problem with exit hooks is that they're not very composable

8:21 justin_smith: opqdonut: sure, with open helps with none of those, that's why you add a shutdown hook

8:21 lxsameer: justin_smith, I'm currently use runtime hook, but since it runs on another thread it seems it would have some problems, let me show you some code

8:21 justin_smith: opqdonut: why would you need to compose them?

8:21 lxsameer: justin_smith, http://dpaste.com/29N3DHV

8:21 opqdonut, ^

8:22 opqdonut: justin_smith: perhaps composable is the wrong word, but they're global and that hurts e.g. testability

8:22 justin_smith: lxsameer: as long as you are aware that there are kinds of shutdown that will prevent that hook from running, that looks fine to me

8:23 lxsameer: justin_smith, cool, thanks

8:23 justin_smith: opqdonut: so what you would do is have a with-open around some resource, and then put the cleanup code after it in the same function body?

8:24 opqdonut: cleanup code is in the .close method of the resource

8:24 justin_smith: whose cleanup code?

8:24 so you reify closable?

8:24 opqdonut: yeah

8:24 justin_smith: interesting

8:25 opqdonut: doesn't this end up being try/finally with no catch clause?

8:25 opqdonut: yes

8:25 justin_smith: but with-open looks nicer?

8:25 opqdonut: yeah, and the code related to a resource stays in one place

8:26 anyway, something like (defn -main [] (with-open [aserver (make-aserver) bserver (make-bserver aserver)] (wait for shutdown)))

8:26 justin_smith: interesting

8:28 opqdonut: c++-style resource management, kinda

8:28 our code is long-running and has a lot of resources (memory on native heap, sockets, shared memory) so we use that pattern a lot

8:29 usually the finalizers of the resource objects assert that the resource has been closed, as well

8:29 so we can test resource handling

8:29 justin_smith: opqdonut: shared memory cleanup is one of those cases where explicit cleanup is really called for

8:29 (at shutdown that is)

8:30 opqdonut: yeah but for e.g. running integration tests you really want to be able to start and stop the system multiple times per jvm

8:30 so exit hooks won't cut it

8:30 justin_smith: oh yeah absolutely

8:31 I guess I was very literally answering the "how to run something on exit", including the criteria "this clearly is only about those things that you actually need to clean up on vm exit so you can skip the stuff that is guaranteed to be cleaned up anyway"

8:32 opqdonut: also, I've had deadlocks with exit hooks

8:32 there was code that calls exit when an exception bubbles up high enough

8:32 there were multiple threads

8:33 exit hook wanted to shut down the threads

8:33 justin_smith: ouch

8:33 opqdonut: so when an exception gets propagated to two threads...

8:34 getting rid of the hook and using try-finally (i.e. with-open) for the cleanups solved the problem

8:34 oh right, temporary files is another case where explicit cleanup is needed

8:34 especially if they're large

8:34 justin_smith: true!

8:35 that's exactly what with-open is made for

8:35 opqdonut: mmh

8:35 justin_smith: also, in our own product, we discovered the need for something like with-open for kafka topics

8:35 opqdonut: yeah, communication channels might need explicit shutdown

8:35 justin_smith: like - "this code needs the topic, but it should be destroyed when we leave this scope"

8:36 opqdonut: yeah

8:36 justin_smith: which gets messy because topics are shared between vms, that's the point of them, but we can always give them a definitive owner in the app logic, so it should work out

8:37 opqdonut: ownership is important yeah

8:37 and transferring ownership is hard

8:37 justin_smith: though the previous iteration (my initial design) was using a smaller set of topics and routing on receipt - which has the advantage of not needing the tracking and cleanup, disadvantage of shared topics and routing

8:38 "just make new topics for stuff" was working great until we filled up kafka's disk drive though :P

8:38 opqdonut: hehe

8:39 justin_smith: but come to think of it, this being kafka, those topics are effectively temp files (or we should be treating them as such)

8:43 noncom: https://hsto.org/files/710/547/32a/71054732a3c34fce82a1baafb7986ca8.png

8:58 justin_smith: noncom: but aren't microservices one of the easiest ways to get clj into production?

9:05 wink: justin_smith: don't give me ideas! :P

9:18 jakedust: is there a way to juxt method calls? Something like (juxt .getKey .getValue)

9:19 luma: you need to wrap the method calls in an anonymous function

9:19 (juxt #(.getKey %) #(.getValue %))

9:19 jakedust: oh, I see, thanks!

9:21 engblom: I know it is not recommended to use array, but for the sake of speed, I would in this case need to create an array of atoms, where each atom might be either 'nil' or 'clojure.java.io/output-stream', how would I do it

9:22 (make-array ....) wants a type.

9:23 mpenet: ,(into-array [(atom nil) (atom 1)])

9:23 clojurebot: #object["[Lclojure.lang.Atom;" 0x42eac430 "[Lclojure.lang.Atom;@42eac430"]

9:23 mpenet: but the whole thing sounds hairy tbh

9:25 engblom: mpenet: I know. I would prefer to use just a hash map. I am making a gpio library for raspberry pi and with a map, 10000 writes takes 1.5 seconds. With vector it went down further to 1.3. Still I would need to get it even lower.

9:28 mpenet: Currently, the library is able to handle 2-3 stepper motors before hitting the limit, when using rpi2. I do not have the rpi1, but some figures are saying that the gpio is about 2.5 times slower. That means just one stepper motor at full speed.

9:29 Full speed means about 14 rpm

9:29 (for 28byj-48 stepper motor)

9:31 mpenet: I am not really concerned about the array, but whenever I see lots of atoms I am suspicious.

9:31 maybe something that might be designed differently

9:32 engblom: mpenet: https://github.com/engblom/gpio/blob/master/src/gpio/core.clj

9:32 mpenet: It is the uggly output-streams in this file. (I know, that line looks just uggly)

9:34 mpenet: The important functions using the output-streams are open-pin and write-value

9:35 It is the write-value I would need to optimize as far as it is possible.

9:35 Currently I am using only one atom (the whole vector) as vectors are, if I understood right, immutable

9:36 I suspect I could drop the use of atoms completely if I went with array...

9:48 * kuochung

10:06 kwladyka: Possibility to comment with #_ is so good.... genius invented this ;)

10:20 justin_smith: engblom: if you are using an array, why not just an array of output-streams where some can be nil?

10:21 you wouldn't need anything inside it to be an atom

10:22 haha, I just ssh'd to my home machine and that silly benchmark is still running (12 hours it's been going now)

10:24 marianoguerra: hi, I have an app that loads some deps from the classpath (JDBC drivers) it runs fine on the build but I can't find where to put them during development when I run "lein run", any help?

10:25 justin_smith: marianoguerra: what are you using to manage your classpath?

10:25 marianoguerra: justin_smith: mmmh, nothing explicit?

10:25 justin_smith: the run script when built adds the lib folder to the classpath

10:25 justin_smith: marianoguerra: well, leiningen is primarily a tool for setting up the classpath

10:26 marianoguerra: the expected usage is that things you want to be available during runtime should be declared as :dependencies in your project.clj

10:26 but this also assumes they are available by some maven repo or cache

10:26 marianoguerra: justin_smith: I know about reproducible builds and all that, that's why I clarified that they are jdbc drivers

10:27 each user has their own needs, I can't bundle all of them just in case

10:27 justin_smith: marianoguerra: OK, then just put them in your dependencies

10:27 if you don't deploy them, put them in the :development profile

10:27 that will ensure they aren't bundled with a deploy

10:28 marianoguerra: sorry, that's :dev as shown here https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L160

10:29 marianoguerra: justin_smith: will try that, thanks

10:30 justin_smith: marianoguerra: both keys there are applicable actually - anything under :resource-paths is added to your classpath, and you can also have normal dependencies specific to a profile

11:40 tfw that criterium benchmark you started running 13 hours ago is still using 100% CPU on one thread

11:43 ashnur: how do people handle user input validation in clojureland?

11:44 cap10morgan: ashnur: We use Plumatic Schema (formerly Prismatic) https://github.com/plumatic/schema

11:46 ashnur: thanks

11:47 cap10morgan: ashnur: that's a building block that is solely focused on the data structures, not any UI aspects. other libs get into web form UIs more if that's what you want.

11:49 ashnur: yeah, my issue is that our java backend is sending me validation errors such that from js it looks something liek "res.body.errors[0].exception.validationResults[0]" and that is an object which has validatedObjectType, status, failedRegexRules, failedNullChecks, failedDataValueValidations

11:50 and here i was hoping that if we use graphql this is going to be better. now it is too late

11:55 engblom: Really suprising: java-array is slower than vector... about 11-12 times slower

11:55 I was expecting an array to speed up my code, but it is slower now...

11:56 justin_smith: engblom: slower to do what?

11:57 Bronsa: engblom: you're probably doing a lot of reflection

11:57 engblom: What earlier too 1.3s now takes 12-13s

11:58 so 10 times slower

11:59 Bronsa: What do you mean with "reflection"?

12:01 justin_smith: when clojure can't tell at compile time what the type of some variable will be, it compiles code that checks the type at runtime

12:01 this type checking is reflection, and it is expensive

12:01 it's very slow

12:02 engblom: justin_smith: Raspberry Pi got totally 54 GPIO "pins". Some are real, some are for checking up other things. So I am having a 55 items long array created by (make-array java.io.BufferedOutputStream 55). The purpose was to really quickly map gpio number to right output-stream.

12:02 kwladyka: engblom practical example http://clojure.wladyka.eu/#avoid_reflections

12:03 justin_smith: engblom: if you turn on the *warn-on-reflection* parameter, you can find what in your code might be reflecting

12:04 kwladyka: engblom but i suggest solution from my article, i doesn't mess with reflections in core on screen

12:04 justin_smith: oh, kwladyka 's link shows that, cool

12:04 engblom: The only thing I am basically doing is (.write (aget output-streams gpio-number) (.getBytes "1\n"))

12:05 Glenjamin: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L259

12:05 ^ I like doing it that way

12:05 justin_smith: engblom: that's probably got at least one reflection happening (type of output-streams) if not more

12:05 Glenjamin: I suspect that .write is reflection

12:06 kwladyka: Glenjamin just check it, you have description how in my link

12:06 oh, not to you :)

12:07 Glenjamin: yup :p i'm just eyeballing

12:07 kwladyka: sorry, i am just after whole day of work and i will work more :)

12:07 Glenjamin: ouch

12:07 kwladyka: but now for my pleasure....

12:07 ;)

12:17 engblom: How should the reflection be made for (.write stream (.getBytes "1\n"))?

12:17 The hint, I mean

12:18 justin_smith: (.write ^java.io.OutputStream stream (.getBytes "1\n"))

12:18 or you could give it the more specific type if you have it

12:21 engblom: Thanks

12:28 krrysis: hey

12:28 whats this channel about?

12:29 anyone?

12:29 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

12:29 krrysis: hi

12:29 justin_smith: krrysis: as the topic says, the clojure programming language

12:29 tomas`: hi, I have this https://gist.github.com/anonymous/7c1915e9be6426b82de2 simple setup but I get an error of "no such namespace"

12:30 justin_smith: tomas`: I would not expect cljsjs/google-maps the project to provide a cljsjs.google-maps namespace

12:31 tomas`: https://github.com/cljsjs/packages/wiki/Using-Packages

12:34 justin_smith: tomas`: https://github.com/cljsjs/packages/tree/master/google-maps there's nothing in there that defines a cljsjs.google-maps namespace

12:42 engblom: http://pastebin.com/x0yWQcbd <---something is wrong. I get "Exception in thread "main" java.lang.IllegalArgumentException: No matching method found: flush for class java.io.BufferedOutputStream"

12:46 backnforth: Newbie question: When I run "lein run", my program runs fine, but after the program is finished I get a "Exception in main.. Cannot find anything to run for" error message.

12:46 How can I fix this potential error?

12:52 justin_smith: backnforth: umm, what's the actual error message?

12:52 backnforth: my suspicion is that you have top level side effects but no -main for lein run to launch

12:53 engblom: are you sure it's a BufferedOutputStream ?

12:57 backnforth: I have a main: projectName.core is my project.clj

12:58 justin_smith: backnforth: does projectName.core have a function called -main ?

12:58 or does it just have side effects in the top level code?

Logging service provided by n01se.net