#clojure log - Jun 01 2015

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

0:04 cfleming: Does Clojure's type inference ever attempt to infer a type for apply calls? I'm guessing not, since the arity is often not known at compile time. I've tried some simple cases and it appears to not work: (.length (apply str ["Hello"]))

0:06 bbloom: cfleming: i highly doubt it infers anything differently than that the return type of apply is "object"

0:07 cfleming: bbloom: Yeah, that seems to be the case, but I've been surprised recently while implementing inference so I thought I'd ask.

0:07 bbloom: i'm not surprised that you're surprised, since it's totally ad-hoc

0:09 cfleming: enjoyed your cognicast episode btw

0:09 cfleming: Yeah, in several cases I just copied the Compiler and Reflector code and modified it to use IntelliJ's type system.

0:09 bbloom: keep on fighting the good fight for tooling :-)

0:09 cfleming: bbloom: Thanks! It was fun.

0:09 I haven't had time to listen to yours yet - I don't commute, so finding time to listen to podcasts is challenging.

0:10 But the cognicast is always a good listen.

0:10 bbloom: I'm fighting it! Although I feel like I'm fighting the language sometimes too.

0:10 bbloom: cfleming: expected as well :-)

0:11 cfleming: bbloom: This inference has been way trickier than I expected.

0:11 bbloom: so many small details interact in such complex interesting ways

0:11 it's always harder to accommodate something you can't tweak for your needs

0:11 cfleming: Oh, I have plenty of problems with the big details too :-)

0:12 TEttinger: this is fun

0:12 ,(clojure.string/escape (-> (java.util.UUID/randomUUID) .getLeastSignificantBits Math/abs (Long/toString 26)) (zipmap (map char (range 48 58)) "qrstuvwxyz"))

0:12 clojurebot: "rntdifjrwkqqxx"

0:16 TEttinger: ,(-> (java.util.UUID/randomUUID) .getLeastSignificantBits Math/abs (Long/toString 26) (clojure.string/escape (zipmap (map char (range 48 58)) "qrstuvwxyz")))

0:16 clojurebot: "tufaqxcaijixdj"

0:16 TEttinger: horse names!

0:26 kristof: The problem with java-interop is that Oracle/Sun decided on horrendously long method names.

0:27 TEttinger: neat!

0:27 ,(let [u (java.util.UUID/randomUUID) num-str (fn [n cs] (let [cl (count cs)] (-> n Math/abs (Long/toString cl) (clojure.string/escape (zipmap (map #(first (Long/toString % cl)) (range cl)) cs))))) consonants (num-str (.getLeastSignificantBits u) "bcdfghjklmnprstvwxyz") vowels (num-str (.getMostSignificantBits u) "aeiou")] (apply str (interleave consonants vowels)))

0:27 clojurebot: "guladawaninehozakosagidemeguyi"

2:00 xapak: 6

2:16 borkdude: anyone here into boot? Is there any way I can have my public html/js/css in like "resources/public/js/foo.js" and have boot reload signal the browser to reload a file "/js/foo.js" and not "/public/js/foo.js"? I don't want to serve all of my app's resources

2:16 see https://github.com/borkdude/lein2boot

6:09 Deraen: borkdude: #hoplon is the best channel to talk about boot

6:12 borkdude: and currently, no. There is however https://github.com/adzerk-oss/boot-reload/pull/16 which would add support for it.

6:39 slavo: is there any tool for atuo generating requires and imports in emacs other than slamhound?

7:02 Glenjamin: are there some searchable channel logs somewhere?

7:02 $logs

7:02 ah, found them

7:27 Elvis_Presly: Hello, I have a watch on an atom, and I'm swapping the atom inside another thread

7:28 Why the watch doesn't trigger ? I tought atom were shared against all threads

7:48 vijaykiran: slavo: somethign like this : https://github.com/clojure-emacs/clj-refactor.el/blob/master/examples/magic-requires.gif

8:19 magnars: slavo vijaykiran: this one is quite nice: https://github.com/clojure-emacs/clj-refactor.el/blob/master/examples/add-libspec.gif

8:24 slavo: magnars vijaykiran thanks! that is exacly what i was looking for

8:30 sg2002: Hello. Is there anyone here who's using clojure.data.xml? I've found a rather weird bug in it and just want someone else to repeat it, before I'll submit it on the bug tracker.

8:31 arav93: Hi

8:31 How can I use leiningen on windows?

8:32 Empperi: you just download it and lein.bat

8:32 and use it like everywhere else

8:32 lein self-install doesn't work, that's your main problem

8:32 it requires *nix command line tools to work

8:35 arav93_: Hey, so leiningen for windows?

8:36 any idea on that?

8:38 TMA: arav93_: it works well enough under cygwin

9:01 alexyakushev: Hi everyone, are there any ClassLoader wizards online?:)

9:18 piranha: hmm... can somebody recommend me a library to implement facebook server-side authentication flow? :-)

9:23 drbobbeaty: piranha: Are you looking to connect to Facebook as a client and "do things"? Or is this to look "like" Facebook on the server you're making?

9:23 piranha: drbobbeaty: first one

9:24 drbobbeaty: piranha: I've forked a good starting point, and added a few things, but this works very well: https://github.com/drbobbeaty/clj-oauth2

9:25 piranha: There's an example on the README.md not to connect to Facebook, etc.

9:25 piranha: drbobbeaty: thanks!

9:25 drbobbeaty: piranha: No biggie... :)

9:25 piranha: that looks nice :)

9:26 I've looked at clj-oauth2, but last update was in 2012 and I feel like Facebook loves to change things :)

9:26 drbobbeaty: piranha: It works, I've been using it quite a bit to get the OAuth2 tokens, and then re-authenticating them as they expire. I've been calling the Facebook Ad Server endpoints, and it's just fine.

9:26 piranha: hm, ok, thanks :)

9:26 drbobbeaty: do you publish your version on clojars?

9:27 or there is no need?

9:27 drbobbeaty: piranha: Haven't, I sent a pull request to the original author

9:27 piranha: ah, ok

9:27 drbobbeaty: piranha: I was hoping for it to be merged... but I don't know if it's happened yet. I haven't looked recently.

9:28 piranha: doesn't seem so :)

9:28 drbobbeaty: piranha: Not surprising. What I added were a few things for Google, and the reauthenticate function to make it easy to do that too.

9:29 piranha: i.e. they aren't critical. Just nice to have.

9:30 piranha: ah, I see

9:30 drbobbeaty: thanks! Will try that :-)

9:39 sg2002: Is there a way to check java version from clojure repl?

9:40 Oh, found it.

9:45 oddcully: ,(get (System/getProperties) "java.version")

9:45 clojurebot: #error {\n :cause "denied"\n :via\n [{:type java.lang.SecurityException\n :message "denied"\n :at [clojurebot.sandbox$enable_security_manager$fn__889 invoke "sandbox.clj" 69]}]\n :trace\n [[clojurebot.sandbox$enable_security_manager$fn__889 invoke "sandbox.clj" 69]\n [clojurebot.sandbox.proxy$java.lang.SecurityManager$Door$f500ea40 checkPropertiesAccess nil -1]\n [java.lang.System getPropert...

9:45 oddcully: DENIED!

9:47 chouser: bbloom: aww, so you're not using finger trees anymore.

9:47 rrb-vector is probably faster, isn't it.

9:49 hyPiRion: For what purpose?

9:50 chouser: https://github.com/brandonbloom/fipp/commit/a2bd18a92a8480bd84a0410ae9041ed6f2fedcf0

10:20 charlespwd: exit

10:20 xemdetia: permission denied

10:22 charlespwd: Does reading an HTTPInput with slurp prevent from rereading it later? (I'm trying to figure out why (slurp (body :req)) returns nothing when my form-params are not empty)

10:22 stuartsierra: charlespwd: yes

10:24 charlespwd: Followup question, does this mean I have to "unwrap" the middleware that parses the body if I need the raw body?

10:25 stuartsierra: thanks

10:25 stuartsierra: charlespwd: I think so, yes.

10:26 hyPiRion: charlespwd: Is this by any chance related to wrap-params?

10:28 mmg: is there any rumor of a 1.7 release date? I’m trying to plan my app’s upgrade schedule and if I can wait for 1.7 or not

10:28 charlespwd: hyPiRion: it would be the cause, yes. It's because I need to verify a hmac signature with the raw body.

10:29 And I'm not sure if I can trust form-params would be in the right order.

10:35 hyPiRion: charlespwd: Oh, I see. I tend to associate new keys into the request map. So I'd probably do something like (let [body (slurp (:body req))] (response (assoc req :body (ByteArrayInputStream. (.getBytes body)) :body-str body)))

10:35 In a middleware ran before the form param one

10:39 charlespwd: hyPiRion: That is just perfect. And way more elegant than what I was about to do.

10:40 hyPiRion: oh, np. I've been there myself =)

10:47 sdegutis: Is there a way to configure the JVM to instantiate a large object graph much quicker? I have lots of memory and CPU power to spare.

10:48 TimMc: mmg: I would go ahead and test against 1.7 RC to make sure it is forward compatible.

10:49 Is there anything you specifically want from 1.7? Otherwise, I'd stick with 1.6 since it is better characterized.

10:49 (Sorry, probably unsolicited advice you didn't want.)

10:50 mmg: TimMc: I’m on 1.5, if I’m getting the resources to fully regression test my app, I’d rather make the jump to 1.7 instead of 1.6 and then have to do this again in 2 months

10:50 tbaldridge: mmg: also, I'd ask if there's a problem with going to RC now, and switching to the actual release in the future

10:50 sdegutis: mmg: I'm on 1.5.1 and I'm planning to move to 1.6 and then 1.7 just to be sure

10:50 tbaldridge: the changes from 1.5->1.7 are way more than 1.7RC to 1.7 release

10:51 mmg: tbaldridge: but the effort from the test perspective are the same….

10:51 tbaldridge: There were some changes to undocumented things (the way collections are hashed, etc.) in 1.6. That's where 90% of my upgrade problems came from

10:52 mmg: how long does it take to test a new Clojure release?

10:52 stain: sdegutis: try java -X and options like -Xms and -Xss -- you can also use java.io.Serializable to quickly load up from disk or something

10:53 depending on the types of your graph of course

10:53 tbaldridge: in the projects I worked on it mostly involved switching the deps over, running the test suite, and then going through a normal QA/Release cycle.

10:53 What took the longest was fixing bad tests that assumed ordering in hashed collections.

10:54 mmg: tbaldridge: “and then going through a normal QA/Release cycle.” that’s the part that’s a problem. resources are limited, if it needs to go through a “normal qa/release cycle” I want to make that investment once if I can

10:54 stain: sdegutis: also look at https://github.com/ptaoussanis/nippy

10:54 mmg: tbh I’m not here to talk about project management, and don’t take that the wrong way, I was hoping there might be a release date

10:54 if not, no big deal, thanks

10:55 sdegutis: Thanks.

10:55 I'm trying to speed up the creation of an in-memory database in Datomic.

10:55 tbaldridge: no, no release date.

10:55 sdegutis: It's relatively quick, but when I do it 600 times in a row, it takes up to a minute.

11:13 Back.

11:16 madmax88: Greetings, lispers! Suppose I need coordinated, asynchronous access to a Java OutputStream and InputStream. Should I use an agent, or a ref?

11:16 sorbo_: I might be misunderstanding, but how can you be coordinated and async?

11:17 wouldn't being asynchronous mean you can't coordinate, since you don't know when things are going to come back?

11:19 madmax88: I might have a flawed understanding of Clojure's asynchronous handling, but here's what I want to do: I have a bit of asynchronous code, and I have a couple of streams I need to write to and read to. It matters that once one thread writes to the input stream, it reads from the output stream next

11:20 So, I want to coordinate access between threads so this is possible

11:20 justin_smith: sorbo_: async and coordinated means the call to alter the value returns immediately (before it takes effect) but the value changes are coordinated with other changes (retried as needed to ensure all take effect)

11:20 TimMc: madmax88: (you've got read and write reversed there)

11:20 chouser: madmax88: I don't think a ref is going to help you. Any code writing to a ref will do so inside a dosync, and code in a dosync can be re-run multiple times, so not appropriate for side effects like io streams.

11:21 justin_smith: sorbo_: classic example would be bank account - you ensure that all transactions from the account take place exactly once, but the deposit you made just now might not be visible until later

11:21 m1dnight_: How come a future that is cancelled still stops my application from exiting?

11:21 sorbo_: justin_smith: got it

11:21 but wouldn't you use a ref for that?

11:21 justin_smith: sorbo_: refs are not async

11:21 TimMc: m1dnight_: Wait 60 seconds, does it still fail to exit?

11:21 sorbo_: true

11:21 m1dnight_: ill check.

11:21 justin_smith: sorbo_: the update of the ref completes before the updating function returns

11:22 madmax88: TimMc: not exactly. In this case, the input stream is a process' stdout, and the output stream is the process' stdin

11:22 stian: sorbo_: I think i would try an agent (holding both the input and output) .. if you need to deal with sideeffects.

11:22 sorbo_: justin_smight but AFAIK Clojure doesn't have a coordinated async reference type

11:22 justin_smith: sorbo_: on the other hand eg. agents are async - you could have a long line of alterations in a queue waiting to go through before yours does

11:23 m1dnight_: Is it the threadpool or something in the background that has a timeout if no futures are added or something? It seems to stop after a while indeed.

11:23 sorbo_: *justin_smith rather

11:23 spelling is important

11:23 TimMc: m1dnight_: That's the agent threadpool, yeah. Check out shutdown-agents. You can call it when exiting from -main.

11:23 madmax88: stian: I have already done it with an agent, but I'm worried that once more threads are adde, it'll break

11:23 TimMc: System/exit will do it too, naturally

11:23 m1dnight_: aha, didnt think of that in context of futures. thanks timc

11:24 justin_smith: sorbo_: I think that's right - agents are not coordinated

11:24 TimMc: m1dnight_: There are a few things in core that use those threadpools, including pmap and other concurrency tools.

11:24 sorbo_: justin_smith right, that makes sense.

11:24 justin_smith: sorbo_: and they are the only async type of the basic clojure reference types

11:24 m1dnight_: ,(inc TimMc)

11:24 sorbo_: right, since both refs and atoms are sync

11:24 m1dnight_: (inc TimMc)

11:24 clojurebot: #error {\n :cause "Unable to resolve symbol: TimMc in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: TimMc in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: TimMc in this...

11:24 m1dnight_: sorry about that guys

11:24 justin_smith: m1dnight_: lazybot seems to be out

11:24 m1dnight_: it used to be that exceptions were much less spammy

11:25 I wonder if we can fix that again...

11:25 m1dnight_: next time then! ill keep it mind.

11:25 justin_smith: m1dnight_: eh, it's easy to make mistakes, we should have bots that simply tell us the exception, not print out a complex object state

11:25 TimMc: amalloy_: deadbot

11:54 justin_smith: madmax88: what about agents would break with more threads?

11:56 madmax88: After reading the documentation, I didn't think anything would, but I was still concerned. I'm a relatively new Clojure user, and I didn't want to make a mistake like that

11:57 justin_smith: madmax88: the one gotcha I guess would be if you had enough contention on the agent that the thread count and queue size got too big

11:58 but you'll need some other plan if you want tens of thousands of concurrent writes / reads anyway

11:58 nothing built in is likely to do the right thing :)

11:59 madmax88: So if it failed, it would just fail because the threadpool gets too big?

11:59 justin_smith: or the queue size for waiting actions, one of those

11:59 might be fun to stress test it and find out for sure

12:01 madmax88: Alright, sounds good. Thank you! By the way, if someone wanted to do massive amounts of concurrent io, is there a framework you'd recommend?

12:01 justin_smith: make sure whatever you are using has java.nio under the hood - and perhaps use java.nio directly

12:02 which requires min java version of 1.7

12:02 I am not sure about frameworks, but I wouldn't be surprised if you saw ztellman or aphyr somewhere in the commit log if there was one

12:03 chouser: madmax88: have you considered core.async?

12:03 not sure if it would be a good fit for you or not

12:04 justin_smith: chouser: so maybe java.nio async filesystem access in go blocks? or is there something higher level?

12:05 SagiCZ: i was actually trying to read very large text files into channels

12:05 chouser: Not sure -- haven't been reading too closely here, but if you've got multiple threads trying to access a shared mutable resource, you can protect that resource a few ways.

12:05 SagiCZ: it was very difficult to make it work lazily.. you have to check when the last item is read to close the reader

12:06 but i was possible with chans.. it couldnt work with simply lazy-seq

12:06 chouser: one is to only use that resource from inside an agent action. Another is to put a classic lock around it. Another may be to wrap it in a go block or thread and provide access via async channels.

12:07 justin_smith: chouser: makes sense. I have heard warnings about using go blocks for things that block (like IO), but maybe java.nio changes the rules for that enough for that to make sense

12:07 chouser: no, you're probably right. For io I think you'd want 'thread' instead of 'go'

12:08 SagiCZ: justin_smith: i am using go blocks for that.. never seen any warning like that, why is it a bad idea?

12:08 tbaldridge: SagiCZ: go blocks are limited to a certain number of threads

12:08 thread blocks are unlimited.

12:08 justin_smith: well, I dunno about "right" - just trying to figure out what makes sense out of various bits of info I have seen

12:09 tbaldridge: So if you do this (dotimes [x 1000] (go (Thread/sleep 100000))) You will cause the threadpool to block and no other go will be able to run

12:09 SagiCZ: tbaldridge: ok what do you mean by limited to a ceratin amount of threads? do you mean only a certain amount of threads can <! from the chan?

12:09 chouser: oh. hi, tbaldridge!

12:09 * chouser stops giving core.async advice.

12:10 SagiCZ: oh.. so only certain amount of threads can use go block simultaneously

12:10 justin_smith: SagiCZ: core.async is backed by a thread pool of fixed size, all go blocks are served from that one pool

12:11 SagiCZ: and the fixed size is smaller than 1000?

12:11 justin_smith: SagiCZ: (thread count * 2) + 42 iirc, something like that

12:11 tbaldridge: SagiCZ: so go blocks are really only callbacks with syntactic sugar. Those callbacks are run inside a dedicated thread pool. That thread pool is imited to ((NCPUS * 2) + 42). Large enough to be somewhat forgiving of blocking io. Small enough that the memory consumption/ context switching shouldn't hurt you.

12:12 justin_smith: haha, of course i meant ncpus not thread count

12:12 SagiCZ: tbaldridge: thanks.. i guess i kinda get it although i must admit that the implementation sounds like black magic

12:13 btw is core.async still actively developed/used?

12:13 tbaldridge: oh yeah, core.async got trasducer support last year. And I use it daily with large enterprise clients.

12:13 SagiCZ: great to hear!

12:16 Bronsa: alexyakushev: I hacked a bit on DynamicClassLoader, I might be able to help

12:20 sdegutis: I like the idea of chaining computations that take into account the previous function's result, propagating either results or errors. Is this idiom common in Clojure?

12:21 solussd: sdegutis: you mean function composition, or are you thinking continuations?

12:21 gfredericks: or the either monad?

12:21 sdegutis: solussd: closer to an either monad

12:21 gfredericks: yeah that

12:21 solussd: does anybody know if it is possible to make the clojure pretty printer print each mapentry in a map on its own line?

12:22 justin_smith: sdegutis: we have nil-safe chaining with some-> / some->>, but I don't know of something that propagates errors

12:22 ToxicFrog: solussd: there's pprint, although I forget what namespace it's in

12:22 I also don't know if it's guaranteed to be repr-clean

12:22 justin_smith: ToxicFrog: it doesn't always do one entry per line

12:22 ToxicFrog: justin_smith: oh!

12:22 solussd: There’s the clojure.algo.monads library that has what you’d need to build it

12:22 justin_smith: ToxicFrog: clojure.pprint/pprint

12:22 ,(require 'clojure.pprint)

12:22 clojurebot: nil

12:22 justin_smith: ,(clojure.pprint/pprint {:a 0 :b 1})

12:22 clojurebot: {:a 0, :b 1}\n

12:23 solussd: pprint doesn’t print maps with each entry on its own line— I was hoping there was a way to tell the printer to do that..

12:23 justin_smith: see, two entries on one line

12:23 alexyakushev: Bronsa: Thank you, I think I figured that problem is not with Clojure. I'm trying to load Clojure in an environment with different classloader, and it fails when it tries to load pre-compiled Clojure classes (e.g. clojure.stacktrace)

12:23 Bronsa: Now I think the problem is with that parent non-Sun classloader

12:24 SagiCZ: when you make a defrecord or defprotocol is it available only in its current namespace?

12:25 tcrayford____: SagiCZ: nope. Protocols define functions just like normal functions

12:25 sdegutis: saltsa: thanks, though I've heard bad things about using literal Haskell monads in Clojure considering Clojure can't dispatch differently on 0-param functions like Haskell can

12:25 I meant solussd sorry

12:25 tcrayford____: SagiCZ: and records are just java classes under the hood (they also define map->MyRecord and ->MyRecord functions for creating them)

12:26 justin_smith: SagiCZ: some things are bound to vars, and those are only accessible from the namespace, some things are made as classes, which are available for usage or import via the namespace's corresponding package

12:26 SagiCZ: tcrayford____: so are they classes in the default package?

12:26 solussd: sdegutis, Yeah, I don’t have much real-world experience using monads in clojure— I used the maybe monad for some exception handling once.

12:26 justin_smith: SagiCZ: no, my.ns/MyRecord is of class my.ns.MyRecord

12:27 but you should require the namespace before using the class, to ensure it is constructed by clojure

12:28 SagiCZ: i see.. i will need some function that would automatically require all ns in a specified directory then

12:28 tcrayford____: SagiCZ: what're you building?

12:30 SagiCZ: tcrayford____: the truth is I would need some help with the design, but it is a pretty complex thing so I first I need to find out what questions to ask

12:30 justin_smith: sounds like DI

12:30 SagiCZ: just a hunch - code against some protocol and not the specific records, and make sure the protocols are required

12:30 tcrayford____: SagiCZ: would strongly recomend against any API that involves the filesystem, namespaces or vars. They tend to be pretty weird to use

12:30 justin_smith: but given the level of info here I could be way off base

12:31 tcrayford____: (likewise)

12:31 SagiCZ: justin_smith: if I require the protocols .. I then just have to require those records that I want to instantiate, correct?

12:33 simply said.. there is an event queue.. and then there is a group of animals that consume the queue.. each animal can behave differently (traditional polymorphism).. but since the behavior is pretty complex I want to define each animal (defrecord) in its own namespace... exactly as with Java classes... before that I used multimethods but I found them unnecessary since I dispatch only on the type of the animal and nothing else

12:35 SagiCZ1: ~lazy-logs

12:35 clojurebot: lazy-logs is http://logs.lazybot.org/

12:35 tcrayford____: SagiCZ: so why can't your API consumer pass the instantiated set of animals into your queue? Constructing them via reflectiony magic seems pretty weird to me

12:35 (but might be missing context)

12:36 SagiCZ1: well they have to be instantiated somewhere right?

12:36 tcrayford____: right, but you can just call (map->MyRecord) a few times

12:37 SagiCZ1: wait what? sorry I dont know this construct

12:37 i thought records are instantiated like this (MyRecord. params)

12:37 tcrayford____: when you define a record, it also defines these functions: ->MyRecord

12:37 and map->MyRecord

12:37 (the first is positional, the latter takes a map)

12:38 SagiCZ1: wow it does!

12:39 but these functions are automatically defined in the same ns as the record right

12:39 sdegutis: Time to write tons of really really bad code because deadline.

12:43 tcrayford____: SagiCZ1: right

12:44 SagiCZ1: so instead of requiring the record class with :import I will have to :require the namespace

12:44 bendlas: tbaldridge: any plans to unify clojure.core.async and cljs.core.async, now that reader conditionals are here?

12:45 tbaldridge: it could possibly be done, but that would lock users of core.async into 1.7.

12:45 Also the CLJS go macro needs to be unified with the CLJ go macro and that requires a CLJS version of tools.analyzer. Not sure what the status is on that.

12:47 bendlas: tbaldridge: tools.analyzer.js, I'd really like to see that extracted from clojurescript

12:48 would start it myself, if I didn't feel guilty about finishing data.xml before

12:49 tbaldridge: one thing that contrib projects would benefit massively from, is a maven plugin to backport files with reader tags to older clojure versions

12:50 that way, users of older clojure versions could benefit from reader tags as well

12:50 like, treat older clojure versions as just another read-cond feature

12:53 dfletcher: heh some? is a sligtly odd name for the opposite of nil?. i just typed (filter some? results). sounds way more sloppy than it actually is. "oh you know, just give me some results, whatevs" :)

12:54 gfredericks: ~clojure is all about slightly odd names

12:54 clojurebot: You don't have to tell me twice.

12:54 cap10morgan: We're using Datomic for our data persistence layer, but we have run into some situations where we need to store arbitrary EDN data whose structure isn't known ahead of time. Datomic doesn't seem like a great fit for this. What are other folks in the Clojure community using here? (Or do we have it wrong and Datomic is great for this?)

12:59 bendlas: cap10morgan: I store blobs by their content-hash in the file system, like git does, and then store the file hash into datomic

12:59 you could do the same with edn data, by storing it fressian-encoded

12:59 cap10morgan: bendlas: hmm, interesting

13:00 bendlas: cap10morgan: that is, as long as you don't need any indices over parts of that EDN

13:01 cap10morgan: bendlas: we do sometimes. what we're imagining now is that incoming data would say "these key-values are identifiers that I'd like to use to query for this data in the future and the rest is just a blob I want you to store for me"

13:01 for the former I was thinking of dynmically adding attributes to the datomic schema

13:02 bendlas: yeah, that could work

13:02 cap10morgan: here is my blob store, of you don't want to reimplement it: https://github.com/webnf/webnf/blob/master/filestore/src/webnf/filestore.clj

13:02 cap10morgan: bendlas: cool, thanks. I'll check it out.

13:13 sdegutis: Is there something like defmulti/defmethod, but that will dispatch based on which key exists?

13:14 I have different maps, and I want to dispatch based on which map has which key.

13:14 I can easily do this with cond, but that doesn't allow extension from without.

13:15 devth: is `difference` the idiomatic way to remove a single item from a set?

13:15 solussd: sdegutis: you can do it with defmulti, too

13:15 sdegutis: Oh maybe (partial contains?)

13:16 solussd: well, your dispatch function would still have to enumerate all possibilities .. guess that isn’t quite what you want.

13:17 sdegutis: Right.

13:17 Any other things Clojure has to offer for this?

13:19 luxbock: sdegutis: what should happen if more than one of the keys are present?

13:19 sdegutis: luxbock: they never will be

13:19 xemdetia: sdegutis, did anyone mention core.match and defun https://github.com/killme2008/defun

13:20 sdegutis: xemdetia: you ;)

13:20 xemdetia: o

13:20 sdegutis: xemdetia: just now I mean ;)

13:20 solussd: maybe you should make the key the value of the :type key in metadata and dispatch using the `type` function. :)

13:20 sdegutis: xemdetia: anyway core.match doesn't allow extension from without

13:20 l1x: hi guys, any om/reagent person around? i have few questions how to design a brand new application using reagent or om

13:20 sdegutis: xemdetia: same with defun

13:25 xemdetia: sdegutis, can you explain what you mean by 'extension from without'

13:25 sdegutis: xemdetia: in another file, I want to add another handler

13:25 another defmethod so to speak

13:26 justin_smith: l1x: #clojurescript will likely be more helpful. I highly recommend setting up figwheel from the very start.

13:26 devth: you can use dissoc on sets ##(dissoc #{:a :b} :a)

13:26 ,(dissoc #{:a :b} :a)

13:27 clojurebot: #error {\n :cause "clojure.lang.PersistentHashSet cannot be cast to clojure.lang.IPersistentMap"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentHashSet cannot be cast to clojure.lang.IPersistentMap"\n :at [clojure.lang.RT dissoc "RT.java" 834]}]\n :trace\n [[clojure.lang.RT dissoc "RT.java" 834]\n [clojure.core$dissoc invoke "core.clj" 1438]\n [sandbox$eval2...

13:27 devth: justin_smith: oh nice didn't know that. thanks

13:27 justin_smith: n/m bran fart

13:27 devth: ah

13:27 i thought i had tried it :)

13:27 tbaldridge: ,(disj #{:a :b} :a)

13:27 clojurebot: #{:b}

13:27 justin_smith: that's the one!

13:27 (inc tbaldridge)

13:27 devth: tbaldridge: ty

13:27 sorbo_: l1x: +1 for justin_smith's recommendations (checking out #clojurescript && using figwheel)

13:28 l1x: justin_smith: thanks!

13:28 i have figwheel and it is amazing

13:28 justin_smith: figwheel is great, and easier to start with it than to add it later

13:28 J_Arcane: Figwheel is indeed quite handy.

13:28 luxbock: sdegutis: if you know all the keys that can be present when you create the defmulti, then you could use (fn [m] (some #{:foo :bar :baz} (keys m))) as the dispatch function

13:29 J_Arcane: Even if you don't use the REPL functions, just having a live reloading to the actual running javascript instead of just autorecompile saves significant pain.

13:31 sdegutis: ok thanks

13:33 sorbo_: the fact that it picks up CSS is great too

13:34 !lein scss once from inside Vim & it updates after compilation

13:34 slower than the on-edit changes to CLJS but still great

13:35 travisrodman: sdegutis: are you still looking for an answer to this question?

13:35 justin_smith: sorbo_: see also lein less auto

13:36 sdegutis: travisrodman: sure

13:36 travisrodman: sdegutis: cool...

13:37 a system I wroted needed plugins to be loaded, at runtime, and add them as message handlers to a running system

13:37 sorbo_: justin_smith: oh nice

13:37 travisrodman: it sounds a little like what you are describing

13:38 so, to make this happen, I had a file watcher on a directory, looking for new files to be dropped, but this could be any io to get the text into your system

13:39 on system startup, I had a map, stored in an atop and a dispatching function that took a key and '& args' to pass to the function

13:40 then, I wrote a macro of the form (defhandler KEY (fn [d] ... )) that would expand to install the function in the map

13:40 all of the functions would get handed the sequence of args, and pulling the function related to the key was trivial.

13:41 I then just applied the matching function to then arguments, which the writers of the handlers were able to produce, and it was an extensible plugin system for a running system

13:42 does that seem like a viable answer to your issue?

13:43 so, the essentiall calling function looked like this: ((get fn-map :key) args)

13:44 sdegutis: neat

13:45 I think I solved it with (defmulti my-fn #(partial contains? %))

13:45 travisrodman: the defhandler code above was similar to: (assoc fn-map (keyword key) (fn...))

13:45 okay... cool

13:45 sdegutis: thanks travisrodman

13:45 travisrodman: np

13:55 sdegutis: never mind. solved it with (cond).

13:55 cuz deadline

13:57 solussd: use case, since the values are compile-time literals

13:57 travisrodman: i read once, all the most interesting functions contain a cond

13:58 :b#

13:58 argh... sorry vim command...

13:58 sdegutis: solussd: don't see how that's possible here

13:59 solussd: I'm switching based on keys that may exist inside the map

13:59 Shayanjm: in cider, is there some equivalent to the 'up' button in terminal? i.e: autofilling the last expression sent to the REPL without executing it?

13:59 solussd: oh right-

13:59 condp ? :) that’d be a little nicer

14:00 justin_smith: Shayanjm: M-p

14:00 sdegutis: solussd: ah yeah totally

14:00 justin_smith: that is, Meta-p

14:01 Shayanjm: also, if you have something partially typed, it acts similar to Control-R in the terminal

14:01 Shayanjm: ooh, awesome thanks justin_smith

14:25 sdegutis: You know how idiomatic Clojure advocates consuming and returning raw data and letting call-sites interpret that data?

14:28 postpunkjustin: sdegutis: could you give an example? I'm not sure what you mean.

14:29 sdegutis: I bet justin_smith could give the best example.

14:29 He's super good at Clojure.

14:30 postpunkjustin: yes, yes he is.

14:30 xemdetia: I think he means more the general lisp style of call a function with a value and return value' after the operation has completed

14:32 postpunkjustin: sdegutis: are you asking a question or making a point?

14:34 sdegutis: xemdetia: no I mean that Clojure is very data-oriented rather than type-oriented or abstraction-oriented

14:34 xemdetia: it has a few abstractions, such as how anything can implement IFn or IAssoc or whatever

14:34 but mostly, you just work with raw functions and raw data

14:35 xemdetia: yes, that's the quality of a lisp

14:35 justin_smith: raw-dogging, the language

14:35 sdegutis: I'm starting to notice that this usually leads to lots of tight coupling.

14:36 justin_smith: sdegutis: because I return a hash-map, I am tightly coupled to other code in that I force it to consume a hash-map?

14:36 or do you mean the implicit structure of that hash-map

14:36 sdegutis: justin_smith: I guess I mean the keys in your map example

14:37 justin_smith: and that the structure of any data can't easily change once someone starts consuming it

14:37 justin_smith: for that, I find prismatic/schema helps reintroduce sanity

14:37 at the least, it explicitly describes the expected shape of the data structures

14:39 sidharth1: sometimes i'm a clumsy developer, so i'm wondering if there is a way i can determine at run time whether my clojure code is running in the cider nrepl or running from a jar or standalone jar ?

14:41 mikerod: justin_smith: I find prismatic/schema gets addictive

14:41 then I start wanting to put schema on nearly everything

14:41 justin_smith: sidharth1: you could determine this based on the classpath, or by the output of (System/getenv "pwd"), or (.getHostName (java.net.InetAddress/getLocalHost))

14:42 mikerod: and this is a problem?

14:42 mikerod: then I start feeling like I'm not doing dynamic typing anymore

14:42 :P

14:42 justin_smith: sidharth1: a real solution is determining your runtim via something like environ

14:42 mikerod: even though it isn't "statically checked"

14:42 sidharth1: justin_smith: wow, great thoughts

14:42 justin_smith: mikerod: heh, at least schema is strictly opt-in

14:42 mikerod: yes, I tend to turn them on during testing

14:42 justin_smith: sidharth1: of course by "pwd" I actually meant "PWD

14:42 mikerod: I'm just making an observation though and schema doesn't really get in the way as much as a static checker would

14:43 justin_smith: mikerod: and unlike core.typed (for better and worse) it doesn't force transitive usage of its annotations

14:43 mikerod: we tend to find schema very useful for its consistent documentation style as well

14:43 justin_smith: yup

14:43 mikerod: good point on the non-forced transitives

14:49 dnolen: ClojureScript 0.0-3308 released https://groups.google.com/forum/#!topic/clojurescript/kNIKpsFgvyk

14:53 celwell: Hi, I want a function to return its value quickly (it's part of a web service user action on a mobile app) but the function needs to initiate an email sending. Should I use future to call the email sending function?

14:54 justin_smith: celwell: as long as the reply doesn't need to indicate to the client that the email send succeeded, sure

14:55 celwell: cool, and I won't have any issues with threads building up? do they get killed automatically?

14:55 after evald?

14:55 justin_smith: celwell: futures execute immediately and their thread is returned to the available pool when they finish executing

14:56 celwell: thanks

14:56 justin_smith: if you hold onto a handle to the future, it will be available for later examination of the return value / receipt of exceptions it may have encountered

14:57 celwell: one thing to watch out for is by default you don't see errors unless you access the future's value, but stuartsierra had a good blog post about this recently

14:57 celwell: But I have exceptions logged for it, that would work still right?

14:57 justin_smith: celwell: http://stuartsierra.com/2015/05/27/clojure-uncaught-exceptions

14:58 celwell: if you are explicitly using try catch that should work out - be sure to check out that blog post

14:58 there are some tricky corners there

16:22 amalloy: andyf: i'm curious why you're so enthusiastic about flatland/ordered

16:23 bmorphism: Hi, I'm trying to speed up some parallel code (https://www.refheap.com/666e0750586b3c05232d067d2) and was wondering if anything else could be changed to improve it? Would appreciate any feedback!

16:26 justin_smith: ~pmap

16:26 clojurebot: pmap is requires syntax quoting which most of the time

16:26 andyf: bmorphism: You have a pmap whose function does very little work there, only a format call on a string I'm guessing is not terribly large.

16:27 justin_smith: ~pmap

16:27 clojurebot: pmap is not what you want

16:27 justin_smith: that's the one I was going for

16:27 andyf: pmap creates a separate thread object for every function call, which is a lot of overhead for a quick function

16:27 tbaldrid_: bmorphism: I'd look into core.async's pipeline functions

16:28 bmorphism: andyf: thanks, took it out

16:28 tbaldrid_: but yeah, it will still have some overhead

16:28 andyf: bmorphism: It also was not obvious what size the batches were in your remaining pmap use

16:30 pmap can be used to get parallelism speedup, but I'd estimate that you would want the individual function calls to take on the order of a second or so of CPU time to see it (i.e. closer to the order of a second than to 1 millisecond or less)

16:30 tbaldrid_: andyf: I wonder what would happen if he put a partition before the pmap, and then a concat at after

16:30 bmorphism: tbaldrid_: will do, I've seen mapcat> in the docs; I've tried transducers and 1.7.0-RC1, for better or worse: https://www.refheap.com/a81642a4f0927a8079a65ba7e

16:30 tbaldrid_: poor-man's batching

16:30 bmorphism: andyf: All words from the Unix words file =)

16:31 Switching the inner pmap to map has improved performance substantially! (from ~5MB / sec written to disk to ~9 MB / sec on my machine)

16:31 tbaldrid_: bmorphism: https://clojure.github.io/core.async/#clojure.core.async/pipeline

16:32 bmorphism: one of the problems with your transducer example is that you're still using sequences

16:33 bmorphism: tbaldrid_: pipeline looks very promising! shoving the transformations into it to see what I can get now

16:33 tbaldrid_: If you want some serious performance you'll want to use transducers from start to finish. That means making a file that implements IReduce and a reducing function to write to disk

16:33 andyf: bmorphism: Put (set! *warn-on-reflection* true) after the ns form and recompile to get reflection warnings. You may not have any, but if you do, and they are in a hot code path, figure out how to eliminate them, usually via type hitns

16:34 tbaldrid_: doing that I've easily done way above 17MB/sec for this sort of thing before

16:34 andyf: hints

16:34 tbaldrid_: also take a look at: https://github.com/thebusby/iota

16:36 andyf: minor point, but (format "%s\n" s) will create a copy of s before it is written out. You might want to try calling .write method twice with s and then "\n", or use a method that appends the newline for you.

16:37 bmorphism: tbaldrid_: Thanks! Do you have any open examples of transducers-throughout? I'm very new to the concept

16:37 andyf: No warnings so far, and good point about format, making it a double-write; I used (str ...) before, but afaik that also creates a copy

16:38 andyf: bmorphism: yes, str also creates a copy, at least if it has multiple args. Not sure if it only has 1.

16:39 justin_smith: ,(apply identical? ((juxt identity str) "word")) ; andyf

16:39 clojurebot: true

16:42 justin_smith: ,(apply identical? ((juxt identity (partial format "%s")) "word"))

16:42 clojurebot: false

16:43 andyf: bmorphism: Isn't number-ending called with a 'batch' of one word only?

16:43 justin_smith: ,(apply (juxt = identical?) ((juxt identity (partial format "%s")) "word"))

16:43 clojurebot: [true false]

16:45 andyf: bmorphism: Have you tested performance with all pmap calls replaced with map ?

16:45 bmorphism: andyf: Oh, as such, yes, sorry -- I meant that the words come in lazily from the reader, reading the text file with all the words

16:46 andyf: I seem to recall that it was slower, testing again

16:47 andyf: Might want to compare run time with (format "%s%s" word %) replaced with (str word %) to see if there is any difference. I don't know how those compare off-hand.

16:47 bmorphism: andyf: Wow, substantially better ~14 MB / sec now!

16:48 andyf: bmorphism: Yeah, your pmap batches are so small that the creation of threads is slowing you down noticeably.

16:49 bmorphism: andyf: I also got a few reflection warnings

16:49 call to method write on java.io.Writer can't be res

16:49 olved (argument types: unknown).

16:49 woops, sorry about multiline

16:51 andyf: prefixing w with a type hint of ^java.io.Writer, and/or the 2nd arg to .write with ^String, may help eliminate those.

16:51 Probably the String one, given the message.

16:51 bmorphism: Up to 25 MB/s having replaced format with str, gotta love the SSD!

16:54 andyf: amalloy: Sorry, didn't notice your message before now. It fills a request made by people I've seen periodically on the Google group. Since I've made link to it in the cheat sheet, I figured I'd try making sure its docs were reasonable for relative newcomers.

16:55 amalloy: I don't plan on enhancing it indefinitely. Don't worry :)

16:56 tbaldrid_: bmorphism: another thing you can do is pass the output stream into the add-ending function, that will allow you to remove all calls to str.

16:56 Strings are immutable, so each call to str involves a O(n) copy of the input strings

16:59 bmorphism: tbaldrid_: Interesting! So instead of mapping #(str ...), map two .writes, one for word and another the ending?

17:00 tbaldrid_: right.

17:00 it's less functional, but it should be faster.

17:00 you can get rid of all the mapcats, conj, etc.

17:02 bmorphism: Will test in that version as well! Even still, 5MB / sec -> 25 MB / sec for a few simple changes is a great success! Thanks andyf, tbaldrid_!

17:03 SagiCZ1: when calling a protocol function on an instance of record i have to use the dot notation right?

17:13 credulous: Starting to use Korma -- where is the best place to put the defdb macro calls? In entities.clj where I define the entities?

17:41 gfredericks: SagiCZ1: no, protocol functions can be called as regular functions

17:41 ,(defprotocol Foo (foo [_]))

17:41 clojurebot: Foo

17:41 SagiCZ1: yeah.. i had some other issues with my project

17:41 i dont really understand how the defprotocol works and what has to be required to be able to implement it in a different ns

17:45 gfredericks: the protocol itself and all the associated functions are vars

17:45 so they get required as normal

17:45 SagiCZ1: really

17:45 so i dont have to (:import Classname) ?

17:45 gfredericks: both defprotocol and defrecord generate classes/interfaces, which have to be imported specially, *HOWEVER* you can usually get away with not using the classes/interfaces at all

17:46 SagiCZ1: that sounds odd

17:47 gfredericks: not sure how to make it sound not odd

17:47 SagiCZ1: how am i supposed to know when i can get a way with it

17:48 gfredericks: protocols you almost never need the interface

17:49 records you only do if you have to actually use the class name, like if you're extending a multimethod or using extend-type or extend-class or something like that

17:49 anywhere you could use a normal java class as well

17:49 SagiCZ1: i see.. well that explains it well

17:49 gfredericks: you don't need to call the constructors directly because defrecord generates two constructor fns for you

17:50 ,(defrecord Heyo [a b c])

17:50 clojurebot: sandbox.Heyo

17:50 gfredericks: ,(->Heyo 1 2 3)

17:50 clojurebot: #sandbox.Heyo{:a 1, :b 2, :c 3}

17:50 gfredericks: ,(map->Heyo {:a 3})

17:50 clojurebot: #sandbox.Heyo{:a 3, :b nil, :c nil}

17:50 gfredericks: and those are regular vars that you can require

17:50 SagiCZ1: yeah i found that out today

17:50 so they are regular vars but they are invisible in the source code

17:50 gfredericks: so I rarely ever import anymore w.r.t. records and protocols

17:50 yep

17:51 SagiCZ1: Cursive is just not cooperating

17:52 and I only ever say nice thing about Cursive

17:56 is cfleming ever around anymore?

17:58 sdegutis: Ok. Finished working for the day. Ready to answer Clojure questions! Who's up?

17:59 justin_smith: sdegutis: how do I pronounce ->>

17:59 sdegutis: justin_smith: pewpew!

18:00 postpunkjustin: thread last?

18:00 SagiCZ1: gfredericks: when you talked about that I have to import the class name only when I actually need it.. when I implement protocol in a record thats the case right?

18:00 sdegutis: damn it shia no, its pewpew

18:00 gfredericks: SagiCZ1: no

18:01 ,(defprotocol P)

18:01 clojurebot: P

18:01 gfredericks: I guess I can't demo it in the repl bot nevermind

18:01 SagiCZ1: i think i get it

18:01 P is not a class name

18:01 its the var with the protocol

18:01 gfredericks: the class is also called P

18:02 ,(type P)

18:02 clojurebot: clojure.lang.PersistentArrayMap

18:02 justin_smith: ,(type @#'P)

18:02 clojurebot: clojure.lang.PersistentArrayMap

18:02 gfredericks: ,*ns*

18:02 clojurebot: #object[clojure.lang.Namespace 0x2d75ca0a "sandbox"]

18:02 gfredericks: ,(type sandbox.P)

18:02 clojurebot: java.lang.Class

18:03 justin_smith: ,(import '(sandbox P))

18:03 clojurebot: #error {\n :cause "clojure.lang.Var cannot be cast to java.lang.Class"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Var cannot be cast to java.lang.Class"\n :at [clojure.lang.Namespace referenceClass "Namespace.java" 129]}]\n :trace\n [[clojure.lang.Namespace referenceClass "Namespace.java" 129]\n [clojure.lang.Namespace importClass "Namespace.java" 158]\n [clojure....

18:04 SagiCZ1: the protocol var contains a lot of stuff

18:05 gfredericks: yep

18:06 profil: I am feeling really stupid now, but how do I conjoin to vectors? from [1 2] [3 4] to [1 2 3 4]

18:06 justin_smith: ,(into [1 2] [3 4])

18:06 clojurebot: [1 2 3 4]

18:07 profil: justin_smith: will the order be preserved?

18:07 SagiCZ1: ,(into [] (concat [1 2] [3 4]))

18:07 justin_smith: yes

18:07 clojurebot: [1 2 3 4]

18:07 justin_smith: SagiCZ1: that concat is not needed

18:07 SagiCZ1: use mine if you want a worse and uglier version

18:07 justin_smith: haha

18:08 profil: into is not order-preserving for other types, but for vectors it appends in the intuitive way

18:08 amalloy: more specifically, into is just repeated conj. knowing that, you can deduce how it will behave for other types

18:09 SagiCZ1: can i access "this" in defrecord?

18:09 profil: great, thanks :)

18:09 justin_smith: SagiCZ1: it's the guaranteed first argument to every protocol method

18:09 cfleming: SagiCZ1: What's up?

18:10 SagiCZ1: justin_smith: so if the method in protocol has 1 argument the implementation should have two?

18:10 justin_smith: SagiCZ1: the method in protocol should specify the this arg, iirc

18:11 SagiCZ1: hmm

18:11 justin_smith: SagiCZ1: for example, defprotocol should complain if you don't specify at least one arg (which will always be this)

18:12 The resulting functions dispatch on the type of their first argument, and thus must have at least one argument

18:12 to quote http://clojure.org/protocols

18:13 SagiCZ1: yeah.. i see.. so it really is just a different api to multimethod system

18:13 justin_smith: SagiCZ1: not at all. A multimethod could dispatch by inc'ing the second arg

18:13 they are not constrained on dispatch or argument count

18:14 they are very similar to the common usage of defmulti, sure

18:14 SagiCZ1: cfleming: Hi I tried to msg you

18:14 gfredericks: ,(defmulti second-arg-inc'd-in-words (fn [a b] (inc b)))

18:14 clojurebot: #'sandbox/second-arg-inc'd-in-words

18:14 SagiCZ1: justin_smith: yeah i meant that..

18:14 gfredericks: ,(defmethod second-arg-inc'd-in-words 71 [_ _] :seventy-one)

18:14 clojurebot: #object[clojure.lang.MultiFn 0x1d75b8d5 "clojure.lang.MultiFn@1d75b8d5"]

18:14 gfredericks: ,(second-arg-inc'd-in-words "WORDS" (* 2 5 7))

18:14 clojurebot: :seventy-one

18:14 SagiCZ1: justin_smith: its how i was always using multimethods

18:15 justin_smith: SagiCZ1: yeah, it's how most people use them, just being clear that multimethods are actually much more flexible than that

18:15 gfredericks: that's an amazing multimethod

18:15 SagiCZ1: justin_smith: yep i know.. but since I dont need the flexibility I am going back to protocol and defrecords

18:15 justin_smith: SagiCZ1: that's what I would do too, yeah

18:16 gfredericks: justin_smith: #protip

18:18 justin_smith: gfredericks: now I am wondering if seventy-one, the lib, could use a multimethod that returns :seventy-one if the second arg is 71, and throws an exception otherwise

18:18 gfredericks: it could be called "validate"

18:18 justin_smith: indeed!

18:19 gfredericks: also would accept a pr for (defn seventy-one? [n] (= n seventy-one))

18:29 SagiCZ1: this happens to me when working with core.async>

18:29 NullPointerException [trace missing]

18:31 justin_smith: SagiCZ1: yes, core.async does weird things to the call stack

18:31 SagiCZ1: that seems like a serious disadvantage

18:32 justin_smith: SagiCZ1: asserts and try/catch can help

18:32 SagiCZ1: good idea

18:32 andyf: Is it core.async specifically, or is this perhaps maybe an instance of the JVM sometimes optimizing away the stack trace, which can be improved upon with a command line option when starting the JVM, e.g. http://stackoverflow.com/questions/2411487/nullpointerexception-in-java-with-no-stacktrace

18:32 justin_smith: but the very nature of core.async is to compile a state machine, so a normal stack is a lot to ask

18:32 SagiCZ1: will try that too andyf

18:33 justin_smith: andyf: even if a full stack trace were available, you can't expect more than async-thread-pool-dispatcher -> run-go-block -> maybe the name of the function that got the exception

19:08 Seylerius: There anything to do proofs of clojure code?

19:11 postpunkjustin: Seylerius: do you mean formal proofs like you'd find in Coq or Agda?

19:15 amalloy: you can't even prove it's clojure code! could be common lisp with a lot of sneaky reader macros

19:16 postpunkjustin: what if that's all it ever was

19:17 andyf: Seylerius: I attended a talk years ago where someone was demonstrating formal proofs of the behavior of Java byte code. I haven't heard of anything similar that is specifically for Clojure.

19:18 ambrosebs is working on core.typed, which is an optional type system for Clojure that can prove some type-system-like things about specially annotated Clojure code, but that is probably not what you are asking about.

19:18 sg2002: Hello again. Is there anyone using this: https://github.com/AvisoNovate/pretty directly and not under timbre? How do you set pretty exceptions up?

19:18 andyf: The system used to prove things about behavior of Java byte code was ACL2: http://www.cs.utexas.edu/users/moore/acl2/

19:19 I suspect using it to repeat their work, or extending it for nontrivial-sized Clojure programs, would be a significant chunk of work.

19:28 postpunkjustin: Yeah, I'm sure it would be easier to implement Clojure code extraction for Coq or something, since it already (kinda) works for Scheme

19:37 credulous: Any fans of Yesql? I'm having trouble with a toy example...

19:38 -- name: insert-user<!

19:38 INSERT INTO users (fname, lname, email, level, is_active, password_digest)

19:38 VALUES

19:38 (:fname :lname :email :level, 1, :password_digest)

19:38 is the sum total of users.sql

19:38 user> (defquery insert-user "distillednotes/models/users.sql" {:connection db-spec})

19:39 1. Caused by clojure.lang.ExceptionInfo

19:39 Parse error at line 2, column 4: -- name: insert-user<! ^ Expected

19:39 one of: NOT NAME_TAG "\t" " "

19:39 {:index 24,

19:39 :reason

19:39 [{:tag :negative-lookahead, :expecting {:NOT "NAME_TAG"}}

19:39 {:tag :string, :expecting "\t"}

19:39 {:tag :string, :expecting " "}],

19:39 :text "-- name: insert-user<!",

19:39 :column 4,

19:39 :line 2}

19:39 core.clj: 4403 clojure.core/ex-info

19:39 instaparse_util.clj: 18 yesql.instaparse-util/process-instaparse-result

19:39 queryfile_parser.clj: 42 yesql.queryfile-parser/parse-tagged-queries

19:39 core.clj: 28 yesql.core/defquery*

19:39 AFn.java: 160 clojure.lang.AFn/applyToHelper

19:39 AFn.java: 144 clojure.lang.AFn/applyTo

19:39 Urk that was ugly, sorry

19:54 andyf: credulous: Please use a paste web site and put links to them here.

19:56 amalloy: andyf: i think credulous knows that, given the apology after pasting

19:57 credulous: Won't happen again, sorry.

19:57 https://gist.github.com/rodfrey/456f92feb6ca33bb9826

20:08 sg2002: Hey guys, can someone tell me the current status of closeable sequences? While dealing with my data.xml stuff, I found this discussion: https://groups.google.com/forum/#!topic/clojure/2JDLF9E934o . So was it ever realized in any way?

20:14 andyf: sg2002: I am pretty sure the answer is no.

20:17 The last comment on this page says Rich considers it an open problem: http://dev.clojure.org/display/design/Resource+Scopes

20:18 I don't recall seeing this library before. I have no idea how useful it may be: https://github.com/pjstadig/scopes

20:19 Wrapping the body of a with-open with doall or dorun can sometimes eliminate the laziness that is causing problems.

20:22 gfredericks: andyf: sg2002: I really like hiredman's idea of using reducers instead of lazy seqs for that kind of stuff

20:22 amalloy: andyf: i think it's kinda a "closed problem", in that it seems like the wrong way to do things. all of the efforts at resource management have gone in some other direction

20:22 gfredericks: although technically I have never tried it

20:22 amalloy: eg reducers, as gfredericks has just said

20:22 gfredericks: somebody find that weird aws hiredman url

20:22 hiredman: ~reducers

20:22 clojurebot: reducers are http://clojure.com/blog/2012/05/08/reducers-a-library-and-model-for-collection-processing.html

20:23 hiredman: http://ce2144dc-f7c9-4f54-8fb6-7321a4c318db.s3.amazonaws.com/reducers.html

20:23 * gfredericks assumes hiredman has it memorized

20:23 hiredman: the uuid is actually a hex encoding of the last few digits of PI

20:24 gfredericks: PI is over everybody is switching to TAU

20:26 andyf: TAU isn't half of what PI used to be.

20:27 sg2002: andyf: Thanks for the info.

20:28 gfredericks: andyf: well put

20:28 fredfe: Has anyone ever tried putting data validation (like with bouncer) as ring middleware? Like with a redirect in case of a bad validation?

21:11 bbloom: chouser: yeah, moved to rrb vectors (they should be in core by now!)

21:11 but 2-3 ft was great for a while :-)

21:12 theoretical beauty has just got nothing on cache friendly hackery

21:14 credulous: My Yesql problem was solved by putting a newline at the top of the file, before the first "-- name:" tag. Is there an obvious reason that should be?

21:39 cryptack: hey, can someone explain when to use condp over cond? I'm not quite certain I follow the examples in clojuredocs.org

22:11 wei_: is Avout still the go-to for managing a distributed system, or is there a more up-to-date alternative?

23:04 justin_smith: cryptack: it makes sense to use condp if you are repeating the same two argument check function for each case

23:04 CuteStat: how much is your website worth? find out at http://www.criosphinx.net/site-worth for more information visit https://www.criosphinx.net - Sell your website for top dollar get a free apparaisal

23:04 justin_smith: amalloy: you around?

23:05 amalloy: sure, what's up?

23:05 cryptack: justin_smith: not certain I follow yet? can you give me a small example?

23:05 amalloy: oh. i guess i can ban that driveby

23:05 cryptack: justin_smith: cond seems to be able to allow you to apply any function check you want, in order, and I understand case, in that it allows a specific field eval

23:05 justin_smith: but condp, seems odd to me still...

23:06 amalloy: they've already logged off, and probably will never use that nick again, though

23:07 justin_smith: cryptack: condp is useful precisely because it is more limited

23:07 which means you know exactly how each clause is going to work

23:07 aids understanding

23:08 also, it allows you to use the result of the dispatch function in your clause

23:28 dumptruckman: hmm

23:28 i want to turn (map-players move entities) into something like (-> entities (map-players move))

23:28 so i can add more processes to the chain

23:29 but that doesn't work so i thought (-> entities (partial map-players move)) would do it but that also doesn't work -.

23:30 OH

23:30 oh.. i wanted ->>

23:41 alright, say i have an array of maps and in the maps i have an :x and :y

23:41 is there some handy way to check if there's a particular :x and :y value amongst the maps and to get the map it belongs to?

23:42 justin_smith: (first (filter #(= (:x %) v) maps))

23:42 that's probably the most straightforward method you'll find

23:42 clojurebot: I don't understand.

23:43 dumptruckman: but i need both the :x and :y at the same time

23:43 i was wondering if maybe i could restructing the map

23:43 justin_smith: oh, sure

23:43 dumptruckman: restructure*

23:44 justin_smith: make the predicat #(select-keys % [:x :y] {:x my-x :y my-y})

23:44 err, bad braces

23:44 #(= (select-keys % [:x :y]) {:x my-x :y my-y})

23:45 dumptruckman: like i have [{:foo bar :x 2 :y 3} {:foo baz :x 1 :y 3}] and turn into {[2 3] {:foo bar :x 2 :y 3} [1 3] {:foo baz :x 1 :y 3}]

23:45 something like that

23:45 justin_smith: dumptruckman: select-keys does that for you, but in a much more useful way

23:45 dumptruckman: hmm

23:46 justin_smith: another options is #(= ((juxt :x :y) %) [my-x my-y])

23:46 ,((juxt :x :y) {:x 0 :a :e :f "foo" :y 1})

23:46 clojurebot: [0 1]

23:46 justin_smith: which is closer to what you proposed above

23:47 dumptruckman: hrmm i don't think select-keys does what i want

23:47 justin_smith: but I think select-keys may convey your intent better than juxt

23:47 dumptruckman: cause i need to be able to know what map the x and y belong to

23:47 so i can compare that maps to another

23:47 amalloy: dumptruckman: what do you imagine happening if there are two different maps with the same x and y?

23:47 justin_smith: ,(select-keys [:x :y] {:x 0 :a :e :f "foo" :y 1})

23:47 clojurebot: {}

23:47 justin_smith: err

23:47 dumptruckman: amalloy: bad stuff probably

23:47 justin_smith: ,(select-keys {:x 0 :a :e :f "foo" :y 1} [:x :y])

23:47 clojurebot: {:x 0, :y 1}

23:48 amalloy: you're using [x y] as the key in your map, which can't support duplicates, when it seems perfectly plausible for a duplicate to exist

23:48 dumptruckman: i mean i could certainly traverse the map to do what i wnat

23:48 but i just figured there's a more clojurey way

23:48 amalloy: i mean it's not hard

23:48 justin_smith: oh, wait

23:48 that's close to being group-by

23:48 amalloy: justin_smith: it is group by

23:48 justin_smith: except group-by would give you a collection for each x/y pair

23:48 instead of one item

23:49 dumptruckman: i want to find all the maps that contain a particular x and y

23:49 justin_smith: either group-by or filter can do that, depends how many x/y pairs you want to look up - if more than one or two I would do it via group-by

23:49 dumptruckman: but i need to know if that map has a particular POJO inside it

23:49 if so i don't care about it

23:50 amalloy: dumptruckman: your requests are contradictory. the latest thing you've asked for is the opposite of the example input/output you gave. perhaps you should be clearer about what you need to do and/or why

23:50 dumptruckman: ok

23:50 i will try

23:52 i have a map contain a java object and a coordinate pair. i have a vector of a bunch of these same maps with non-equal java objects and mostly different coordinates. i need to find out which of those maps in the vector matches the first map, but i want to ignore the first map itself, which exists in the vector

23:52 my actual goal is collision detection

23:53 justin_smith: OK, I would use a filter that tests the x, y, and pojo

23:53 dumptruckman: the vector is all the objects on screen, i'm trying to find out if one of the objects is in the same coords as another, excluding itself since that will always be the case

23:53 amalloy: okay, so you are searching through a sequence for any number of objects which meet a specific criterion (which, here, is "has the same x/y, but not that other thing"

23:53 justin_smith: if you were looking up more than one x/y I would suggest group-by instead

23:54 dumptruckman: just one x and y

23:54 i'll look at filter

23:54 amalloy: yes, basically

23:54 amalloy: then you are doing exactly a filter

23:54 dumptruckman: or precisely

23:54 k

23:55 oh yeah, duh

23:55 thank you!

23:57 currentoor: so what do people usually use for oath?

23:57 anyone try this?

23:57 https://github.com/mattrepl/clj-oauth

Logging service provided by n01se.net