#clojure log - Sep 01 2015

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

0:05 andyf: TEttinger: The multicore revolution has already ended? You mean, not in hardware, but in that so much software uses only one virtual core per process, and typically one thread, but they scale out by having many processes, not many threads?

0:05 TEttinger: I mean we aren't doubling the hardware cores available every 2 years :)

0:13 Wild_Cat: what's Clojure's story for high-concurrency HTTP?

0:13 (as in, when one wants to process more than one concurrent request per thread)

0:44 andyf: Moore’s law/observation hasn’t shut off yet, so if it isn’t going to more cores, I guess it is going for larger caches, then?

0:54 TEttinger: well I mean I can buy an octacore desktop processor today, from AMD, that still isn't very good.

0:54 intel has been making faster quad-cores and also the weird ultra-low-voltage chips for "ultrabook" laptops

0:56 GPUs are totally going above and beyond for Moore's thang though

2:05 tolstoy: Wild_Cat: Maybe use the ztellman's Aleph lib? Has an http client with deferreds, streams, ways to chain them together, some interoperation with core.async, etc. http://aleph.io

3:19 domokato_: aset-float seems to be doing reflection. Am I doing something wrong?

3:20 or is it unavoidable?

3:20 * abhir00p_

3:21 amalloy: domokato_: for reasons i dont understand, you're better off using (aset ^floats xs ...)

3:25 Bronsa: amalloy: looking at def-aset, it is written to always use reflective methods

3:26 TEttinger: huh

3:26 amalloy: oh i know it uses reflection, i just don't know why

3:26 Bronsa: I don't think there's a good reason

3:27 domokato_: (aset ^floats xs ...) seems to be about the same speed...let me dig a little more

3:28 TEttinger: to be perfectly honest, I think some array-heavy code is better written in java just so you don't have to deal with boxing stuff

3:28 Bronsa: amalloy: looks like def-aset was written before clojure had primitive support

3:29 amalloy: interesting. i don't think i even knew there was such a time

3:29 Bronsa: 2008

3:34 domokato_: according to the profiler, aset is also doing reflection

3:36 Bronsa: domokato_: how are you using it?

3:36 domokato_: aset won't do reflection IFF you use the 3-arity and the array is propertly type hinted

3:49 domokato_: i need to use the 4-arity, it's a 2d array

3:50 i type hinted the array as ^floats, but still uses reflection

3:54 ah, ^floats is inaccurate anyway since it's a 2D array...

4:02 got it! i just needed to pull out each inner array and use the 3-arg version of aset on it

4:04 TEttinger: domokato_: you might have just found a better way, but when I was doing this (and I hadn't thought of pulling out the inner array), I found using a 1d array to emulate a 2d array was rather high-performance

4:04 and also sorta played nicer with amap

4:05 domokato_: TEttinger: I would do that if I could, but the API I'm using takes 2D arrays

4:05 TEttinger: ah ok

4:06 vectorz may be a good thing to look into then

4:07 amalloy: hint it as ^"[[F" probably works for the 2d array

4:07 TEttinger: oh nvm, vectorz uses its own array stuff, not the [[ arrays

4:08 Hitch: Hello. I am looking for a simple crud-website-backend-tutorial to get me started.

4:08 TEttinger: amalloy: the ^"[[Z" thing for a 2d boolean array is sure weird

4:10 wink: this is offtopic, but any ideas how I'd best represent a list like '(1 "a" {:foo 2}) in plain java?

4:10 I can think of 10 non pretty ways, but nothing easy

4:10 Hitch: use a class obviously...

4:11 wink: class with 3 fields is one of the ugly ways, yes :P

4:11 Hitch: it's the appropriate way in java

4:11 when in rome... ;)

4:12 there is lots of boilerplate in rome.

4:12 wink: hehe ok

4:15 storm's Values just uses ArrayList<Object> though

4:16 Hitch: storm?

4:16 wink: https://github.com/apache/storm

4:21 Hitch: would have to look at the code to figure out why they did it. unless their lists change it is probably just laziness.

4:42 TEttinger: wink: there's that clojure-data-structures-for-java library

4:42 https://github.com/rschmitt/collider is one...

4:42 wink: thanks

4:43 but I think I'll just stick to Values, I'm using Storm after all :P

4:43 *bookmarks for later use*

4:43 TEttinger: ah, also https://github.com/rschmitt/dynamic-object

5:47 Empperi: oh nice. Someone actually has implemented that

5:48 been thinking on doing the exactly same thing although without clojure underneath

6:10 pseudonymous: If anyone's used HoneySQL - could someone explain me the rationale behind the (insert-into) helper function ? The result from applying (honeysql.core/format) to the resulting map yields a vector which works fine with clojure.jdbc/execute! but execute only tells you the rows affected and clojure.jdbc/insert! expects a much different format

6:22 ddellacosta: pseudonymous: honeysql doesn't really work with any of the helpers that c.j.j provides

6:23 pseudonymous: other than execute!

6:23 pseudonymous: mostly it's not a problem, but definitely it's a pain w/insert

6:23 pseudonymous: Yea. I've arrived at the conclusion that it's best that I just write a helper of my own to transform the query map into what c.j.j/insert! expects

6:24 ddellacosta: pseudonymous: what we end up doing is to simply pull the table name and values out of the map created by honeysql and pass that into insert!, when we care about the return value at least

6:24 pseudonymous: yep, that's basically what we do

6:24 pseudonymous: I guess I just asked to be sure I wasn't doing something obviously stupid :P

6:25 ddellacosta: pseudonymous: no, it's kind of an ugly incompatible bit w/honeysql and c.j.j I think

6:25 at least, I haven't seen any clever way around it

8:21 roelof: how can I change (http://lpaste.net/140030) so 0.0.0.0 is used instead of localhost ?

8:25 Bronsa: https://ring-clojure.github.io/ring/ring.adapter.jetty.html

8:26 there's a :host option

8:31 roelof: Bronsa: I tried this : (run-jetty (var application) {:host "0.0.0.0" :port 8080 :join? false}) but still not working

8:43 how can I change (http://lpaste.net/140030) so 0.0.0.0 is used instead of localhost ?

8:53 zetlen: ok guys: https://www.refheap.com/109051 this is not parallelizing very well. i'm expecting it to get higher than 150% proc usage. should i be doing something more involved than pmap? perhaps switching from pmap to map or controlling the thread pool?

8:54 i mean, switching from pmap to map at a certain depth

8:54 thus practically limiting the number of threads to 26

8:54 hmm

8:56 darth10: zetlen, if you're trying to create a new collection, use fold from clojure.core.reducers

8:57 zetlen: darth10: i see, it takes n arguments

8:58 darth10: ahem, it takes an n argument for concurrency limit

8:58 darth10: zetlen, what i meant was try using a reducer :)

8:59 zetlen: darth10: i'm quite new to clojure--what does a reducer have over pmap?

8:59 darth10: the advantage to pmap is that i don't have to think about shared memory or partitioning my trie, is what it feels like

9:00 darth10: zetlen, actually building lazy lists may not be the best way here if you want to squeeze out more parallelism

9:00 yenda: is anyone using pallet ?

9:01 darth10: zetlen, so i meant try using a reducer based computation http://clojure.org/reducers

9:01 zetlen: darth10: i see...then how would i stream it out to http during calculation?

9:02 my test case is joining a string, sure, but i wanna avoid that in production

9:41 yenda: What are people using in the clojure world for provisionning and task automations ?

9:52 drbobbeaty: yenda: like creating AWS hosts? Or more like 'cron' tasks in your apps?

9:53 yenda: drbobbeaty: like creating aws hosts

9:53 and then installing stuff

9:53 and configuring

9:54 drbobbeaty: I've used Amazonica - but most often times I still use the AWS Console on the web.

9:54 https://github.com/mcohen01/amazonica

9:57 yenda: drbobbeaty: seems more up to date than jclouds support in pallet

9:57 good for provisionning but I still need to find something for tasks excecution

9:57 drbobbeaty: yenda: It's nice and we've used it to make SNS and SQS assets as well.

9:58 yenda: I use at-at in clojure: https://github.com/overtone/at-at

9:58 yenda: I've had a lot of luck with it for scheduling/cron - but it's in my process space - not "just managed" by AWS. I could not find anything to do that.

10:10 yenda: drbobbeaty: I am rather looking for something that would that would allow me to do some configuration on the instances

10:11 Like ansible

10:11 drbobbeaty: yenda: Yeah... sorry... I got nothing for you there. We are looking into tools like that, but I'm not in the selection group.

10:25 noncom: i am exploring the luminus web framework and i have found that the wrap-format middleware ( https://github.com/ngrunwald/ring-middleware-format ) tries to transform a websocket object sent as a response for a websocket request and throws an exception

10:26 does this mean that i should avoid using this middleware if i am to use websockets?

10:27 justin_smith: ping

10:51 Deraen: noncom: I remember using it with Sente. How are you sending the response the websocket request? At least with Sente you should use reply-fn or chsk-send! if I recall correctly.

10:53 noncom: Deraen: i am not sure what reply-fn or chsk-send! are, but the form that the existing middleware sends the websocket back is a {... :body WebSoketObject ...}

10:53 and this causes this error

10:53 i am very noob in compojure so i must be missing some fundamental piece of understanding

10:59 kavkaz: I have a function in which i use the expression (repeat <somenumber> \tab) and I try to apply str on it and some strings

10:59 but that particular expression doesn't evaluate, when i output the string it contains clojure.lang.LazySeq

11:00 How do I go around this? Or get it to evaluate?

11:00 Deraen: noncom: Unfortunaltely I'm not very familar with websockets. But yeah, r-m-f will try to encode the responses and that could fail. You could go around this by providing custom predicate for r-m-f response middleware.

11:01 noncom: The default implementation is here: https://github.com/ngrunwald/ring-middleware-format/blob/master/src/ring/middleware/format_response.clj#L19-L27 you could add (instance? WebSocketObject body) to the `or` to prevent r-m-f trying to encode those.

11:01 noncom: kavkaz: you get a lazy sequence, that is ok. if you want to see result, try (into [] ..LazySeq..)

11:01 kavkaz: noncom: Oh okay, I'll try that, thanks noncom

11:01 noncom: kavkaz: or, if the seq is big (or endless) and you want to see like 100 first elements, do (take 100 LazySeq)

11:02 Deraen: yeah! seems like it. i just wasn't sure that's ok... hmmm patching the lib..

11:02 maybe the creator did not think about websockets...

11:02 Deraen: noncom: the middlewares should take the predicate function as option

11:03 noncom: ah, ok, i will look into where i can pass it

11:03 Deraen: noncom: https://github.com/ngrunwald/ring-middleware-format/blob/master/src/ring/middleware/format_response.clj#L369 (this version is not yet, released but I'll release it now)

11:04 noncom: ah, it's you the author :D

11:04 Deraen: maintainer

11:04 though I've been as busy lately as the author

11:05 noncom: heh, very cool :) well, okay, this makes much sense. i will be configuring the middleware to behave ok with the websockets!

11:20 Deraen: noncom: It's released: https://github.com/ngrunwald/ring-middleware-format/blob/master/Changes.md#060-2015-09-01

11:21 noncom: alright! i'm updating! also remember to change the lein instruction on the main readme to reflect version 6.0 (now it says 5.0)

11:22 thank you :)

11:28 troydm: can anyone explain me how this is used? http://clojuredocs.org/clojure.core.logic/project

11:38 noncom: troydm: well, there's always https://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic.clj

11:38 https://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic.clj#L1327 in particular

11:38 as to how describe this with words - i am not sure, i'm not much into logic programming yet

11:39 as far as i understand, you feed it the vars and the goals and it returns you the values of the vars

11:45 troydm: noncom: ah, I understand now, thank you

11:53 justin_smith: noncom: pong - what server are you trying to set websockets up with?

11:54 noncom: justin_smith: it's immutant! but with help of Deraen, the man behind the format middleware, we have already fixed things!

11:54 justin_smith: oh, cool

11:54 noncom: there comes a new version of the middleware

11:55 it will be configurable to avoid processing what does not need to be processed, that's the solution

11:56 jcrossley3: noncom: if you see opportunities to change immutant in some reasonable way to make things more sensible overall, feel free to holler

11:57 tcrawley: noncom: what was the problem? that the middleware was trying to encode the body returned from the as-channel call?

11:57 noncom: tcrawley: yes

11:57 it was trying to encode the websocket java object

11:57 tcrawley: ah. I'm curious what your predicate looks like?

11:58 noncom: jcrossley3: okay, i will! though i am still in the very early learning stages :)

11:58 tcrawley: actually, i had no predicate.. and the new version of the middleware allows specifying the predicate if needed

11:59 Deraen: Another soultion could be to reorder middlewares so that r-m-f middleware doesn't see response from websocket middleware.

12:01 tcrawley: Deraen: in Immutant, you can init ws from middleware, or from a standard ring request

12:02 noncom: the easiest thing to check in the predicate is (:websocket? request)

12:02 jcrossley3: so if the former, re-ordering should work, right?

12:02 tcrawley: then you don't have to care about the type of the :body

12:02 jcrossley3: correct

12:03 noncom: tcrawley: i see... conceptually i got what you said but i will have more experiments until i really see how it works :)

12:03 tcrawley: sure thing. ping me here or in #immutant if you have any trouble

12:04 Deraen: tcrawley: noncom: r-m-f predicate takes request as the first parameter so checking :websocket? should be very good option

12:04 noncom: tcrawley: okay, thank you!

12:05 roelof: Has anyone succeed in running labrepl on a other host as localhost ?

12:08 troydm: noncom: https://www.refheap.com/109060

12:08 noncom: can u explain why this doesn't works?

12:09 noncom: troydm: i'm afraid i can't my knowledge of prolog and minikanren languages is very poor :) they are on my todo list

12:10 troydm: however, i can advice you to try out on #minikanren

12:10 or here, when more ppl are around

12:10 roelof: noncom: and when are the most people here avaible then ?

12:13 Deraen: noncom: I added issue to r-m-f about custom predicate for Immutant ws: https://github.com/ngrunwald/ring-middleware-format/issues/46 If it works for you, I could add a mention to docs.

12:15 noncom: roelof: idk, depends... sometimes it's full of ppl, sometimes, not.. and, by looking at contributors to that project ( https://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic.clj ) it looks like that they are not here or afk now

12:15 Deraen: okay! will be checking in a half an hour!

12:17 roelof: noncom Im looking for someone or a contributor to this project : https://github.com/relevance/labrepl and not core.logic

12:26 maybe better make a issue on the page ?

12:33 noncom: roelof: oh, i am not sure. probably he'll be around here some times. or you can pm him

12:43 roelof: yeah, an issue about missing documentation would do i think

12:43 roelof: noncom but then I have to know his irc name and I get a suspion that relevance is company

12:44 noncom: yes, thinkrelevance is a company

12:44 but stuart is real

12:44 i remember seeing him around

12:44 long time ago

12:47 roelof: also there is clojure google group

12:47 roelof: I will make issue. I tried this (defn -main [& args] (run-jetty (var application) {:host "0.0.0.0" :port 8080 :join? false}) (println "Welcome to the labrepl. Browse to http://localhost:8080 to get started!"))

12:47 but no luck

12:48 I have asked there some questions but no answers there

12:58 noncom: roelof: what about {:host "localhost"} ?

12:59 roelof: that does also not work. My cloud provider wants that you use 0.0.0.0 instead of localhost

12:59 oddcully: i think OP want _not_ to bind to localhost but to the world

13:01 noncom: oddcully: quite possible! what are his options then?

13:04 oddcully: noncom: any (0.0.0.0) should be fine here (for ipv4)

13:06 noncom: eh, but it is not..

13:08 roelof: oddcully: schould I do (0.0.0.0) instead of "0.0.0.0" ?

13:08 oddcully: no. this where no cloj parens ;)

13:09 and just to have it asked: the host in question actually has ipv4 addresses on it?

13:11 pseudonymous: w/o being fully clued in. If you wanted to bind to localhost (i.e. disallow outsiders you'd use "127.0.0.1" (or the IPv6 equivalent) or simply "localhost"). If you want to bind to the outside world "0.0.0.0"/"<whatever your machine's externally facing IP is>.. If it's a Linux box, you'll probably get much better help from throwing the output of "ip addr" up on a gist

13:11 roelof: oddcully: yes, they say themselves to use 0.0.0.0

13:12 oddcully: roelof: and regardless of what you tell to be the :host here you bind to ::1?

13:12 pseudonymous: And if this really is just a question of not having a connection. Install "netstat" on the machine and look over the list with "netstat -taupen" - try to see which interface (if any) your service bound to

13:13 roelof: sorry now I miss you. This is becoming very technical

13:14 oddcully: from what i gathered your problem is, that regardless of what you configure with :host, your service there only accepts connections on 127.0.0.1 (or localhost)?

13:14 this got determined by you or by your ops folks?

13:15 roelof: odd : I think this is a good explantion of my problem

13:20 pseudonymous: roelof: I'd bet your problem isn't whatever clojure service you're trying to get going. It's way more likely that you guys aren't deploying it right. Maybe no one looked with 'netstat -taupen' to determine which IP's the service binds to but just observed that they get no response aside from 127.0.0.1 - in that case, it's most likely because of the server's firewall rules. If (say) you guys are attem

13:21 pting to deploy this to a Ubuntu box or something like that, your best bet is to investigate the server environment further and possibly solicit help from their channels.

13:29 roelof: thanks all

13:44 clojer: Trying to get a local JAR into my project. Have setup "mvn" directory with `mvn install:install-file .....` and the JAR is under <project>/mvn/astro/swisseph but it doesn't seem to be in my classpath. What would be the correct (import ...) format?

13:45 justin_smith: clojer: after the mvn install you need to add the jar to your deps (in project.clj if you are using lein)

13:45 import does not change your class path, you need to set up your class path via lein, boot, mvn, gradle, whatever

13:45 clojer: Followed instructions at: http://www.thesoftwaresimpleton.com/blog/2014/12/06/om-local subsituting local java JAR for Om JAR

13:45 justin_smith: (or by hand if you are crazy like that)

13:46 clojer: if the install succeeded, double check your project.clj settings

13:46 clojer: justin_smith: Which format for project.clj?

13:46 justin_smith: it should either have added the jar to classpath, or failed because it could not find the artifact

13:47 clojer: the link you just shared shows, but also you can check the documentation at leiningen.org. We can help here if you have a more specific question than "what format"

13:47 clojer: justin_smith: So just add like a Clojure dep?

13:47 justin_smith: right, because it is a dep

13:48 clojer: justin_smith: I mean no separate config section for Java JARs?

13:48 justin_smith: there is no separation or difference

13:48 a dep is a dep, whether it contains clojure code, java classes, or javascript

13:48 clojer: justin_smith: I mean no separate config section for Java JARs?

13:49 justin_smith: clojer: like I said all deps are treated the same way no matter what is in them

13:49 so no there is no separate section

13:49 clojer: justin_smith: I mean no separate config section for Java JARs?

13:49 justin_smith: seriously, what the fuck, ignored

13:50 clojer: justin_smith: Use (import .. or (require ... ?

13:50 Sorry, repasted. Sorry

15:14 ben_vulpes: so i'm working to compile some clojurescript from the clojure repl, and have hit what i think is the final boss: my compiled clojurescript sez `goog.require('cljs.core')`, and that fails. when i manually edit that file to read '../cljs.core', google can find the file and my compiled clojurescript runs. does anyone know how to set that compiled path name during the cljs compilation step?

16:12 justizin: is there anything like maven's ~/.m2/settings.xml or a parent pom for leiningen?

16:13 justin_smith: justizin: some of that is replicated in ~/.lein/profiles.clj

16:14 eg. with the :repositories key that you can add to profiles there

16:15 or :mirrors

16:15 * clausewitch bought tickets to datomic conf and clojure/conj!

16:18 justizin: justin_smith: ah, sweet, hadn't seen profiles.clj in the docs

16:42 TimMc: justizin: Careful with that, by the way -- it's great for user settings, but I really don't recommend putting anything in there that is important to the build (such as which repositories to pull from.)

16:42 gganley: right now im using om to write my front end and im looking for a datastore to store edn in. I'm guessing the answer is going to be datomic but how does om talk to datomic? through JSON? through some other way? I'm just looking for some feedback

16:44 justizin: TimMc: we have tens of projects, so even though i agree with you in principle, it's a huge manageability improvement for us

16:45 and basically how our maven configs already look

16:45 * justizin looking at moving from maven to lein for java projects

16:45 justizin: but yah i am considering just flattening everything, the shared nature was confusing to me when i started here

17:14 TimMc: justizin: I'd almost consider using a plugin in that case... but that will only help with consistency in things that are not plugins.

17:14 We only have a handful of Clojure projects and we actually stopped relying on profiles.clj for repositories.

17:27 * justizin nods

18:32 simon1234: Hi there! I have a problem with a very simple macro and arg destructuring, any insight would be great! https://www.refheap.com/109070 Cheers!

18:37 ZimaBlue`: hi, I'm new at this too but aren't you supplying the inner log-structured with 3 arguments, when it needs an even number?

18:38 kanja: Is there a good tutorial on error handling for clojure? Is dire a good choice for new projects?

18:43 sdegutis: Question: Do you generally just write `(Date.)` or do any of you use a wrapper library for this?

18:47 simon1234: Hm, why does not that work? (into {} (partition 2 [:foo :bar :x :y]))

18:53 justin_smith: simon1234: because maps are picky and their entries must be vectors

18:53 ,(into {} (map vec (partition 2 [:foo :bar :x :y])))

18:53 clojurebot: {:foo :bar, :x :y}

18:53 justin_smith: or better yet ##(apply hash-map [:foo :bar :x :y])

18:53 lazybot: ⇒ {:foo :bar, :x :y}

18:54 sdegutis: ,(Date.)

18:54 clojurebot: #error {\n :cause "Unable to resolve classname: Date"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.IllegalArgumentException: Unable to resolve classname: Date, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6891]}\n {:type java.lang.IllegalArgumentException\n :message "Unable to resolve classname: Date"\n :at [cloj...

18:54 sdegutis: ,(java.util.Date.)

18:54 clojurebot: #inst "2015-09-01T22:54:57.504-00:00"

18:55 justin_smith: sdegutis: I just do (Date.) but a lot of people hate java.util.Date with a passion and use clj-time always

18:55 sdegutis: justin_smith: why aren't you in that camp?

18:55 justin_smith: lib-bloat

18:55 I usually don't need the features of clj-time, and I never try to modify my dates so the fact they are mutable doesn't become an issue

18:56 sdegutis: Okay cool. We're using chee.datetime (https://github.com/slagyr/joodo/blob/master/chee/src/chee/datetime.clj) simply because it's a predefined set of functions (like `now`) that I can stub out during tests, unlike Java constructor calls.

18:56 justin_smith: I already have like 200 deps on every project, I like having an excuse to leave a few out

18:56 sdegutis: That said, I'm considering creating a "Time" Component that I can use in my System component so that it's more "natural" to do dependency injection and swap out the real version for a fake version.

18:59 Oh wait, Components are meant to be things that can start and stop.

18:59 So I guess that's a stupid plan that doesn't make sense.

18:59 simon1234: justin_smith: oh thanks

19:00 Yeah, it seems really picky, I mean, it could just blow up... why does it have to be a vector. What guarantee does it bring?

19:05 TEttinger: simon1234: this is sorta an interesting topic. you can map over a hash-map, and it gives key-value pairs to the fn. ##(map identity {:a 1 :b 2 :c 3})

19:05 lazybot: ⇒ ([:c 3] [:b 2] [:a 1])

19:05 TEttinger: &(map class {:a 1 :b 2 :c 3})

19:05 lazybot: ⇒ (clojure.lang.MapEntry clojure.lang.MapEntry clojure.lang.MapEntry)

19:05 justin_smith: simon1234: clojure.core tries to force things to be efficient sometimes - see also no function being defined to add an element to the end of a list, or the beginning of a vector

19:05 TEttinger: they aren't exactly vectors, but MapEntry extends vector I believe?

19:06 justin_smith: maybe not "tries to force things to be efficient" but more like "tries to make inefficient things a bit harder to do"

19:06 TEttinger: a mapentry is a vector

19:06 subclass

19:06 simon1234: Yeah, but does it really achieve efficiency here? It just forces the construction of an intermediate vector, is it more efficient?

19:06 TEttinger: what's the term for, "is a subclass of X but is not strictly X"

19:07 simon1234: isa?

19:07 demouser: proper subclass

19:07 justin_smith: simon1234: I think it's to lead you toward modifying values in an existing entry rather than replacing it with a seq? or maybe it's just a wart on clojure's design :P

19:07 simon1234: :)

19:08 What does not strictly X mean TEttinger?

19:08 TEttinger: ,(into {} [:foo :bar :x :y]) ; curious about this

19:08 clojurebot: #error {\n :cause "Don't know how to create ISeq from: clojure.lang.Keyword"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: clojure.lang.Keyword"\n :at [clojure.lang.RT seqFrom "RT.java" 535]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 535]\n [clojure.lang.RT seq "RT.java" 516]\n [clojure.lang.ATransientMap conj "ATransientMap.java" 4...

19:08 TEttinger: simon1234: that's sorta the reason I'm confised about it

19:09 simon1234: , (into {} (map vec (partition 2 (:foo :bar :baz :binz))))

19:09 clojurebot: #error {\n :cause "Wrong number of args passed to keyword: :foo"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Wrong number of args passed to keyword: :foo"\n :at [clojure.lang.Keyword throwArity "Keyword.java" 97]}]\n :trace\n [[clojure.lang.Keyword throwArity "Keyword.java" 97]\n [clojure.lang.Keyword invoke "Keyword.java" 150]\n [sandbox$eval49 invokeStatic "NO_SOURCE_FI...

19:09 TEttinger: there's an IPersistentVector interface, and the vectors you create with [] are I think a different implementation than MapEntry is

19:09 simon1234: , (into {} (map vec (partition 2 '(:foo :bar :baz :binz))))

19:09 clojurebot: {:foo :bar, :baz :binz}

19:09 TEttinger: ,(class [])

19:09 clojurebot: clojure.lang.PersistentVector

19:11 TEttinger: ,(into {} (map vector '(:foo :baz) '(:bar :binz)))

19:11 clojurebot: {:foo :bar, :baz :binz}

19:11 TEttinger: if your keys are separate from values that could be a shortcut

19:11 justin_smith: ,(zipmap '(:foo :baz) '(:bar :binz))

19:11 clojurebot: {:foo :bar, :baz :binz}

19:12 simon1234: TEttinger: :) yep, but it is not. But that's ok, I will do it another way, I was just curious

19:12 justin_smith: simon1234: yeah, apply hash-map is really the solution if you have your hash-map as a flat seq

19:12 simon1234: Yep, thanks for the suggestion!

19:17 amalloy: clojurebot: apply hash-map is <reply>http://stackoverflow.com/q/7034685/625403

19:17 clojurebot: In Ordnung

19:19 amalloy: my second-most popular answer on SO, curiously

19:20 simon1234: :) good return on investment!

20:05 kavkaz: I'm trying to use (if (empty? <someseq>) dosomething recur *whatever*) on (range) and obviously it's an infinite recursion. I tried wrapping it in lazy-seq, and I'm still having the same problem. I guess my trouble is that I'm not sure how else to solve the problem without using recur

20:07 How would I normally recursively call a function over a sequence such as (range)?

20:07 The assumption is that the client of the function can just call (take n (myfunction <someseq>))

20:09 amalloy: kavkaz: just call the actual function by name instead of using recur, inside the lazy seq

20:09 well

20:09 you have to also produce a partial result, rather than using an accumulator. take a look at the definition of take, for example, since you mention take

20:09 ~def take

20:13 kavkaz: Thank you amalloy, I'll take a look at that. I think now that i've tried explaining my issue it'll be easier to try and solve it.

20:22 amalloy: Oh i see

20:23 pradeepchhetri: hello, i want to convert ({"name" "databases", "columns" ["name"], "values" [["testdb"] ["mydb"]]}) into ({:name "testdb"} {:name "mydb"})

20:23 i am unable to think for a way to do this, can someone help me out.

20:28 gfredericks: ,(defn pradeep [data] (for [{:strs [columns values]} data, :let [k (keyword (first columns))] [v] values] {k v}))

20:28 clojurebot: #'sandbox/pradeep

20:29 gfredericks: ,(pradeep '({"name" "databases", "columns" ["name"], "values" [["testdb"] ["mydb"]]}))

20:29 clojurebot: ({:name "testdb"} {:name "mydb"})

20:29 gfredericks: pradeepchhetri: I think the problem as you described it is a bit underspecified, but I wrote something that did what you asked

20:30 TEttinger: ,(let [start {"name" "databases", "columns" ["name"], "values" [["testdb"] ["mydb"]]}] (map (fn [vcoll] (map #(into {} [(keyword %1) %2]) (start "columns") vcoll)) (start "values")))

20:30 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword>

20:30 TEttinger: ,(let [start {"name" "databases", "columns" ["name"], "values" [["testdb"] ["mydb"]]}] (map (fn [vcoll] (map (fn [a b] {(keyword a) b}) (start "columns") vcoll)) (start "values")))

20:30 clojurebot: (({:name "testdb"}) ({:name "mydb"}))

20:30 TEttinger: ,(let [start {"name" "databases", "columns" ["name"], "values" [["testdb"] ["mydb"]]}] (mapcat (fn [vcoll] (map (fn [a b] {(keyword a) b}) (start "columns") vcoll)) (start "values")))

20:30 clojurebot: ({:name "testdb"} {:name "mydb"})

20:31 pradeepchhetri: gfredericks: thank you very much :)

20:31 TEttinger: gfredericks: that won't work for multiple columns I think, but that looks good

20:32 mange: If you can also have multiple columns you could do something like: (mapcat (fn [{:strs [columns values]}] (map (partial zipmap (map keyword columns)) values)) data)

20:32 TEttinger: ,(let [start {"name" "databases", "columns" ["name" "id"], "values" [["testdb" 1] ["mydb" 2]]}] (mapcat (fn [vcoll] (map (fn [a b] {(keyword a) b}) (start "columns") vcoll)) (start "values")))

20:32 clojurebot: ({:name "testdb"} {:id 1} {:name "mydb"} {:id 2})

20:32 TEttinger: hm

20:32 pradeepchhetri: TEttinger: thank you for the solution :)

20:33 TEttinger: mine isn't right either!

20:33 it's partially there!

20:33 pradeepchhetri: yes .

20:34 mange: pradeepchhetri: Give my one a go if you want multiple columns as well.

20:34 TEttinger: ,(let [start {"name" "databases", "columns" ["name" "id"], "values" [["testdb" 1] ["mydb" 2]]}] (map (fn [vcoll] (into {} (mapcat (fn [a b] {(keyword a) b}) (start "columns") vcoll))) (start "values")))

20:34 clojurebot: ({:name "testdb", :id 1} {:name "mydb", :id 2})

20:34 TEttinger: yeah, mange yours looks rather concise, good job

20:34 pradeepchhetri: mange: cheers. i will definitely.

20:38 gfredericks: TEttinger: I couldn't tell what the requirements were

20:43 skeuomorf: What do you folks use to do static analysis "linting" while coding in emacs? -Something like, run linter on save-

20:43 I'm using CIDER FWIW

20:45 TEttinger: justin_smith: don't you make a tool that I can't remember the name of for lint-like stuff?

20:49 ah, https://github.com/jonase/eastwood

20:49 skeuomorf: TEttinger: Appears to fit the bill, thanks!

20:50 TEttinger: hope it does, glad to do some confused googling!

20:51 skeuomorf: I did some googling for "cider lint" and "clojure static analysis" but failed

20:51 I am new to the whole shebang, so had I known about "Flycheck" I might've been luckier

20:51 Shebang == emacs, clojure, CIDER

20:51 TEttinger: what got it for me was https://duckduckgo.com/?q=clojure+code+lint+tool

20:52 skeuomorf: nice

20:53 TEttinger: clojure lint found linters for Google Closure Compiler, thanks auto-"correct"

20:53 skeuomorf: hehe

20:53 I might've forgotten to google clojure linters and googled CIDER linters instead

20:54 zetlen: lint in my cider! nooo

20:54 skeuomorf: zetlen: Googling CIDER lint made me sad :D

20:55 Apparently there's flycheck-clojure as well, wonder how it differs from eastwood

20:57 Ahh, flycheck-clojure is https://github.com/clojure-emacs/squiggly-clojure which is eastwood inside emacs

21:12 zetlen: all right, folks: https://www.refheap.com/109077

21:13 i got some advice earlier to "use a reducer", of which map is one. i'm trying to parallelize this

21:13 my janky little strategy is to limit the number of threads to theoretically 26, by switching out `pmap` for `map` once you're two nodes down the trie

21:14 it's not working--i'm getting 20 to 30 seconds and at best 150% proc use, inside cider

21:14 i'm new to clojure--can anyone give me some guidance about parallelizing?

21:23 justin_smith: zetlen: pmap already restricts the maximum number of threads it uses

21:23 ~pmap

21:23 clojurebot: pmap is requires syntax quoting which most of the time

21:23 justin_smith: erm...

21:23 ~pmap

21:23 clojurebot: pmap is not what you want

21:23 arrdem: lol

21:23 justin_smith: I swear this bot was once more useful

21:24 arrdem: lazybot: ping

21:24 lazybot: arrdem: Ping completed in 0 seconds.

21:24 arrdem: $grim clj::clojure.core/pmap

21:24 * arrdem flips desk

21:24 arrdem: that PR has been merged for what 6 months now?

21:25 zetlen: infobots are particularly subject to entropy

21:25 i don't blame it

21:25 rhg135: An useful bot? I miss that.

21:26 zetlen: justin_smith: should i be managing my own thread pool?

21:26 arrdem: maybe we should make a 3rd bot named usefulbot....

21:26 zetlen: and just limiting it to the number of cores?

21:27 justin_smith: zetlen: that's one way to do it. I recently had to make a map-reducing function for my codebase and I opted for using core.async with a shared channel, and then controlling the parallelism by deciding how many go-loop blocks shared the same input channel

21:27 but you can also use a thread-pool

21:28 it depends on what your bottlenecks are, and you should probably be benchmarking a few options if it matters enough to go parallel

21:28 zetlen: justin_smith: it does, as silly as this looks, because i need to learn those techniques :)

21:30 justin_smith: a thread pool i more or less understand, but i want to be idiomatic about this. i don't honestly understand why pmap doesn't work--the trie is shared memory, immutable, and i imagined the threads working their way down it

21:30 so if i knew why i was switching to core.async it would give me direction

21:30 amalloy: justin_smith: pmap restricts the number of threads for a single call to pmap

21:30 but if f uses pmap to make N recursive calls to f...

21:31 justin_smith: amalloy: good point, yeah

21:31 amalloy: particularly relevant because that's what zetlen is doing

21:31 justin_smith: zetlen: one issue with pmap is that it parallelizes but it waits on results in order

21:31 amalloy: oh, I missed that, sorry

21:40 zetlen: zoinks! yes

21:41 in my impl of f, i switch out pmap with map at depth 2, and since this is the alphabet that should limit me to 26 threads, right?

21:47 amalloy: well i'd guess 26^2

21:47 but who knows

21:48 justin_smith is right in suggesting that if you want to manage parallelism you are better off using a real tool like an executor with a thread pool, rather than a toy like pmap

21:58 kanja: Is dire a good choice for new projects?

22:03 tmtwd: I am looking up "^ clojure" on google to find out more about the built in clojure type system

22:03 but I am not getting what I am looking for

22:04 arrdem: tmtwd: http://clojure.org/java_interop#toc30

22:05 tmtwd: Clojure doesn't have a "type system" in the conventional sense. ^foo hints are strictly advisory and for performance in the case of interop usage

22:05 tmtwd: can you mix in type hints with normal arguments

22:05 ?

22:05 arrdem: Yep!

22:06 (fn [^Long x] ..) totally works

22:06 tmtwd: like (defn yo [^String foo bar] (...))

22:06 so foo must be a String and bar is optional

22:06 arrdem: no, foo may be any object at all, but if you try to do Java interop on it, it will be cast to a String.

22:07 amalloy: and bar is not optional at all

22:07 arrdem: also true

22:08 amalloy: tmtwd: type hints, via ^, have (usually) no impact on semantics at all, only performance. it is not a type system

22:08 tmtwd: ah okay

22:08 amalloy: so yo has two arguments, both mandatory

22:08 tmtwd: okay

22:09 amalloy: which can both have any type, but it is probably a bad idea to pass anything but a string in the foo slot

22:09 tmtwd: I meant foo would be casted to a String and bar would be treated normally

22:10 amalloy: tmtwd: it will be cast to a string if any java interop is actually done to it. eg, ((fn [^String s] (.length s)) whatever) casts to a string. but ((fn [^String s] 5) whatever) doesn't

22:10 again, the function would have the same output whether or not you typehinted it; what's being discussed here re casting is just implementation details of how efficiently the runtime can give you that output

Logging service provided by n01se.net