#clojure log - Nov 26 2013

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

0:00 seancorfield: dnolen: is there somewhere we can read about the defrel / pldb change and how it affects usage? if it does...

0:00 you mentioned it might be a breaking change so i was looking for code before / after examples... or is it too esoteric for casual users to care?

0:01 dnolen: seancorfield: https://github.com/clojure/core.logic/commit/1375f34ef42ee6b288ccb110b5c8c4aeb87a39a9

0:01 seancorfield: thx... reading...

0:01 dnolen: seancorfield: is the only thing currently available, I'll try to find some time to write up about it

0:02 seancorfield: but tldr; this is just way more idiomatic

0:02 seancorfield: no mutable madness

0:10 seancorfield: the tests sort of explain it... i guess i hadn't seen the madness that it was before :)

0:11 the fact databases, esp. the merging across them, looks very nice...

0:16 dnolen: seancorfield: yep, and this code has been used in production >1 year, more?

0:16 seancorfield: I'll definitely write up a transition - can more or less use the tests as a starting point

0:16 transition guide

0:21 seancorfield: i'm looking forward to hitting a problem at work for which core.logic is the perfect solution :)

0:21 one day, one day... :)

0:22 i have played with it in the repl several times... it really is very cool... i used to do a fair bit of prolog (back in the... late 80's I guess) but haven't hit a "real" problem for which i've needed that much firepower lately

0:33 andyf: Is there an easy way to make pprint show metadata, too?

0:34 doh! And of course (binding [*print-meta* true] (pprint ...)) does it, but somehow I didn't think it did despite trying it a few days ago.

0:53 devn: Does (with-pprint-dispatch code-dispatch (pprint ...)) include that binding?

1:03 seancorfield: doesn't look like it devn

1:03 ,(source clojure.pprint/with-pprint-dispatch)

1:03 clojurebot: Source not found\n

1:04 seancorfield: hmm, worth a try... but all it does is bind *print-pprint-dispatch*

1:11 myguidingstar: hi all, I want to test a function that generate code but got this https://gist.github.com/myguidingstar/7654141

1:12 how can I force the test to skip resolving namespaces?

1:14 FYI, I am writing a lein plugin that will read some symbols "and", "or" from project.clj

1:21 tufflax: myguidingstar: I have not used midje so im not sure how it works, but maybe you could use ` instead of ' in your fact? :P

1:22 myguidingstar: tufflax, it works!!!!!

1:22 thanks a lot ^^

1:23 tufflax: myguidingstar: np

1:30 myguidingstar: tufflax, but when evaluating the generated code, I got java.lang.RuntimeException: Can't use qualified name as parameter

1:31 tufflax: hm

1:31 myguidingstar: does that mean I have to use ' instead of ` for all the code?

1:31 tufflax: probably not

1:31 myguidingstar: (hmm, that looks weird)

1:32 tufflax: You mean when you eval what is after Expected: in your gist?

1:33 myguidingstar: yep, something like this (eval `(fn [my-ns/s] ...))

1:34 tufflax: show exactly what

1:34 myguidingstar: well, I just apply eval to the result

1:35 and because the symbol s is qualified with my current ns, so (fn [...]) doesn't work

1:37 tufflax: oh

1:37 now im starting to understand

1:37 you have to do `(fn ['~x] ...)

1:38 for function parameters

1:38 i think that's it

1:38 myguidingstar: ok, I'll try

1:42 tufflax: myguidingstar: did it work? :P

1:43 myguidingstar: tufflax, it works perfectly now

1:43 tufflax: nice

1:44 myguidingstar: but a little change in syntax

1:44 ,`(fn ['~x])

1:44 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: x in this context, compiling:(NO_SOURCE_PATH:0:0)>

1:44 myguidingstar: ,`(fn [~'x])

1:44 clojurebot: (clojure.core/fn [x])

1:44 tufflax: oh

1:44 yeah :p

1:46 seancorfield: ,`(fn [x#] (if (string x#) "yup" x#))

1:46 clojurebot: (clojure.core/fn [x__84__auto__] (if (sandbox/string x__84__auto__) "yup" x__84__auto__))

1:46 seancorfield: you can use gen-sym here i think?

1:48 tufflax: seancorfield: yes probably, but that would perhaps again break his test :P

1:48 seancorfield: wasn't sure whether he really wanted an anaphoric macro or not...

1:49 tufflax: this approach to tesing macros seems to be a bit broken :p

1:51 seancorfield: the gist has timed out / gone away so i can't check it

1:54 tufflax: he was basically comparing macro expansions, so differing symbol names would make the test fail

1:56 seancorfield: ah so he didn't really care about execution of the macro, just the expansion?

1:57 tufflax: I imagine he cares about execution too, but he was writing tests at the moment

2:01 myguidingstar: You probably want to do what seancorfield said and use s# instead of ~'s

2:05 myguidingstar: thanks seancorfield tufflax for your suggestions. It's a very small function, not a macro

2:08 seancorfield: a macro is just a function that manipulates clojure forms :)

2:09 SegFaultAX: That's evaluated at compile time.

2:09 emaphis: a compile time lambda.

2:13 brainproxy: not looking for upvotes per se, but recommendations from the clojure crowd would be welcomed: https://news.ycombinator.com/item?id=6799511

2:33 tufflax: brainproxy: this book got a stellar review http://www.amazon.com/review/R2CE1AUN4BVEXM

2:39 brainproxy: tufflax: :/

2:40 tufflax: I actually did not find the book that bad, but there are proabably better ones :p

2:40 brainproxy: this one is relatively new: http://www.digitalgrammars.com/ipl-book/

2:40 no reviews on amazon, though

2:42 tufflax: brainproxy: here is a free one http://www.diku.dk/~torbenm/Basics/

2:48 brainproxy: tufflax: nice! thanks

2:48 tufflax: brainproxy: how much background do you have?

2:48 do u know what automata are and how to write a context-free grammar etc?

2:49 dnolen: CLJS AST + core.logic is entertaining https://gist.github.com/swannodette/7654717

2:49 brainproxy: tufflax: nope

2:49 but I like to eat monads for breakfast and generally can learn as I go

2:49 dnolen: partial maps are pretty sweet for this ... need more sugar though

2:50 andyf: Minor victory: An update to the eastwood linting tool that uses the latest tools.analyzer contrib library by Bronsa to find redef'd vars in Clojure code.

2:51 tufflax: This book is ok for learning about automata, grammars, turing machines, grammars and so on. Does not talk a a great deal about parsers or generating code though http://www.amazon.com/Introduction-Automata-Languages-Computation-Edition/dp/0321455363

2:52 brainproxy: ^

2:55 brainproxy: tufflax: got it, thanks

2:55 looked up the Sipser book mentioned by a reviewer too

2:56 certainly have some options now :)

3:43 jcidaho: anyone got a good example of using core.async tap?

3:43 want to check the size of a chan

4:42 * ucb waves

4:55 d11wtq: Hi all. Newb question. I'm building a REST API in Compojure and want to keep my handlers in e.g. my-proj.handlers.users/show, my-proj.handlers.users/delete etc. Given I'll have resources of types other than 'users' in other namespaces, is there a form of (:use ... ) that will import my-proj.handlers, so I can simply refer to users/show and users/delete without the preceding namespace?

4:55 I'm happy to blindly import all namespace under my-proj.handlers.*, since they'll all be used in the defroutes.

5:04 tangrammer: Hi @d11wtq, maybe the behavior you are thinking about is similar to "loading functions/classes/libs into the namespace on the invoking of a function →"

5:05 @d11wtq take a look to this code https://github.com/nathanmarz/cascalog/blob/develop/cascalog-core/src/clj/cascalog/playground.clj#L7-L12

5:05 it's used to dynamically load require dependencies

5:05 piranha: dnolen: problem with externs is that you'll have to specify them every time you include react in some project

5:06 d11wtq: tangrammer: thanks! Exactly what I was getting at!

5:07 tangrammer: d11wtq: i discovered it very recently, i'm glad with my first contribution in this channel :)

5:17 llasram: tangrammer, d11wtq: Calling `require` outside of your `ns` form is pretty uncommon, and there isn't usually a great reason to do it...

5:18 d11wtq: Did you just need (:require ... :as ...) ?

5:19 tangrammer: Hi @llasram, i suppose that this code will conform to the clojure standard use https://github.com/nathanmarz/cascalog/blob/develop/cascalog-core/src/clj/cascalog/playground.clj#L7-L12

5:21 llasram: tangrammer: Not really. `use` is semi-deprecated, and like I said, calling `require` outside of `ns` is unusual. It makes sense there because it serves the non-standard purpose of letting you quickly slurp some vars into the `user` namespace for experimentation, but I wouldn't suggest using it as a pattern for production code

5:22 tangrammer: llasram: thanks a lot for your comemnts, I really appreciate them

5:24 llasram: Er, np :-)

5:50 justin_smith: tangrammer: just saw an answer of yours on SO - fyi

5:50 ,@(future + 1 2 3)

5:51 clojurebot: #<SecurityException java.lang.SecurityException: no threads please>

5:51 justin_smith: anyway, that returns 3

5:51 future takes a normal body as an argument

5:52 tangrammer: justin_smith: hi justin!, can you be a bit clear please?

5:52 justin_smith: tangrammer: @(future (+ 1 2 3)) actually works as expected

5:52 that would return 6 if clojurebot let me use futures

5:53 this is regarding your answer on http://stackoverflow.com/questions/20203013/how-to-write-concurrent-program-in-clojure-using-ref-agent-and-future

5:53 tangrammer: justin_smith: actually i've never used futures, let me see again

5:56 justin_smith: when i try to evaluate the code with the parenthesis then my nrepl-connection get closed,..

5:56 justin_smith: but if i remove the extra parentheses then the code print the results in the console

5:57 justin_smith: in a repl, run the two examples I pasted here

5:57 @(future + 1 2 3)

5:58 @(future (+ 1 2 3))

5:59 the first one is the equivalent of (do + 1 2 3) - no function application, just returning the last one specified

6:00 ddellacosta: somebody hope me! https://www.refheap.com/21254

6:00 tangrammer: justin_smith: you are right with your example!

6:01 ddellacosta: sorry, being silly. I want to figure out how to deref a form and pass a variable in--generated in the macro--so that I can use it in the form I pass in

6:01 there is something basic I'm confused about wrt macros here

6:01 justin_smith: tangrammer: there are clearly other things wrong with that guy's code, just saying using future that way is just avoiding a symptom, not fixing the code

6:01 tangrammer: justin_smith: let me check again,

6:02 justin_smith: ddellacosta: ~@body spits out body into the surrounding form

6:03 clgv: ddellacosta: just use ~body

6:03 justin_smith: either don't use @, or pass in (#(+ 3 %)) instead of #(+ 3 %)

6:03 ddellacosta: justin_smith, clgv: thanks!

6:03 tangrammer: justin_smith: (future transfer(balanceA balanceB 20 1 (rand-int 100))

6:03 justin_smith: depending on what you want other usages to look like

6:03 clgv: ddellacosta: splicing unquote (~@) enrolls a list/sequential

6:03 justin_smith: tangrammer: totally wrong

6:04 tangrammer: justin_smith: it need to be replaced with (future (transfer balanceA balanceB 20 1 (rand-int 100)) (prn "result" @balanceA @balanceB))

6:04 i got it

6:04 ddellacosta: clgv: right, now it makes sense.

6:04 tangrammer: and thanks a lot

6:04 justin_smith: (future (transfer balanceA balanceB 20 1 (rand-int 100)))

6:04 tangrammer: yeah, you got it

6:04 tangrammer: justin_smith: i'll change the code in SO, you are a crack! thanks!

6:04 justin_smith: np

6:05 noncom: anybody here users of CounterClockWise?

6:05 justin_smith: I am unfamiliar with that idiom

6:05 tangrammer: spanish slang?

6:05 clgv: noncom: yes, what's your question?

6:06 tangrammer: justin_smith: yes, sorry! it's like a great guru

6:06 justin_smith: well, shucks

6:07 noncom: clgv: i am specifying -Xmx1024M in VM parameters of the launch config, then I click "Run", the repl starts and I eval my things there and with time the app slows down and then the Heap Exception is thrown. The task manager says that the java process still takes no more than about 330 Mb...

6:07 how do I set more memory for the VM correctly?

6:08 btw, there is 1Gb free ram for sure, so it should be available to the jvm

6:09 clgv: noncom: the memory config for the REPL needs to be set in the run configuration

6:09 justin_smith: so counterclockwise uses a separate vm for the repl?

6:09 clgv: noncom: oh right you said you did

6:09 justin_smith: yes

6:10 noncom: i should also say that i am using 0.13 beta version (which is dated, but it has the necessary leiningen interaction)

6:10 justin_smith: if it is using leinengen, maybe the vm args should be in the project.clj?

6:10 just a wild guess

6:10 ucb: justin_smith: being a crack is usually used in the context of sports in Spanish - most notably football; it means being a star. :)

6:11 noncom: justin_smith: oh, maybe! the point is that CCW above 0.13beta do not use lein and setting configuration properties works for them.. so I gonna check it with the projcet.clj

6:11 tangrammer: ucb: but it's also used in programming contexts

6:11 justin_smith: ucb: gotcha. In american english, crack as a noun is likely to mean "some crack" as in the drug, or "a crack" as in what people have on their ass

6:12 ucb: justin_smith: heh

6:12 tangrammer: indeed; I was just referring to the potential origin of the expression plus it's most common use? (I've not seen it quite in the programming context)

6:13 clgv: noncom: afaik CCW does not use the full project.clj there are a lot of features missing

6:13 justin_smith: clgv: well if he is intentionally using a version that farms out to lein...

6:14 noncom: clgv: but 0.13beta is special - it delegates all launch to leiningen, so that should be the spot!

6:14 clgv: justin_smith: he probably means support to run leiningen tasks. that feature is not implementing full project.clj compliance

6:14 noncom: is it gone on the current beta channel? I'd doubt that

6:15 noncom: there is a channel for each branch afaik

6:15 justin_smith: another option is env _JAVA_OPTIONS=-DXmx1g <command>

6:15 noncom: clgv: you mean that newer ccw beta versions still delegate to leiningen?

6:15 justin_smith: that should get passed to each jvm within the process tree under that point

6:16 noncom: he is claiming that no delegating to leiningen ever happens

6:16 clgv: noncom: I specify 10GB for my repl which worked in stable 0.12.x and works now in stable 0.20.0

6:17 noncom: i see.. well i can only say that i talked to lpetit and we had that long talk of fighting a bug that was happening with me. finally we came to the decision that it is about the launch config. and he said that 0.13beta was special in that regard. and i have to use it. it is there lying specially in the "legacy" folder on the update link

6:17 clgv: justin_smith: I now that Laurent was working on creating direct launchers for arbitrary leiningen tasks. but if they are experimental on a beta branch I doubt that he replaced the working REPL bootstrap with that

6:18 noncom: for that single reason

6:18 so 0.13beta really wokred

6:18 where others did not

6:18 clgv: noncom: what exactlly do you do? are you running custom tasks from integrated launchers?

6:19 noncom: clgv: well, i am not sure what is a lein custom task, but i think no. i just refer some jars in the :resource-paths which a program launched from CCW only finds if CCW is 0.13beta

6:22 so, i tried setting Xmx in project clj and seems like it works... so really, it simply asks lein to launch the app

6:23 justin_smith: well, glad my ignorant guess may have helped

6:30 clgv: noncom: weird. then this was reverted for stable 0.20.0

6:31 noncom: so you need classpath entries via the specification in project.clj. for folders this works with current ccw but maybe there is an issue with the jars - I dont know

6:31 noncom: clgv: you mean it is absent in 0.20? if so then yes, Laurent said that it was experimental and the last version that had it was 0.13beta. Then he removed the feature. He said he planned to work on it more later, after 0.2x so that he can get the main CCW features ok and then work in these things

6:32 clgv: I tried it with some of the latest versions of CCW, like 0.19 or 0.20 idk, and as far as i remember it did not work, but I gonna try again with the latest - maybe it'll work.. wanna work with the latest version and not 0.13 :)

6:40 clgv: noncom: so the problem was that you wanted the contents of a jar in a directory specified as resource path accessible, right?

7:18 noncom: clgv: yes, i wanted the program to be able to see and use the JMonkeyEngine3 from the path (i know that there is the repeatability approach and JME repos mainained by some ppl)

7:34 silasdavis: Can anyone tell me how to get line numbers displayed in timbre log messages?

7:34 I've found this, but it's not entirely clear to me how it's meant to work: https://github.com/ptaoussanis/timbre/issues/22

7:35 I have the vague idea that appenders are particularly logging endpoints, but it seems that that is missing something

8:23 mdrogalis: The ClojureBridge mailing list is pretty incredible. Clojure reaches literally everywhere.

8:25 clgv: noncom: so you do this to have a normal dependency?

8:26 noncom: you should just upload the jmonkey release you need to clojars and use leiningen normally. the uploading is easier than you might think

8:33 noncom: clgv: yeah, i tried.. i even have some own projects uploaded to clojars.. but clojars do not accept more than 20mb files, and i may need nighties every day and even make custom changes to the engine code and other stuff.. also from time to time i have to link other libs.. i agree that clojars is good and stuff but for now, working 100% only with it makes more pains than i really need..

8:34 actually many people here already have jme repositories that anyone can use

8:34 but nevertheless yet it is harder to use than the copy/paste thing. maybe sometime the unified repo technology will progress enough..

8:36 schmir: I need to base64 encode a byte array. do I need the data.codec for that or is there a builtin function?

8:37 noncom: schmir: idk but i doubt it is a build-in one

8:38 schmir: noncom: ok. will go with data.codec then...

8:50 clgv: noncom: hm ok. I am runnning a private apache archiva myself, so a file size limit is no issue...

8:52 noncom: clgv: agree, but installing that server thing on all machines that i might be working on and then commiting all the things to it.. it is cool, but it just does not beat the copy/paste technique (for my case). so i just have all stuff in my project and then beam it up and down from the mercurial repo on bitbucket and it works really fine!

8:54 i guess that technically it happens to be that i just use mercurial instead of the central repo

8:55 and it is a copy/paste filesystem-based thing when with the maven i have to setup a bunch of stuff and then deal with all these manifests pom and others

8:57 clgv: noncom: no, the point is to install it only on one server ;)

9:03 noncom: clgv: ahaha :) got you :) but in country where i live, you are never sure aout network or internet.. :(

9:04 clgv: noncom: well just use ssh and https with the security level you think you need ;)

9:04 noncom: but i am thinking about migrating to that approach anyway. coz all people say it is great

9:05 clgv: nono, not security is issue, but the presense of internet itself.. when in big cities it it no problem, it can be a real pain if you go somewhere..

9:05 but you're right, i have to adopt correct techiques for the jobs

9:08 clgv: oh ok

9:08 where are you from?

9:09 noncom: russia :)

9:09 clgv: in the european or asian part?

9:10 noncom: european, namely, saint-petersburg. spb and moscow are ok, but if you go like 50km away... you never know what you get... and there we often have some clients with bit projects..

9:10 s/bit/big

9:12 clgv: noncom: oh ok. clients in the "desert" so to say ;)

9:13 noncom: yeah :D they have museums there and all kinds of memorials and stuff. they often want some graphical installations or integrated systems... cool the development is coming but i hope it comes sooner :)

9:30 nen yf fylhjtlf[ cblbn&

9:30 sorry

9:46 TimMc: Sounds like Russian. :-P

10:06 jcromartie: running "lein ring server &" yields a non-functioning webserver

10:06 is there any way to run a ring server as a background job?

10:06 mdrogalis: lein ring server-headless I think?

10:16 ath01: (run-jetty #'app {:join? false}) if you're going that route

10:29 myguidingstar: hi all, I'm writing a lein plugin and want to test some functions. How can I access the project map inside tests?

10:31 for example, given my project (defproject name "0.1.0" :some-key "some-value"), how can I get "some-value" with tests?

10:38 noncom: myguidingstar: your plugins entry point function takes the project map?

10:38 i mean sure it does, so it is the way

10:38 don't hesitate to study the leiningens writing plugins guide

10:39 there is much useful info there

10:44 dnolen: given this https://gist.github.com/swannodette/7654717, we can easily do what Facebook does https://github.com/facebook/pfff/blob/master/h_program-lang/database_code.pl

10:45 nDuff: dnolen: Heh. That's... pretty closely related to what I'm working on (albeit coming from bytecode rather than source).

10:45 myguidingstar: noncom, thanks but I'm trying to access the value from tests, not the plugin function

10:52 nDuff: dnolen: related: have you seen damp.ekeko? It uses core.logic for queries against Eclipse's idea of the Java AST.

10:53 dnolen: nDuff: yep pretty familiar with it

10:53 llasram: myguidingstar: The project map is just a map. You generally do one of two things: (a) just make a map with the keys you want to test, and call your plugin function(s) on that map

10:53 dnolen: nDuff: I've fixed a few bugs for them. Would like to enhance core.logic to make their lives easier but that's further off.

10:54 llasram: myguidingstar: (b) Setup a full stub project and shell out to `lein` in the test

10:56 myguidingstar: llasram, what do you mean "shell out to lein"?

10:57 llasram: Actually run an instance of `lein` in a subprocess of the JVM running your tests

10:58 BobSchack: ping devn

11:00 myguidingstar: hmm, I want some unit tests, so how can I access the project map inside normal code? I want to run `lein test`, not `lein my-plugin` to test those util functions

11:00 llasram: You literally do not

11:00 You can synthesize a project map and call your functions with it

11:00 Or you can shell out to a lein subprocess

11:00 Those are your two options

11:02 myguidingstar: ok, thanks

11:09 jonasen: dnolen: cool stuff with core.logic / cljs ast. Reminds me of my datomic/cljs project: https://github.com/jonase/scape/blob/master/src/scape/core.clj#L256

11:13 dnolen: one recursive step and you have a implemented a (GClosure-free) tree-shaker for cljs :)

11:13 bbloom: nice.

11:20 tbaldridge: jonasen: how fast/slow was your code?

11:20 jonasen: if you ran it against something like core.cljs did queries take a few ms, or a few sec?

11:21 jonasen: tbaldridge: pretty fast if I remember correctly. Especially when the datalog optimizer was removed :)

11:21 ms

11:21 tbaldridge: nice, I worked on some hobby code like this once, but never ran it against a large codebase

11:24 jonasen: It's 1.5 years since I touched it so I might remember incorrectly. I should update to latest cljs analyzer (and Bronsas clojure analyzer) someday.

11:24 devn: BobSchack: talk to me

11:24 jonasen: I had lots of fun working on it...

11:25 BobSchack: devn you free today at noon?

11:25 devn: BobSchack: what time zone, and for what? :)

11:25 tbaldridge: jonasen: yeah, I'd love to see something like Scheme's nanopass compiler, but using core.logic

11:25 devn: oooohh!

11:25 that'd be really cool

11:25 BobSchack: devn it's Peter at the Tenney building

11:25 :)

11:25 devn: BobSchack: oh, confusing name!

11:26 BobSchack: unfortunately i dont think im going to have time this week :\

11:26 can it be an email? i have a lunch meeting today and im working out of my normal timezone

11:26 outside of*

11:26 BobSchack: I'm seeing if I can make a fressian port in js and wanted to talk to you about it

11:27 sure

11:27 devn: BobSchack: gah, i want to talk about that

11:27 tbaldridge: BobSchack: I started on that once, got a bit hung up on how to handle string encoding.

11:27 devn: but yeah, send me an email

11:27 tbaldridge: have you seen BobSchack's core.async port?

11:27 tbaldridge: BobSchack: but I would seriously use that if you made it, esp if you wrote it in CLJS :-P

11:28 devn: maybe? do you have a link?

11:28 devn: BobSchack: link this man!

11:28 BobSchack: tbaldridge I was looking into making it in JS first like fressian is written in Java for maximum portability

11:29 devn: BobSchack: i cant find the repo URL

11:29 BobSchack: unfortunately JS doesn't have good maps or sets until you get to EMCAScript 6 :(

11:29 devn: what's your github username again?

11:29 BobSchack: https://github.com/Schuck-Johnson/csp-channel

11:29 Schuck-Johnson

11:29 devn: gotcha

11:30 tbaldridge: BobSchack: nice work!

11:31 devn: tbaldridge: yeah, he showed this to me and i went "whoa" like keanu. really nice work. more people need to know about it!

11:31 BobSchack: tbaldridge thanks once you know how to do JS well porting cljs code isn't that hard, testing it to make sure it work otoh :(

11:32 tbaldridge: BobSchack: nice! it supports closure. That'd be nice to have for your fressian port.

11:32 BobSchack: I was meaning to ask you about the writer caching.

11:34 bbloom: i really enjoyed stu's fressian talk. i've needed something like fressian in the past. protobufs got the job done & probably worked out a little nicer for the java-folks that had to maintain it... but i had to suffer with an extra code generator cluster fuck :-P

11:34 BobSchack: It uses hashing which is kind of not there in JS so I was wondering why it uses a new datastructure instead of using a map of object to cache id

11:35 bbloom: BobSchack: can you link to the relevant code?

11:35 BobSchack: https://github.com/Datomic/fressian/blob/master/src/org/fressian/impl/InterleavedIndexHopMap.java

11:36 clgv: bbloom: what are the killer features of "fressian"?

11:36 BobSchack: binary edn I believe

11:36 bbloom: clgv: https://github.com/Datomic/fressian/wiki/Rationale

11:37 clgv: do you understand the rational for BSON in places where people need faster/smaller JSON?

11:37 dnolen: jonasen: yeah I was just thinking that this morning, dead code elimination would be relatively simple with this - not sure about perf though? but perhaps tabling would mitigate that? would need to fix core.logic tabling though.

11:38 bbloom: clgv: it's that, but with all the stuff you've come to expect from EDN over JSON (sets, tagged values, etc) plus some extras

11:38 clgv: bbloom: ah ok.

11:39 tbaldridge: clgv: and it's also the format Datomic uses to store its data.

11:39 dnolen: jonasen: yes I remember, so did you walk the AST putting certain kinds of facts into the DB?

11:39 clgv: tbaldridge: yeah I read that few months ago..

11:40 bbloom: tbaldridge: there was some discussion in here last night about PDF/postscript/turing complete. I'm totally going to make Fressian 2.0 -- A Forth Dialect :-P

11:40 clgv: ah compression via caching is builtin as well

11:40 * bbloom is mostly kidding

11:40 bbloom: mostly.

11:40 jonasen: dnolen: yes: https://github.com/jonase/scape/blob/master/src/scape/emitter.clj

11:41 bbloom: BobSchack: so i think this is about cache locality

11:41 but i'm not sure

11:41 http://en.wikipedia.org/wiki/Interleaved_memory

11:41 devn: are the data.fressian slides online from stu's talk?

11:41 dnolen: jonasen: oh huh, you're emitting more than I thought, and find all callers and all callees was fast over all of core.cljs?

11:42 jonasen: dnolen: If I remember correctly, yes.

11:42 dnolen: indexing FTW

11:43 bbloom: dnolen: i see no reason why we can't *destroy* the perf and quality of transformations that gclosure performs

11:43 dnolen: javascript is just much much harder to analyze, even w/ google's type system

11:43 dnolen: jonasen: will have to play around with that intuitively all those joins would seem prohibitive w/ set oriented semantics

11:44 jonasen: I don't see any real all callees or callers query in your project.

11:46 jonasen: https://github.com/jonase/scape/blob/master/src/scape/core.clj#L221

11:46 upwardindex: How do I call the javascript + from clojurescript (I did js/+ but that yields _PLUS_ and that is undefined)?

11:47 jonasen: dnolen: my weekend project should be to update to latest cljs analyzer so we could play with it some more

11:47 dnolen: jonasen: ah cool, didn't see those there

11:47 jonasen: how long does it take to dump core.cljs into the DB?

11:48 jonasen: dnolen: sorry I don't remember. A few seconds perhaps?

11:48 seangrove: bbloom: Presumably you'd do the dead-code elimination and transforms in cljs-land, then generate the reduced javascript, then pass that off to gclosure for concatenation/minification?

11:48 upwardindex: Interesting, what are you trying to do?

11:49 bbloom: seangrove: initially, yes. but over time, it would be much more efficient to do the work on our end.

11:49 upwardindex: seangrove: remove warnings regarding adding dates or similar stuff

11:49 bbloom: seangrove: otherwise we still need to pay the extra round-trip to text-on-disk just for concat/minify

11:50 seangrove: and we can already generate unique names on our end, so it's only a manner of tweaking the name generation to use single letter names and capitalize on knowledge of javascript scope

11:50 seangrove: bbloom: Certainly could be very interesting

11:50 dnolen: jonasen: that's pretty awesome - I never looked at it closely - I see you're only putting in the relevant parts of the ast into the DB

11:51 devn: stupid white paper pay walls

11:52 dnolen: jonasen: it'd be cool if this was online like your other projects ;)

11:53 seangrove: jonasen: scape looks pretty interesting!

11:54 jonasen: seangrove: kind of similar to codeq (minus the git import + more advanced code analysis)

11:54 seangrove: jonasen: That's what I was thinking. Still not sure what codeq is good for other than as a toy, but I feel like there must be something very useful

11:55 devn: seangrove: i think the model needs to be extended

11:55 dnolen: seangrove: scape is more interesting, but does having all that git history scape less usable?

11:55 "make scape less usable?"

11:56 jonasen: dnolen: I remember trying to combine the two projects, but failed.

11:57 devn: i would like to see codeq with additional analysis tools added into the mix, like ambrosebs' jvm.tools.analyzer

11:59 jonasen: combining it with codeq you mean?

11:59 jonasen: devn: yes

11:59 devn: codeq is a pretty big model to get your head around

12:00 which is why adding jvm.tools.analyzer to it would be a bear

12:03 dnolen: Bronsa: so for your passes do you have pre/post?

12:04 tbaldridge: devn: the new analyzer is actually pretty clean. It'd be a bear to write the insert queries

12:04 Bronsa: dnolen: yes but simply pre/post is not sufficient for some passes for the jvm

12:04 I also have a right to left walk

12:04 dnolen: Bronsa: what's that for?

12:05 Bronsa: it's needed by the clear-locals pass, it needs to walk the children nodes in backward order

12:06 dnolen: Bronsa: ah got, so do you just maintain two vectors of passes or something?

12:06 (disregarding the right left thing)

12:06 Bronsa: dnolen sorry, give me 5 minutes, I'm walking home :)

12:07 dnolen: Bronsa: heh, k

12:11 dabd: Stupid question why is the following not working: ,(z/edit (z/vector-zip [1 [2 3]]) (fn [n & args] (if (odd? n) (* 2 n) n)))

12:12 jonasen: devn: understanding codeq wasn't the problem. Any "real" analyzer will have to do macro expansion. Codeq hands you only a file so you can't just run the analyzer on it since it can't find the macros.

12:14 Bronsa: dnolen: so, for the jvm passes it's not so easy as having a vector of passes and (reduce apply-pass ast passes)

12:14 there are passes that need to be run multiple times/passes that require to be re-run once the result of a previous pass gets invalidated

12:15 so ATM I'm composing the passes manually it's pretty complex actually https://github.com/clojure/tools.analyzer.jvm/blob/master/src/main/clojure/clojure/tools/analyzer/jvm.clj#L327-L359

12:16 dnolen: Bronsa: ah got it, make sense. Was curious how to improve the *passes* feature in CLJS

12:17 Bronsa: dnolen: I've been thinking for a while on how to make this as simple as pushing the pass in a queue and letting the analyzer compose them automatically, but I still have to find a satisfying solution

12:18 TimMc: dabd: What do you expect it to do, and what does it actually do?

12:18 dnolen: Bronsa: k, thanks for the info. I'll probably leave *passes* alone for now then.

12:18 dabd: returns an error: IllegalArgumentException Argument must be an integer: [1 [2 3]] clojure.core/even? (core.clj:1338)

12:18 i would like to multiple the odd numbers in the tree by 2

12:19 *multiply

12:19 TimMc: dabd: Oh, this is the same problem you were having yesterday. Does z/edit edit the current node, or map over all nodes?

12:19 Bronsa: dnolen: yeah, I poked at it and for CLJS it looked fine as it is for now

12:19 alandipert: Bronsa, dnolen: are you guys into the idea of relations for passes? seems like the situation is amenable to core.logic

12:19 dabd: it's the clojur.zip/edit function so it edits the current location according to the docs

12:19 TimMc: dabd: Well, the current location is a vector. :-)

12:20 technomancy: cemerick: have you done any brainstorming on nrepl content types?

12:20 dnolen: alandipert: yes thinking about that now - would be cool - might be too slow of course (w/o some long outstanding core.logic optimization work)

12:20 dabd: but function that is passed to edit applies node to the location so it shouldn't be a vector

12:21 TimMc: The location *is* a vector. What else could it be?

12:21 Bronsa: alandipert: using core.logic over the AST seems like a really cool idea (like how dnolen has shown in his gists today) but I don't think it will be fast enough

12:21 dabd: do you know how to change my code so it works?

12:22 alandipert: but dnolen has put every of the perf into core.logic!

12:22 also there are lots of opportunities to memoize and cut when you're unifying, the way the people with the fast type checkers do

12:23 TimMc: Nope, not to familiar with what zipper data structures are available.

12:23 *not too

12:23 but you'll need to find something capable of storing values at the nodes

12:23 * alandipert is in love with the idea of a compiler that solves for $target and tells me the relations preventing it from doing so

12:23 dnolen: Bronsa: in the future it could be fast enough - the big optimization I haven't had time to implement - skipping unification when ground and just invoking CLJ/CLJS fns

12:23 Bronsa: something serious Prologs do

12:24 coventry: dabd: Have a look at the examples in http://clojure.org/other_libraries#Other%20included%20Libraries-Zippers%20-%20Functional%20Tree%20Editing%20(clojure.zip)

12:25 dabd: z/edit basically does the z/replace and the z/node part of those for you.

12:26 dabd: any expert here could illustrate how to change my example so it works with clojure.zip/edit? ty

12:27 bitemyapp: "do my homework plz kthxbai"

12:28 coventry: dabd: As far as I know, the zipper library doesn't provide any function which walks/edits the structure for you. You have to walk it yourself as demonstrated in those examples.

12:28 cemerick: technomancy: not since the conj. Steeped in all sorts of non-tooling yaks of late. FWIW, here's what I did just prior to nREPL going to contrib https://github.com/cemerick/tools.nrepl/commit/a6851d9cbfa35374c9bad2f8abc738d988b4b55e

12:28 IIRC, that predates the use of bencode, so the base64 encoding business is unnecessary

12:29 Bronsa: dnolen: honestly I haven't done anything serious with core.logic other than playing around a bit, I need better core.logic-fu before considering using it if you say performances might not be a problem

12:29 technomancy: cemerick: cool; thanks

12:29 cemerick: technomancy: also, wasn't suggesting regular MIME types there yet, though that's obviously better than dumb png/txt/etc tokens

12:30 technomancy: cemerick: was just about to ask =)

12:30 TimMc: coventry: That's kind of surprising. There's no prewalk-map or whatever?

12:30 dnolen: Bronsa: we have supercomputers and very little Clojure code

12:30 it might have been a problem in the the 1980s

12:31 Bronsa: dnolen: then I have no excuses :)

12:31 technomancy: cemerick: are you still keen on rendered-* responses?

12:31 xeqi: Bronsa: to use tools.reader with source logging, I should be able to replace `readers/indexing-push-back-reader` with `reader/source-logging-push-back-reader` correct?

12:31 dnolen: Bronsa: which isn't to say traditional approaches won't be an order or two magnitude faster even if I optimize core.logic

12:32 Bronsa: xeqi: yes

12:32 dnolen: still I think there's a lot of FUN to be had here

12:32 coventry: TimMc: As far as I know, in clojure.zip itself. There may be a tool in a different library for that.

12:32 xeqi: blah, time for some fun debugging. https://www.refheap.com/21263

12:32 coventry: TimMc: At any rate, z/edit only edits the current node, it doesn't walk the tree as dabd is hoping.

12:33 Bronsa: xeqi: https://github.com/clojure/clojurescript/commit/36d401797f85c99794eef8a71239641930c36871

12:33 cemerick: technomancy: probably not. If a client sends :accepts ["application/png" "text/plain"], then a response that contains a map of mime types to the slots that actually contain the associated data makes more sense.

12:33 bitemyapp: technomancy: http://motherfuckingwebsite.com

12:34 cemerick: rendered-* only "worked" because dumb tokens were being used

12:34 technomancy: bitemyapp: I hate how that site doesn't wrap

12:34 Bronsa: xeqi: that's a bootstrapping issue with cljs, in order to make that work you have to dissoc :source in analyze-wrap-meta

12:34 bitemyapp: technomancy: beg pardon? it wraps for me.

12:34 cemerick: technomancy: also, there's the (undocumented) escape hatch for binary data: https://github.com/clojure/tools.nrepl/blob/master/src/main/clojure/clojure/tools/nrepl/transport.clj#L96

12:34 technomancy: bitemyapp: it's a proven fact that paragraphs beyond a certain width are more difficult for eyeballs to track

12:34 cemerick: ...which I'm not super-fond of, but I never came up with a better solution...

12:34 bitemyapp: technomancy: yeah, I agree...the page wraps for me.

12:35 technomancy: are you sure there isn

12:35 isn't something peculiar to your uncommon browser choice here?

12:35 technomancy: bitemyapp: I mean it wraps to the browser's width, which is too wide

12:35 bitemyapp: ohhhhh

12:35 technomancy: it would be more readable if it defined a maximum width for paragraphs

12:35 bitemyapp: technomancy: I like mostly unstyled text with a max width.

12:35 clojurebot: Excuse me?

12:37 xeqi: Bronsa: awesome, you just saved me a couple hours of source diving

12:37 technomancy: bitemyapp: http://baymard.com/blog/line-length-readability

12:37 guns: Also, 72 col hard-wrapped mail please.

12:37 technomancy: science!

12:41 llasram: Which is also why max 80 columns of code is the best! :-D

12:45 seangrove: technomancy: You have an unusual browser choice? Are you using the rms system?

12:46 dabd: one way to solve my problem is this: https://gist.github.com/dabd/7662792

12:47 technomancy: seangrove: not quite: http://conkeror.org

12:47 dabd: the branches are vectors so i need a test like number? while navigating the tree

12:47 maybe there is a simpler way»

12:48 * seangrove boggles at conkeror

12:48 technomancy: seangrove: I think they took this down when they got a new maintainer, but it used to say "In order to ensure Conkeror remains pure, I do not own a mouse."

12:48 it's the best

12:49 guns: that's dedication

12:49 technomancy: lmao if your browser doesn't have dotfiles

12:49 coventry: dabd: You might take a look at clojure.walk. It is less powerful than zip, but adequate to that problem.

12:49 guns: :) vimperator makes firefox usable

12:50 bitemyapp: xmonad makes life tolerable.

12:50 guns: I could never get into tiling WMs. I already do tiling in Vim and in tmux

12:50 another layer of tiling is madness

12:51 coventry: Sawfish. Scheme as configuration language FTW!

12:51 seangrove: Ah, would love xmonad on osx

12:51 guns: I do my openbox config in Clojure

12:51 technomancy: coventry: iirc sawfish has some crazy bespoke lisp

12:51 if it used scheme I'd probably still be using it =)

12:52 bitemyapp: the language is called "rep"

12:53 Bronsa: I'm coding in clojure, in an editor written in emacs lisp, in a wm written in common lisp

12:53 coventry: Oh, you're right, lisp.

12:53 Bronsa: lisp all the way down™

12:53 technomancy: Bronsa: on a space cadet keyboard hopefully

12:54 Bronsa: if only

12:54 technomancy: I actually have a keyboard with an embedded JVM

12:54 guns: you kid

12:54 technomancy: no, for real

12:54 hang on

12:54 guns: smartcard reader?

12:55 technomancy: https://en.wikipedia.org/wiki/FingerWorks one of these

12:56 I can't find a citation for it having an onboard JVM, but basically you program it with preset gesture recognition loaded onto the firmware

12:56 guns: The image search looks like I searched for 70's scifi interfaces

12:57 coventry: Ah, it has a scheme flavor http://librep.sourceforge.net/

12:57 guns: you must collect keyboards

12:57 seangrove: Bronsa: What wm?

12:58 Bronsa: seangrove: http://www.nongnu.org/stumpwm/

12:58 seangrove: technomancy: It must have quite an old version of an embedded jvm

12:58 Bronsa: Ah yes, that's the one. Nice.

12:58 technomancy: seangrove: 1.4 I think

12:59 guns: sort of. this one is actually pretty miserable to type on though

12:59 guns: put it on the wall

12:59 technomancy: it's like typing on a touchscreen; ~80% accuracy

12:59 hehe

13:00 guns: got one of these in the mail on its way: https://www.massdrop.com/ext/ergodox/assembly

13:00 yet somehow I don't have a Model M yet

13:01 guns: lol; I think you are playing down your hobby

13:01 but, I am jealous. I have read all the mechanical keyboard threads on the internet

13:02 seangrove: technomancy: But have you written an OTP erlang program to automate the ordering and disposable of various keyboards yet?

13:03 technomancy: seangrove: I was waiting till after I'd finished my arduino forth interpreter

13:03 seangrove: "When the temperature drops below 10C, buy a Model M and a MS Ergonomic 4000"

13:07 Fender: hey, how can I implement e.g. clojure.lang.Counted like in:

13:07 (defrecord Replayer [size current-time queue]

13:07 Counted

13:07 (count [this] size))

13:07 without getting a "Duplicate method name&signature in class file" exception?

13:08 actually, it is a java.lang.ClassFormatError

13:08 hiredman: Fender: records implment Counted already by default

13:08 Fender: and how could I override it?

13:08 hiredman: so if you want a custom Counted you have to use deftype

13:08 Fender: or shouldn't I be using records in the first place then?

13:09 actually I want an "object" so maybe defrecord isnt the way to go?!

13:09 sry, I said the word ;)

13:09 llasram: ~guards

13:09 clojurebot: SEIZE HIM!

13:10 technomancy: objects aren't a goal in and of themselves. what is it you actually want?

13:10 dnolen: Fender: you can't override, if you want your own definition you need to everything from scratch.

13:10 s/to/to do

13:11 Fender: ok, no worries, it is the first o***** I want to write after 18 months of clojure, so I hope I am forgiven ;)

13:12 I need a wrapper for a PersistentQueue that adds some functionality

13:12 so I though about defining a container that, well, contains the queue plus the other stuff

13:13 seangrove: We need more blue ovals!

13:13 objects?

13:14 clojurebot: objects is just adds a blue oval.

13:14 clojurebot: You don't have to tell me twice.

13:14 seangrove: objects?

13:14 clojurebot: objects is just adds a blue oval.

13:14 seangrove: Hrm, not quite right.

13:14 jtoy: how would I write this simple imperitave python in clojure, I couldnt find something that works http://pastie.org/8510498

13:18 i dont think i can use map or reduce for that since I need to stop at the first match

13:18 technomancy: (doc reduced)

13:18 clojurebot: "([x]); Wraps x in a way such that a reduce will terminate with the value x"

13:19 technomancy: jtoy: ^^

13:19 bitemyapp: technomancy: perceptive and brief.

13:19 coventry: jtoy: https://github.com/bigmlcom/sampling#weighted-simple-sampling

13:19 technomancy: bitemyapp: I'm good with bots. they trust me instinctively.

13:19 mpenet: jtoy: you can exit reduce using reduced

13:20 ,(doc reduced)

13:20 clojurebot: "([x]); Wraps x in a way such that a reduce will terminate with the value x"

13:20 mpenet: alternatively you can use loop/recur

13:20 bitemyapp: mpenet: do you read?

13:20 jtoy: I never heard of reduced, should I now use this for reference: http://clojure.org/cheatsheet

13:21 TEttinger: jtoy, clojuredocs is stuck on 1.3 for now. I think there may be efforts for new clojure references too

13:21 llasram: jtoy: Without `reduced`: (fn [probs] (let [z (rand)] (or (->> probs (reductions + 0.0) (map-indexed vector) (filter (fn [[_ x]] (> x z))) ffirst) (-> probs count dec))))

13:21 coventry: Hmm, that library uses reductions https://github.com/bigmlcom/sampling/blob/master/src/bigml/sampling/simple.clj#L72

13:22 TEttinger: I think clojuredocs is great for core parts of clojure.core, but stuff that's newer, even like mapv and reduced, would primarily be documented on that cheatsheet

13:22 jtoy: hm, no examples of reduced online searchable through google

13:23 stuartsierra: `reduced` was added in Clojure 1.5

13:23 bitemyapp: jtoy: https://www.google.com/search?q=Clojure+%22reduced%22&oq=Clojure+%22reduced%22&aqs=chrome..69i57j0l3j69i64.3014j0j1&sourceid=chrome&ie=UTF-8

13:23 stuartsierra: Along with the reducers framework.

13:23 seangrove: jtoy: https://www.refheap.com/21269

13:23 Not sure it's right, but just gave it a shot

13:24 coventry: reductions is better for repeated sampling, because you only build the CDF once.

13:24 seangrove: It doesn't return the index, not sure what you're doing with it

13:24 jtoy: i would modify it to return the actual item

13:26 TEttinger: coventry, I think I joined after the question?

13:26 jtoy: llasram: wow, that has a couple of functions I have never seen, ffirst and reductions

13:26 bitemyapp: jtoy: never ridden in a caar eh?

13:27 coventry: TEttinger: http://clojure-log.n01se.net/#13:14e

13:27 jtoy: thanks seangrove , I wil test all of them

13:27 nz-_: what would be right way to redefine how liberator library encodes application/json responses? https://github.com/clojure-liberator/liberator/blob/master/src/liberator/representation.clj#L73

13:27 TEttinger: thanks coventry

13:30 nz-_: I can redefine the multimethod that does the encoding and that seems to work. (defmethod liberator.representation/render-map-generic "application/json" [data context] (do my thing) ) but is that the right way to do it?

13:31 danneu: wow, i get 50x speedup from converting my regular find-by-eid Datomic queries into d/datoms raw-index lookup.

13:32 TEttinger: pfft who needs... WHAT 50 TIMES! :)

13:32 myguidingstar: hi all, how can I handle key events in Clojure console apps?

13:33 bitemyapp: danneu: to be fair, you shouldn't actually be using datalog queries for dumb entity fetches.

13:33 TEttinger: myguidingstar, consoles don't send events

13:33 at least not in the traditional GUI sense

13:34 myguidingstar: well, so how to catch some basic key combinations? Ctrl+C, Ctr+D, Enter etc?

13:34 TEttinger: it's definitely possible, BUT some may be platform-specific. obviously windows and apple cmd keys

13:35 let me check

13:35 it probably is the same as for java

13:35 llasram: There's http://code.google.com/p/lanterna/

13:35 technomancy: jline2 is able to do stuff like that too; key-by-key handling

13:35 but you don't get anything for that out of the box

13:36 llasram: myguidingstar: What are you doing at a higher level?

13:38 TEttinger: llasram, heh I just remembered http://sjl.bitbucket.org/clojure-lanterna/terminals/ too

13:38 JDShu: hi I'm really new to clojure - is there anything I need to keep in mind when choosing an SQL DSL for my project?

13:38 danneu: bitemyapp: yeah, that makes sense now. although i've never encountered a datomic resource that asserts it.

13:39 JDShu: https://github.com/clojure/java.jdbc lists three choices

13:39 tim: JDShu: keep it simple, and try clojure jdbc first: http://clojure-doc.org/articles/ecosystem/java_jdbc/home.html

13:40 myguidingstar: llasram, well, I'm writing a lein plugin that has a watcher and I want when users press Enter the watcher is forced to run again

13:40 tbaldridge: JDShu: every DSL adds new bugs/features/complexity. I say stay away from them unless you really need them.

13:40 technomancy: myguidingstar: is it a generic watcher, or something that's coupled to a specific lein task?

13:41 danneu: JDShu: the state of sql in clojure is what propelled me to try datomic

13:42 myguidingstar: technomancy, it's a compiler. What do you mean 'coupled to a lein task'?

13:42 JDShu: tbaldridge: alright thanks for the advce!

13:42 tbaldridge: JDShu: I also really like yesql, mostly because it isn't a DSL: https://github.com/krisajenkins/yesql

13:42 danneu: something like korma is nice, but i also used jdbc in the same codebase to handle the things i couldnt do or figure out with korma. so i have this mix of abstractions and sql strings. i bailed

13:42 technomancy: myguidingstar: well, a watcher ideally would be usable for any lein task. writing yet another single-purpose watcher is silly.

13:43 not that it's stopped people from doing it over and over and over again =\

13:43 myguidingstar: for the watcher I use filevents

13:43 JDShu: danneu: haha awesome good to know

13:45 myguidingstar: technomancy, that means I don't reinvent the wheel, I just want some special behaviours

13:46 xeqi: cemerick: any opposition to moving piggieback to use tools.reader for reading forms like how cljs does now?

13:46 technomancy: myguidingstar: what you need to do is decouple the watching behaviour from the action you want triggered

13:47 bitemyapp: danneu: supposed to use entity and touch :P

13:48 danneu: bitemyapp: what are you referring to? this is what i came up with naively https://www.refheap.com/21270

13:48 TEttinger: myguidingstar, there's also the problem mentioned at http://stackoverflow.com/a/11709814

13:48 myguidingstar: technomancy, thanks, I did it

13:48 danneu: bitemyapp: day-of-datomic also uses all datalog queries for its finders

13:49 bitemyapp: danneu: there's a lot in day-of-datomic that isn't a good idea.

13:49 TEttinger: ctrl-c I believe is... a challenge for JVM apps to grab, because it sends a signal to the JVM if I'm reading this right

13:49 bitemyapp: danneu: we had to replace the "maybe" function from d-o-d because it was really slow.

13:51 seangrove: technomancy: lynaghk was working on something pretty relevant for that a few months ago. Not sure it every panned out though

13:51 myguidingstar: TEttinger, interesting

13:51 llasram: myguidingstar: I think what technomancy is getting at is that someone (maybe you) should write a generic higher-order file-watcher task, which accepts another task to run when things change

13:52 technomancy: seangrove: yeah, pretty much every time anyone mentions it in the channel I tell them to do it the right way instead

13:52 llasram: myguidingstar: So there only needs to be file-event->lein integration once, then you can automatically reuse that for any existing or future task + plugin

13:53 myguidingstar: llasram, oh I didn't get it. You're right

13:53 cemerick: xeqi: none at all, has been a long-term TODO

13:54 xeqi: actually, eval'ing namespaced keywords in CLJS over piggieback probably doesn't work right now, because that move to tools.reader hasn't happened

13:55 xeqi: cemerick: heh, glad I haven't had to use namespaced keywords yet for my projects then

13:56 will try and write up a patch in a few days, is required for repl source info through piggieback

13:56 cemerick: xeqi: nice; the error gets swallowed silently, even :-P https://gist.github.com/cemerick/ec873e84115fc6e83f6a

13:57 xeqi: definitely, much appreciated :-)

13:57 bitemyapp: ORM caching destroying my sanity again. Thanks Python.

13:58 danneu: bitemyapp: some sort of datomic cookbook would be nice to bridge the gap between d-o-d and, for example, independently arriving at "oh, i should use d/datoms for dumb lookup"

13:58 maybe you can attract brambling contribs by dispersing cookbook tidbits of insight among its docstrings

14:00 bitemyapp: danneu: it would be nice if my company wasn't the only one using Brambling.

14:01 reiddraper: incidentally, one of Nodejitsu's earliest founders (since forced out?) is a complete psychopath that threatened to shoot me.

14:02 danneu: a Datomic cookbook is a good idea. I'd only consider putting one together if I could get a publisher interested and the blessing of the Coggies.

14:02 danneu: bitemyapp: ive started using it B-)

14:02 seangrove: Damnit, I can't get paredit to turn on automatically with cider.

14:02 bitemyapp: there's a lot I have yet to explore with Datomic, particularly there's a huge set of unknowns operationally that I'd like to experiment with but haven't had the time or hardware to poke at.

14:02 reiddraper: bitemyapp: wow, not the response from that tweet i was expecting… that's disturbing

14:03 bitemyapp: in particular, I'd like to test some sharding strategy ideas.

14:03 reiddraper: the more you know *------

14:04 cemerick: xeqi: an issue FWIW https://github.com/cemerick/piggieback/issues/19

14:04 bitemyapp: danneu: I'm glad you're using it. Next feature I'd like to make happen is differential migrations. Should only require swapping out the "source", sinking should be identical but sans schema injection.

14:04 coventry: seangrove: I have (add-hook 'clojure-mode-hook 'paredit-mode) in the emacs configuration I use to test cider.

14:04 seangrove: Works for me.

14:05 seangrove: coventry: You use clojure mode in the cider repl?

14:06 technomancy: seangrove: won't paredit break if you have repl output that includes unmatched delimiters?

14:06 coventry: Oh, in the repl buffer? I don't have paredit on there.

14:06 technomancy: I've never actually tried it because the repl buffer contains a lot of stuff that isn't code and thus isn't guaranteed to match

14:06 seangrove: technomancy: Hasn't been a problem for the past year so far, no

14:06 technomancy: huh

14:07 coventry: Hmm, I should try that. I've definitely missed it there.

14:07 seangrove: I can't find the right place to add the hook to turn it on automatically though

14:07 coventry: I can't currently turn it on, though, because the buffer has mismatched parens. :-)

14:07 llasram: technomancy, seangrove: I find it breaks occasionally and I need to wipe the REPL buffer, but it's not usually a big deal

14:08 seangrove: llasram: That's possible I suppose, I just haven't had it happen enough that it comes to mind at all

14:08 danneu: bitemyapp: what if it was just a brainstorm-centric bitemyapp/datomic-cookbook

14:09 dotemacs: talking of parenthesis I use smartparens and have it turned on globally, no issues, in repl or elsewhere

14:09 danneu: a place accumulate morsels and bulletpoints if nothing else

14:10 hiredman: I tried smart parens and found it to be a huge hassle, it didn't seem to be as smart about things like different types of quotes as paredit

14:10 coventry: I'm getting "text is read-only" when I try to wipe the repl buffer. Anyone know what could be causing that/how to deal with it? toggle-read-only doesn't fix it.

14:10 hiredman: and didn't try as hard to keep the document well structured

14:10 seangrove: hiredman: Yeah, paredit seemed to be quite a bit nicer.

14:10 coventry: C-c M-o?

14:10 llasram: coventry: Try the command `cider-clear-buffer` (or `nrepl-clear-buffer`)

14:10 bitemyapp: hiredman: Emacs Live has a good smartparens Clojure config.

14:10 hiredman: every time I typed ` it would match it, which drove me nuts in clojure

14:10 bitemyapp: hiredman: you have to have a custom config that distinguishes things like ' and ` from "

14:10 coventry: Thanks, guys. C-c M-o did the job.

14:11 bitemyapp: hiredman: https://github.com/overtone/emacs-live/blob/master/packs/dev/clojure-pack/config/smartparens-conf.el

14:12 hiredman: I use smartparens because it's more flexible I favor the behavior over how paredit works.

14:12 paredit is too restrictive.

14:12 seangrove: Damnit, just can't get it http://dl.dropbox.com/u/412963/Screenshots/4t.png

14:12 dotemacs: regarding the PDF form filling using clojure question I asked yesterday (in case that you care): wrapped up iText and it works well

14:13 technomancy: smartparens seems like a toolkit for building a mode that does what you want, rather than something that Just Works out of the box

14:13 bitemyapp: seangrove: ouch, Cider?

14:13 technomancy: which is why you can use the Emacs Live config to get something intelligent for Clojure out of the box...

14:13 seangrove: Probably enough time trying to automate this for today

14:13 coventry: seangrove: Try cider-repl-mode-hook rather than cider-repl-mode.

14:14 hiredman: which would be great if a mode was what I wanted, I guess

14:14 seangrove: coventry: That was the one, thank you

14:14 * seangrove breathes a bit a easier

14:16 bitemyapp: seangrove: that's a general pattern too, *-mode-hook

14:16 seangrove: bitemyapp: Yes, my fault for not paying attention. Nice to have others around to sanity-check :)

14:16 coventry: Glad it works for you. It causes my nrepl to hang during startup. :-) ("lein repl" works at the CL, though.)

14:17 bitemyapp: I don't understand people that use nrepl-jack-in.

14:17 seangrove: I use it exclusively

14:17 bitemyapp: I want a persistent nrepl server with a port for each project I work on, not stuff bound to my Emacs session.

14:17 my Emacs sessions have shorter life spans than my nrepl servers.

14:17 technomancy: bitemyapp: all your projects in one server? huh?

14:17 bitemyapp: technomancy: no, I use a separate server and port for each project.

14:17 seangrove: bitemyapp: I have the opposite experience - my emacs sessions tend to go for weeks at a time

14:18 bitemyapp: seangrove: I do things that kill my Emacs regularly.

14:18 technomancy: you monster

14:18 seangrove: hahaha

14:18 coventry: That must be hell for your workflow.

14:18 bitemyapp: coventry: well, I'm an idiot and I do dumb things when I work with large datasets.

14:19 `cbp: tell 'em. I'm a dummy.

14:19 seangrove: bitemyapp: Yeah, I suppose if I was working with data that constantly threatened to kill emacs, I would want something like a separate nrepl server

14:19 `cbp: indeed.

14:19 coventry: Oh, yeah, that's happened to me. Helps a lot to send output to a file, but it's easy to forget that.

14:19 danielszmulewicz: So for you guys who run long-standing emacs sessions, I have the following question: M-x b shows me a whole lot of buffers from different projects. What is your solution?

14:20 bitemyapp: coventry: streaming output + tail -f == sanity retained

14:20 seangrove: coventry: Yeah, I think that's one of the worst parts of the emacs integration - the fear of accidentally killing everything

14:20 bitemyapp: danielszmulewicz: fuzzy-search in my buffer lists.

14:20 C-x b

14:20 + IDO

14:20 + iswitchb

14:21 coventry: There's a tool for opening a file within a git project. I haven't had much need for it yet, though.

14:21 technomancy: danielszmulewicz: I have a separate emacs instance per project

14:21 bitemyapp: seangrove: that's like 90% of the reason I keep separate nrepl servers. large data killing my Emacs.

14:21 danneu: danielszmulewicz: i use https://github.com/bbatsov/projectile to flash between projects. using whatever buffer command from projectile can just show the buffers related to the project that contains the current buffer

14:21 hiredman: danielszmulewicz: what is the problem?

14:21 bitemyapp: I've had nrepl sessions that lagged Emacs so badly I had to finish my work in the terminal.

14:21 technomancy: but I keep the emacs instance running for as long as I'm hacking the project

14:21 bitemyapp: M-x nrepl-restart?

14:21 danielszmulewicz: I would like to filter the buffers per project, so that M-x b shows only relevant buffers

14:21 bitemyapp: technomancy: I can try that next time it happens.

14:22 technomancy: bitemyapp: only works if you jack-in, I think

14:22 seangrove: technomancy: That's crazy talk. I have one emacs server, and a bunch of emacsclient -t's

14:22 technomancy: seangrove: I like my namespacing

14:22 danielszmulewicz: technomancy: Oh, interesting, I like fast startup so I run a daemon

14:22 technomancy: I don't want to accidentally switch to an email buffer when I'm hacking lein

14:22 bitemyapp: technomancy: oh well fuck it then.

14:22 technomancy: I'm not doing that. :P

14:22 technomancy: danielszmulewicz: with package.el and autoloads it's pretty trivial to get subsecond launch times

14:23 bitemyapp: technomancy: I kill my Emacs and reconnect it to the same nrepl session, that resolves the lag usually.

14:23 seangrove: technomancy: Understandable. I tend to keep the window layout pretty sparse, and push most of the data management stuff into emacs

14:23 technomancy: bitemyapp: no would killing your nrepl repl buffer and reconnecting

14:23 bitemyapp: technomancy: that too

14:23 technomancy: *so would

14:23 danielszmulewicz: danneu: projectile-switch-to-buffer?

14:24 bitemyapp: technomancy: I've done both.

14:24 danielszmulewicz: I have 375308 LOC in my ~/.emacs.d/, Emacs takes ~3-5 seconds to start.

14:24 danielszmulewicz: I also have 8719 lines of Python.

14:25 the 375k is just Lisp.

14:25 danielszmulewicz: I think projectile should push its buffers to speedbar.

14:25 Some modes do that kind of interop with speedbar

14:26 danneu: bitemyapp: what kind of yakshaving have you got going on in 375308

14:26 lines

14:26 seangrove: Clearly LightTable is the answer here.

14:26 bitemyapp: danneu: Find out for yourself, but the answer is a long history of vendoring and customizing things (many years) github.com/bitemyapp/dotfiles/

14:26 danielszmulewicz: I tried workgroups2 but that didn't work out

14:27 seangrove: wat

14:27 b-ot: seangrove: any idea what the 'proper' way to display a flash object on a website is that gets passed throuhg w3c?

14:27 bitemyapp: seangrove: yes I can't wait for Chris to single-handedly replace everything I use Emacs for.

14:28 seangrove: bitemyapp: He's got a lot of work ahead of him, hope he's waking up early these days.

14:29 danielszmulewicz: technomancy: how many instances of emacs do you end up running simultenously?

14:30 technomancy: danielszmulewicz: seven right now

14:30 three of which are over tmux+ssh

14:30 seangrove: o_O

14:30 technomancy: Are you OSX? How do you keep them straight?

14:30 technomancy: seangrove: haha. no.

14:30 * seangrove imagines the kind of multi-monitor, multi-window nightmare it'd take to make proper use of 7 emacs

14:30 rasmusto: tmux editor sessions are the best

14:31 bitemyapp: seangrove: well, point being, his current focus is good. He can't/shouldn't attempt to replace every little thing people use an editor for.

14:31 technomancy: it's just xmonad. easy. ¯\_(ツ)_/¯

14:31 bitemyapp: seangrove: XMonad is my favorite thing about working on Linux at home.

14:31 easily.

14:31 seangrove: 😥

14:31 * rasmusto uses awesome

14:31 technomancy: seangrove: all my work stuff is done as a separate unix user for compliance reasons

14:32 danielszmulewicz: I like stumpwm. Stays in the family.

14:32 technomancy: so I have two instance for email, one for IRC+IM

14:32 seangrove: technomancy: Sounds like a pretty sane setup, actually.

14:32 technomancy: seangrove: yeah, the separate user thing works out better than I expected

14:32 seangrove: I'll eventually have to make time to setup a xmonad-capable machine

14:33 technomancy: conkeror for regular browsing and x-forwarded chromium for work stuff

14:34 seangrove: also I keep the hacking emacs instances apart by using a separate color theme for each.

14:34 danielszmulewicz: technomancy: That setup running on your 4 year old thinkpad? :-)

14:34 technomancy: danielszmulewicz: yeap

14:34 danielszmulewicz: technomancy: awesome

14:35 technomancy: it's great

14:35 rasmusto: t420?

14:35 er, 400?

14:35 hiredman: t1000

14:35 technomancy: rasmusto: X200s

14:35 rasmusto: technomancy: ah nice. I have an x220 myself

14:36 technomancy: rasmusto: can't bring myself to buy a low-res model =\

14:36 holding on to this one for dear life

14:36 rasmusto: I know, that's my only real complaint, aside from the squeaky expansion slot

14:36 technomancy: that's the last one with the classic keyboard though, right?

14:36 rasmusto: at least there are plenty of 11pt px-mapped fonts. Yes, classic keyboard

14:36 technomancy: nice

14:37 seangrove: technomancy: Separate color schemes sounds like a good idea as well. Might be worth trying out some time.

14:37 rasmusto: well, except for the control/fn nonsense, but I use caps for control anyways

14:37 danielszmulewicz: technomancy: the tmux instances must be teminal emacs, the others you run in X or also in a terminal?

14:37 technomancy: danielszmulewicz: mostly in X, though there's not much difference between the two in my setup

14:38 just having access to the X clipboard instead of the tmux clipboard primarily

14:39 rasmusto: hiredman: t1000-carbon-chiclet?

14:39 bitemyapp: just got to show a coworker (into {} (map vector ...)) and (frequencies ...) - feeling brilliant :D

14:39 seangrove: bitemyapp: Be sure to show them group-by as well, one of my favorites

14:40 coventry: The page for xmonad is not really selling me on it. What's nice about it?

14:40 hiredman: t1000's are a mimetic poly-alloy

14:40 bitemyapp: seangrove: they've already seen that, it's in the Tardis codebase.

14:40 coventry: it's advanced alien technology.

14:40 technomancy: coventry: difficult to explain. it just works perfectly and does everything right.

14:41 coventry: Heh, "It's not stupid, it's ADVANCED!" I'll give it a go.

14:41 technomancy: I'm used to tweaking my setup endlessly, but xmonad pre-empts that by just reading my mind and doing what I want

14:41 rasmusto: is this as good as frequencies? ,(into {} (map (fn [[k v]] [k (count v)]) (group-by identity [:a :a :b :c])))

14:42 except being harder to type ofc :P

14:43 technomancy: coventry: one cool thing is that you can change workspaces of individual displays independently

14:43 rasmusto: I can't quite grok the assoc!/transient thing in the frequencies impl

14:43 technomancy: coventry: takes a bit of getting used to, but is definitely a superior model

14:43 justin_smith: yeah, I like the workspace per display thing

14:43 and full screen also being per display

14:44 `cbp: rasmusto: read up on transients then :P

14:44 rasmusto: technomancy: awesome3 lets you "tag" windows to multiple workspaces, so you can have a single thing in multiple places

14:44 `cbp: aw, ok :)

14:44 technomancy: rasmusto: yeah, that was one thing I liked about wmii. in practice I never used it personally.

14:44 bitemyapp: rasmusto: (into {} (for [[k v] (group-by identity "abbbc")] [k (count v)]))

14:44 justin_smith: I actually switched to notion, because I like having absolute control of window layout independent of app instances (yes I know that is weird), but I miss xmonad features and may just hack the behavior into xmonad one of these weekends

14:45 coventry: rasmusto: You get the same result as if you hadn't used transients, but it's faster in some circumstances because assoc! is bashing a data structure in-place.

14:45 bitemyapp: I actually think the transients implementation is pretty elegant.

14:45 justin_smith: coventry: is allowed to, but not guaranteed to :) you still need to use the return value of the transient op

14:46 rasmusto: Okay, reading the transient rationale (and "tree falling in the woods" thing) cleared it up :)

14:46 dnolen: bitemyapp: it's also pretty novel, I'm not aware that they exist elsewhere - certainly nothing in the literature

14:47 danielszmulewicz: technomancy: If you ever going to try stumpwm, you might want to take a look at this: https://gitorious.org/dss-project/stumpmacs/source/1a2d69f20f0843fce5c5213a539824020786ad27:

14:48 bitemyapp: dnolen: Context please?

14:48 dnolen: bitemyapp: transients

14:48 bitemyapp: dnolen: they most certainly exist in Haskell, in a much richer variety and forms.

14:49 dnolen: that's part of the whole point of the ST Monad among other things.

14:49 dnolen: bitemyapp: link?

14:49 bitemyapp: yeah not even remotely the same thing

14:49 coventry: Hmm, xmonad causes emacs to run off the screen. I'll play with it more later.

14:50 bitemyapp: dnolen: http://hackage.haskell.org/package/vector-0.7.0.1/docs/Data-Vector.html

14:50 dnolen: data freezing (after building from something mutable but hasn't escaped a monadic scope) is very common.

14:50 dnolen: bitemyapp: the novelty around transient is specifically taking Ideal Hash Tries and wrapping the nodes w/ edit markers so you can do O(1) conversion to and from in

14:51 bitemyapp: yes that's the simple idea - not what is novel about Clojure implementation of PersistentVector/HashMap Transients

14:52 bitemyapp: dnolen: that's getting incredibly implementation specific.

14:52 the point was that the concept of building something mutably and freezing it into something immutable is a thing in Haskell.

14:52 dnolen: bitemyapp: that was my whole point - you said implementation

14:52 danielszmulewicz: Is there a manual somewhere for clojurebot? Don't want to bother anyone with basic usage questions.

14:52 dnolen: bitemyapp: I'm not saying that isn't common in Haskell

14:53 bitemyapp: See, the nitpicking, this is why I cringe everytime you ask me to elaborate on something.

14:53 because I know invariably you're going to keep digging until you've got something you can contradict me with.

14:54 tbaldridge: bitemyapp: It can be good to welcome such interactions, can help you learn

14:54 dnolen: bitemyapp: heh don't worry, I won't. I thought you were making a specific point about how elegant they are - and I agreed, and I'm not ware that the idea has been done elsewhere where Ideal Hash Trie data structures are available.

14:55 bitemyapp: tbaldridge: there's no learning here, I was talking about a different aspect of what I saying Haskell offered (freezing mutable data or containing/scoping side effects)

14:55 dnolen: I don't think it's out of the question that unordered-containers in Haskell could implement the same thing. It just doesn't matter because when people are solving this general category of problem they use monads/unsafe/freezing.

14:56 dnolen: the reason it doesn't exist in that exact form is because comparable solutions exist, my point was that comparable solutions exist. Most languages outside of Clojure and Haskell don't have this in any form at all.

14:56 danielszmulewicz: lazybot, I meant.

14:57 dnolen: bitemyapp: look, I know this - I just thought you were talking about how cool the Clojure implementation is all and that other people should copy it :)

14:57 danielszmulewicz: $help

14:57 lazybot: You're going to need to tell me what you want help with.

14:57 bitemyapp: dnolen: unsafeFreeze on MArray in Haskell is a non-copying O(1) as well.

14:58 `cbp: $help me

14:58 lazybot: Topic: "me" doesn't exist!

14:58 danielszmulewicz: ,$help entry

14:58 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: $help in this context, compiling:(NO_SOURCE_PATH:0:0)>

14:58 danielszmulewicz: $help entry

14:58 lazybot: Topic: "entry" doesn't exist!

14:58 TEttinger: danielszmulewicz, yeah I made my own commands command for my lazybot

14:58 it sends like 5 messages...

14:58 danielszmulewicz: ,commands

14:58 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: commands in this context, compiling:(NO_SOURCE_PATH:0:0)>

14:59 danielszmulewicz: TEttinger: what do I type?

14:59 dnolen: bitemyapp: but do you get O(1) unsafeThaw, that is the point

14:59 TEttinger: https://github.com/flatland/lazybot/tree/master/src/lazybot/plugins you go here for now...

14:59 danielszmulewicz: TEttinger: thanks

14:59 TEttinger: because that bot isn't on this server

14:59 lazybot and my roguebot have diverged a bit

14:59 I last checked out in may

15:00 bitemyapp: dnolen: yes.

15:00 danielszmulewicz: TEttinger: what's running here?

15:00 TEttinger: lazybot and clojurebot

15:00 I copied an older lazybot

15:00 danielszmulewicz: TEttinger: OK

15:00 bitemyapp: dnolen: the unsafe thaw and freeze are non-copying O(1) for multiple types of arrays.

15:00 danielszmulewicz: ,cmd

15:00 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: cmd in this context, compiling:(NO_SOURCE_PATH:0:0)>

15:00 TEttinger: added a bunch of features, maybe i did some poorly

15:00 coventry: TEttinger, is lazybot yours? For some reason, I thought it was Raynes's.

15:00 TEttinger: you can /msg lazybot

15:01 no not mine

15:01 it is Raynes

15:01 Roguebot is mine, but it's on Quakenet only (that hive of scum and villainy)

15:01 bitemyapp: dnolen: literally the only thing missing is the specific combination of unordered-containers + O(1) non-copying freeze/thaw. Which most Haskell users don't care about (unordered-containers)

15:01 Raynes: lazybot would be the combined consciousness of a Raynes and an amalloy_.

15:01 dnolen: bitemyapp: unsafeThaw makes no such guarantees based on the documentation, must be provided for by the underlying implementation

15:01 bitemyapp: They usually use more specialized collection types.

15:01 dnolen: bitemyapp: http://hackage.haskell.org/package/array-0.3.0.2/docs/Data-Array-MArray.html

15:01 seangrove: coventry: I think it's actually a feral bot

15:01 coventry: Heh. Where's the power cord???

15:01 lazybot: coventry: Oh, absolutely.

15:02 coventry: Oh dear.

15:02 bitemyapp: dnolen: it...is...implemented...

15:02 dnolen: did you look at the types provided for?

15:02 TEttinger: and Raynes is the man, if it weren't for lazybot I would still be messing with painful stuff to get my own bot running and featureful

15:03 dnolen: bitemyapp: anyways we're going into the weeds, unsafeThaw doesn't guarantee anything - anyways my point is only the implementation of transients and their novelty - moving on now

15:03 TEttinger: moving onto cats

15:03 http://i.imgur.com/Bmb9P.jpg

15:04 bitemyapp: dnolen: the guarantees are part of the type system, not the runtime implementation

15:04 dnolen: Haskell decomplected safety from runtime behavior >:)

15:04 TEttinger: they're eating my soul

15:04 dnolen: bitemyapp: the doc string for unsafeThaw is scary, we must be reading different things

15:05 bitemyapp: dnolen: you're expecting to understand what the IO and ST monad are doing for you.

15:05 TEttinger: (inc Raynes)

15:05 bitemyapp: expected*

15:05 lazybot: ⇒ 37

15:07 seangrove: Wow, "Iran Facts" is advertising on youtube. This can't be a good thing.

15:08 bitemyapp: saw a tweet recently, "I wonder how Iran will react when they find out they can't keep their health insurance plan?"

15:08 TEttinger: Iran "Facts"

15:08 mattmoss: Iran fax

15:08 TEttinger: Iron fox

15:09 bitemyapp: dnolen: everything in Haskell, including the mutable data types, is designed around equational reasoning. Even Oleg will abandon a line of investigation that cannot maintain that property.

15:09 seangrove: Wow, the 2 minute scaremongering ad ends with a huge bomb explosion and says we need to protect ourselves.

15:09 Lovely.

15:09 dnolen: the safety of unsafeThaw/Freeze http://www.haskell.org/pipermail/glasgow-haskell-users/2005-November/009235.html

15:09 bitemyapp: seangrove: didn't we win the Cold War with blue jeans and Coca Cola?

15:11 dnolen: yep, anything with unsafe* or acme-* at the beginning is a Bad Idea (TM) unless you know what you're doing.

15:11 acme is typically a bad idea even when you do.

15:12 coventry: bitemyapp: That sounds a lot less handy than the "just add bangs to everything and it'll work the same, but faster" deal you get wiht transients, though.

15:12 bitemyapp: coventry: there's a continuum of solutions in Haskell to that general problem, you just have to choose your preferred balance of safety and performance.

15:14 coventry: another difference is that the general attitude is that if the type system can statically verify the safety of the code, that the compiler output produces something that uses mutability isn't very important.

15:14 coventry: So what on that continuum corresponds to the safety and performance of transients?

15:15 bitemyapp: coventry: almost anything that uses a mutable data structure inside of ST.

15:15 I say almost because you can certainly do things that crash, but that's pretty easy to avoid by not using the "scary" packages.

15:17 coventry: having an optimizing compiler with very high-level (monadic) static type information means you can get away with some interesting optimizations while maintaining safety.

15:19 having access to unboxed value types is really nice too.

15:20 you can pass the equivalent of struct A { int a; }; around.

15:40 iKillCypher: b

16:12 seangrove: Sometimes the cljs repl just freaks out and consumes 700% cpu across all cores.

16:14 wink: is there some sort of goto auth/user framework/lib for webapps? more like django than noir

16:16 dnolen: seangrove: browser REPL or are you talking about piggieback?

16:16 seangrove: or both?

16:17 seangrove: dnolen: piggieback/austin/cider, somewhere in there. I just kill it and restart everything right now. Not sure how to track it down other than at the process level.

16:17 TEttinger: wink: I've heard of friend a few times

16:18 wink: thx

16:18 TEttinger: https://github.com/cemerick/friend

16:18 dnolen: seangrove: I wonder if this is memory related?

16:19 coventry: TEttinger, wink: That's specifically for auth, though, whereas it sounds like wink's asking about a django-style framework.

16:19 wink: coventry: no, just a little more laid out than libnoir/bare

16:20 coventry: Cool.

16:20 sritchie: seangrove: I think it's related to ac-nrepl

16:20 there was a friend bug about that

16:20 err, a cider bug

16:21 dnolen: wink: http://www.luminusweb.net? also http://let-caribou.in

16:21 bitemyapp: dnolen: luminus doesn't really have an auth library.

16:21 dnolen: you just implement your own.

16:21 I have no idea if caribou does or doesn't.

16:21 dnolen: bitemyapp: you can't just add some middleware?

16:21 bitemyapp: dnolen: that's our attitude towards it.

16:22 dnolen: We don't really like the existing auth libraries and don't consider it a particularly difficult problem.

16:22 wink: exactly

16:22 dnolen: bitemyapp: got it

16:22 bitemyapp: we just show people an example and let them take it from there.

16:22 wink: well I haven't had the energy to come up with those few lines

16:22 I wanted some plug-and-play thing for the few small apps I have

16:24 bitemyapp: wink: if you're that lazy, copy-pasta from neubite or Luminus.

16:24 wink: https://github.com/bitemyapp/neubite/blob/master/src/neubite/middleware.clj#L35-L44

16:24 wink: bitemyapp: thanks

16:24 bitemyapp: wink: provide the "get-user-by-email" functionality and toss a :user-email into the session (encrypted)

16:25 wink: https://github.com/bitemyapp/neubite/blob/master/src/neubite/handler.clj#L49-L51

16:25 that's the middleware for the encrypted sessions

16:25 all told, 5-10 LOC

16:25 wink: woo *frantically writes down links*

16:27 bitemyapp: for how small it is, I get a lot of mileage out of pointing people to Neubite for web stuff.

16:31 guns: Does anyone object to telling new users to install :user :dependencies as "LATEST" or "RELEASE"?

16:32 coventry: That sounds handy, actually. Do you need to specify anything in your project.clj file for that to work?

16:33 guns: No, it's just a maven keyword AFAICT

16:33 coventry: Thanks.

16:34 technomancy: guns: as long as it's a dev or user profile only thing it's not bad

16:34 guns: I'll be sure to point that out

16:35 I'm recording a slamhound screencast, actually

16:35 technomancy: oh, the other thing is it'll trigger a check for an update every 24h

16:35 so that could get annoying

16:35 seangrove: Wow, cool to hear guns

16:35 guns: I see

16:35 technomancy: looking forward to the screencast =)

16:35 guns: Maybe I won't bother the

16:39 coventry: Is the clojure compiler thread-safe in the sense that it can safely compile multiple forms in simultaneous threads?

16:42 lnostdal: not in my experience .. e.g. defonce vs. the same `name` is not thread safe

16:43 coventry: Good point. Thanks.

16:50 alexyakushev: Hello friends, I've just created #clojure-android IRC channel and will try to hang there periodically. If you have questions too instant to come to mailing list, feel free to ask on the channel

17:48 srruby: I have a small module that uses a template which it loads from disk. Is it better to NOT load the template in the module? If not then how? The reason I ask is that loading the template uses IO and I understand that it is better to code with pure functions. https://gist.github.com/rothfield/7667730

17:51 typeclassy: sometimes it's "better" to code with "pure" functions, but i really don't think you're going to have much trouble loading a single template from a file

17:51 bitemyapp: srruby: I already added a comment about one possible improvement. I don't see anything else wrong with it given the provided context.

17:52 srruby: more context would tell me more about what to improve.

17:52 srruby: Thanks all!

17:52 bitemyapp: srruby: pure functions when you can, when you can't, whatevs.

17:52 srruby: the way to split it out is to separate the lilypond stuff from the resource/slurp invocations so that it just takes a string.

17:57 srruby: bitemyapp: Thanks. I guess it is a good rule to do IO stuff in main.

17:58 bitemyapp: srruby: uh, not "main"

17:58 srruby: just separately.

17:58 srruby: I try to separate IO into actions/providers that feed into the pure code.

17:59 srruby: makes the both bits of code more reusable.

17:59 srruby: ok

18:00 bitemyapp: srruby: don't make a religion out of anything though. one-off code is what it is.

18:02 pmonks: Speaking of religion - should I be concerned that we have 666 members right now? o.O

18:02 DOH - riley526 spoilt my observation!

18:03 riley526: pmonks: hah

18:03 no more need for concern.

18:03 pmonks: (phew)

18:03 OH NOES!!!!

18:05 bitemyapp: srruby: to maintain "easy" you can wrap the IO stuff and pure stuff with an outer layer.

18:06 danneu: Is there a simpler way to select a map based on a key value? (first (filter #(= 3 (:thing/idx %)) all-things))

18:07 srruby: bitemyapp: OK.

18:17 hyPiRion: danneu: (first (for [{elem :thing/idx :as m} all-things :when (= 3 elem)] m)) ?

18:18 bitemyapp: I never use for. I feel like I'm missing something therer.

18:18 there*

18:20 rasmusto: isn't that the same thing?

18:20 hyPiRion: semantically the same, sure.

18:21 rasmusto: (some (fn [{elem :thing/idx :as m}] (if (= 3 elem) m)) all-things) works too, yea?

18:21 technomancy: bitemyapp: it's great for nested loops

18:22 bitemyapp: technomancy: I just write horrific artifacts of my time spent in Python and CL that are nested map/filter/reduce.

18:22 technomancy: so instead of a single for clause, I'll have like 4 or 5 of those babies.

18:23 technomancy: bitemyapp: for most things, ->> with map+filter is fine

18:23 rasmusto: my only wish for "for" is that you could do (for [:let [a 'foo] b (range)] [a b)

18:23 technomancy: but ->> with a nested map gets ugly fast

18:23 bitemyapp: technomancy: I don't ->>

18:23 (((((( :lol :die ))))))

18:23 technomancy: well then I don't even know what's wrong with you

18:23 bitemyapp: technomancy: Common Lisp and Python. That's what.

18:23 justin_smith: I have a config storage that can have atoms in it, and has a special case for embedded atoms so they can be swap!'d or reset!'d rather than being replaced in the parent map

18:23 rasmusto: do you -> bitemyapp ?

18:23 TEttinger: pfffffft. you only wish you could be using hundreds-of-character regexes as part of a (map read-string ...) https://dl.dropboxusercontent.com/u/11914692/class-formatter.clj

18:24 bitemyapp: technomancy: the limitations of single-expression lambdas warped me.

18:24 technomancy: bitemyapp: they have recovery programs for that

18:24 well, tehy should

18:24 bitemyapp: rasmusto: oh I do use -> and ->>, it's just that for this specific instance, when I'm building up what would ordinarily be a list comprehension I'll just accumulate and nest map/filter.

18:24 justin_smith: if I want a client to be able to use an avout distributedAtom, but don't want to add a distributedatom dependency, what is the best way to make that modular?

18:24 bitemyapp: people still use Avout? Sweet!

18:25 justin_smith: is there a better option? it seems nice so far

18:25 rasmusto: bitemyapp: ah, okay. I feel like I use ->> about half the time, depends on how much I care about individual elements, or if I do partitioning/destructuring

18:25 JDShu: is there a goto solution for user management for clojure web applications?

18:25 justin_smith: I mean I guess I could add avout as an unconditional dependency of my lib, but leaving it modular would be nice

18:26 bitemyapp: justin_smith: uh not really. I'd like a high-performance Mnesia'ish data store for Clojure but Avout is all we have atm.

18:26 rasmusto: ,(for [[a b] (partition 2 1 (range 10))] [a b])

18:26 clojurebot: ([0 1] [1 2] [2 3] [3 4] [4 5] ...)

18:26 bitemyapp: justin_smith: maybe Spacebase's stuff?

18:26 or Immutant.

18:26 'ish

18:26 TEttinger: JDShu, this happened to be asked not long ago. http://let-caribou.in http://www.luminusweb.net https://github.com/cemerick/friend

18:27 rasmusto: ,(->> (range 10) (partition 2 1) (fn [[a b]] [a b]))

18:27 clojurebot: #<sandbox$eval81$fn__83 sandbox$eval81$fn__83@13e043>

18:27 rasmusto: ah well, you get the point

18:28 JDShu: TEttinger: I found friend through a search, would you say that's pretty much it?

18:29 TEttinger: I don't do web dev in clojure yet, caribou might be an alternative?

18:30 JDShu: TEttinger: alright, thanks :) I guess I'll try using friend for now

18:30 TEttinger: it seems to be well-supported

18:31 friend questions are certainly more frequent than caribou ones in here

18:31 JDShu: awesome, thanks for the context!

18:33 technomancy: argh "performant"

18:35 TEttinger: technomancy, I never know if performant is a word or not

18:35 technomancy: TEttinger: I don't want to get into the "not a word" debate

18:35 actually

18:35 TEttinger: you're not a word

18:35 typeclassy: i have over thirteen years of experience in web application performancy

18:35 technomancy: here we go https://mobile.twitter.com/aphyr/status/403596006211604481

18:36 justin_smith: wait, how would caribou replace friend? as a caribou dev that proposal sounds odd at first glance

18:37 technomancy: justin_smith: do you have the power to replace s/performant/efficient/ on the caribou homepage?

18:37 justin_smith: I do!

18:37 I'll consider that, thanks

18:37 technomancy: sweet

18:38 I like the logo

18:38 justin_smith: thanks

18:38 we have some good designers here

18:40 the answer to my above question turns out to be: implement a protocol, have an avout extension of the protocol, so that avout can be injected by a user of the lib but someone who does not need avout (or wants mongo or immutant for coordination instead) can avoid the avout dep

18:40 I think

19:08 technomancy: pr submitted, with any luck we should see the change in the next deploy of the site

19:08 thanks again for the suggestion

19:08 technomancy: \m/

19:09 I have a (pretty short) list of words I can't read without cringing, and that is on it.

19:09 along with "utilize", "webinar", and "ask" as a noun

19:10 brehaut: technomancy: i hesitate to query this, but how can ask be a noun

19:11 technomancy: brehaut: happy to hear the madness hasn't spread to your locale yet

19:11 "Let me look over the document and I'll send you a list of my asks." - an actual human, not joking

19:11 brehaut: i just died a little

19:11 technomancy: grown ups say this

19:12 in 'murikka

19:12 brehaut: is this the same category of grownups who communicate via .ppt files rather than plain text?

19:12 (likely the same category that bemoan text messaging as destroying language)

19:12 technomancy: I believe there's some correlation

19:20 hyPiRion: technomancy: that's a strange abuse of the word ask. I guess they meant 'requests' in that context?

19:21 technomancy: yeah, I don't understand it

19:22 language evolves, but I would prefer it to evolve in ways that make sense, like maybe *finally* adding a plural "you" to English which has been bereft for bloody centuries

19:24 Bronsa: technomancy: that would be *great*

19:24 justin_smith: technomancy: clearly the word you are looking for is all-y'all

19:24 brehaut: is y'all singular now?

19:24 wait

19:24 brain fart

19:24 justin_smith: brehaut: depends on dialect

19:24 dsrx: "y'all" can be singular or plural

19:24 much like "you"

19:25 but unlike "you all"

19:25 technomancy: ._.

19:25 pmonks: Pretty sure it's singular in TX.

19:25 brehaut: thats it. im never visiting america

19:25 justin_smith: all-y'all is unambiguous though

19:25 pmonks: all y'all is plural

19:25 (in TX)

19:25 brehaut: how long till all y'all is signular again, and you have to use all all y'all

19:26 in some ridiculous peano number style greating

19:26 justin_smith: the deplurality treadmill

19:26 brehaut: s/ea/ee/

19:26 justin_smith: not nearly as fun as the dysphemism treadmill

19:26 technomancy: brehaut: with a preliminary handshaking phase to determine which enlgish version is active

19:27 justin_smith: oh, handshaking, in that case the Texans will love it

19:27 technomancy: I honestly don't see what's wrong with https://en.wiktionary.org/wiki/yous

19:27 hiredman: "sup" "hello" version mismatch

19:27 brehaut: technomancy, hiredman: nicely done

19:29 technomancy: https://en.wiktionary.org/wiki/Wiktionary:List_of_protologisms_by_topic/third_person_singular_gender_neutral_pronouns

19:30 that's quite the list

19:32 amalloy: one of my math professors love to talk about all-yall, and so on. his favorite was yins

19:36 technomancy: so... I'm thinking of how cool it would be to support rich content types in nrepl

19:36 so you could have operations that returned jpegs or SVGs

19:36 or html or whatever

19:38 amalloy: technomancy: doesn't hiredman have something like that?

19:38 hiredman: I have lots of things

19:38 technomancy: is this awesome? [Y/n]

19:38 dsrx: lol, peano number style greeting

19:39 technomancy: hiredman: you had a gui repl thing, right?

19:39 Wild_Cat: technomancy: kinda like IPython Notebook? That'd rock.

19:39 hiredman: several, and I had a pr for session to use nrepl, and this clojruescript browser scratchpad thing

19:39 technomancy: Wild_Cat: I haven't used IPython, but DrRacket and Factor do a great job at this

19:40 Wild_Cat: technomancy: http://ipython.org/notebook.html

19:40 technomancy: I want someone to write a monitoring endpoint that can return SVG graphs

19:40 for load and memory usage

19:40 hiredman: the thing with content types is you get, you know, a hunk of xml data that is svg

19:40 Wild_Cat: I saw a presentation or two at Pycon, and it blew my mind

19:40 now all I have to do is find reasons to use it :p

19:40 technomancy: Wild_Cat: right; why shouldn't that be built-in to nrepl?

19:40 hiredman: where I think something like the reader tags would be better

19:41 #chart/rows [[1 2] [3 4] [5 6]]

19:41 technomancy: hiredman: how do you do content negotiation then?

19:41 Wild_Cat: technomancy: other than "because it runs in a console widget", I have no objections. In fact, it'd rock.

19:41 technomancy: Wild_Cat: yeah, you would need graceful degradation

19:41 Wild_Cat: if anything because it'd finally rid ourselves of the abomination that the Windows console widget is.

19:41 justin_smith: technomancy: regarding the idea of making something like schmetterling as an nrepl middleware, would that mean using that middleware in the debugged process, or the debugging one? some combo?

19:42 I think bitemyapp had some input on this too

19:42 technomancy: justin_smith: it would belong on the project process

19:42 the debugee

19:43 hiredman: technomancy: the idea is not to do content negotiation

19:43 justin_smith: so instead of stopping the debuggee and poking at the halted process, you leave it running and...

19:43 technomancy: hiredman: ah, so the server is unaware of the client's capabilities

19:43 hiredman: technomancy: #chart/rows [[1 2] [3 4] [5 6]] is data and readable even if you don't know what #chart/rows is

19:44 you can get the vector and fiddle with it

19:45 I dunno, there are some trade-offs with that approach as well, but it is currently what I am thinking I will do for my current pass at computational documents for clojure

19:46 I'll need to replace pr with a protocol display, that by default gives you "#display/pr-str <result of pr-str escaped as string>"

19:46 technomancy: hiredman: yeah, that puts a lot more logic in the client, which I'm less fond of

19:46 hiredman: so the client will edn/read everything to get back whatever to render

19:46 technomancy: right now you don't need a reader to be an nrepl client

19:46 plus I don't know how you'd support things like the inspector offering hyperlinks

19:47 hiredman: #display/html

19:47 justin_smith: technomancy: re s/performant/efficient - just got merged

19:47 technomancy: hiredman: but many clients can't do anything with HTML

19:47 hiredman: technomancy: yeah, well I have the luxary of using clojurescript as the client, so I don't have a reader

19:48 technomancy: how do hyperlinks work in your scheme?

19:48 #display/link

19:48 err

19:48 I do have a reader

19:48 even with the ability to send back content types from nrepl

19:48 how do you do it?

19:49 you have to replace the pr whatever nrepl middleware with an nrepl specific thing that can transform the data in to some representation and content type to send back

19:49 technomancy: hiredman: bunch of HTML with <a href="/myop?k=v">stuff</a>

19:49 ^ actually got that working at the conj

19:50 hiredman: well, yeah, that is the samething as what I said with #display/html

19:51 my plan is on the client side I'll have the tag display/html return something that can render the html has a child when given a dom node

19:51 technomancy: except you're putting it all in the :value key, yeah

19:51 hiredman: so things come off the wire knowing how to render themselves in my little document

19:56 mmg: is there a way to do this? (map quote [a b c]) = ['a 'b 'c] ?

19:57 Bronsa: mmg: if you think about it, that doesn't make sense

19:57 technomancy: mmg: only in the context of a macro

19:57 coventry: mmg: You mean pull out the symbol names and stick them in the compiled code? The dbg macro does something like that.

19:57 technomancy: in normal context [a b c] is evaluated before map gets called

19:58 coventry: Or if that's not what you mean, '[a b c] may meet your purposes.

19:58 mmg: technomancy, I am indeed trying to do this in the context of a macro, it's.... an evil anamorphic macro, I realize this isn't really the clojure way

19:59 coventry: mmg: Look at &env and &form

19:59 mmg: will do, thank you coventry

20:13 amalloy: mmg: i rather doubt that the proposed solutions are really what you want, even in the context of evil. perhaps you would get better guidance if you gave an example of how you want your macro to be used and what it would expand to

20:16 mmg: amalloy, it's a deep rabbit hole.... I've been reading Let over Lambda from Doug Hoyte and trying to recreate what he's doing in clojure

20:16 technomancy: uh oh

20:16 amalloy: blugh

20:16 mmg: ok I'll stop ;)

20:17 amalloy: most of the macros in that book are really neat for common lisp and terrible for clojure

20:17 mmg: yes but climb every mountain right?

20:17 amalloy: but you shouldn't need &env or &form for any of them that i can recall

20:17 technomancy: as an exercise, maybe. just don't subject anyone else to hoyte-inspired macros =)

20:17 mmg: it's just for fun

20:18 it's this problem (defmacro foo [x] `(* ~x ~x))

20:18 amalloy: technomancy: with-cxrs was a fun one to implement in clojure

20:18 mmg: if x is some function it evaluates twice

20:19 that's what I was trying to solve

20:19 justin_smith: mmg: the common answer there is to put a let binding in the macro

20:19 Bronsa: mmg: this is what you want: `(let [x# ~x#] (+ x# x#))

20:19 duh `(let [x# ~x] (+ x# x#))

20:19 amalloy: see how you get a much better answer when you give your actual problem rather than a partial solution you've thought up, mmg? :)

20:20 mmg: well it sounds alright for this case

20:20 but I was looking at (defmacro!....)

20:20 for the arbitrary case

20:20 so (defmacro! ) will return a quoted (defmacro...)

20:20 amalloy: mmg: defmacro! is a common-lisp solution to the problem that clojure's auto-gensyms already solve better

20:21 if you wanted to do it using only tools that hoyte has available, you could (let [m (gensym "x")] `(let [~m ~x] (* ~m ~m)))

20:22 mmg: got it, thank you

20:24 justin_smith: is it totally gauche to name my protocol in all lower case?

20:24 amalloy: yes

20:24 justin_smith: cool, glad I asked

20:24 the code works lower case, but it occured to me it may get in the way of comprehension

21:55 danneu: http://stackoverflow.com/questions/2685435/cooler-ascii-spinners

21:59 egosum: What are people using/should use to run web apps which need to do a lot of HTTP requests (and other blocking calls) on the server-side of things? http-kit? jetty with core.async?

22:00 danneu: gonna make people's jvm boot worthwhile to watch my app work

22:01 egosum: core.async is really fun to use for that

22:02 egosum: danneu: fun as in "won't make you hate yourself because you chose node for a MVP?" or another kind of fun?

22:03 justin_smith: egosum: you can make your requests parallel easily with http-async.client https://github.com/neotyk/http.async.client

22:03 or yeah, use core.async

22:04 also a smart caching layer (as apropriate) can do wonders

22:04 egosum: Yes, I was looking at http.async.client, as well as http-kit (as well as core.async). They all look very nice (though I'm leaning toward core.async). I was wondering if people might have experience (or know of posts regarding said experience) using them in production?

22:04 justin_smith: now if your requests are stateful (ruling out caching) and semantically serial (ruling out parallelization of requests) then get a server in the same data center your services in and cross your fingers ?

22:05 egosum: Caching for sure, but these are wildly dynamic requests I"ll be sending out; users will determine them

22:05 justin_smith: if only :)

22:05 justin_smith: I'm working on networked finite state machines as a server :)

22:05 service*

22:05 so they can send out requests to other APIs as you transition states

22:05 justin_smith: well core.async turns normal looking code and turns it into a fsm

22:06 egosum: essentially, they're a way to tie together existing APIs with state

22:06 justin_smith: well, if you are signing up to implement state, good luck with that :)

22:06 egosum: justin_smith: well, essenially every business application implements a finite state machine

22:07 which describes their business process

22:07 essentially*

22:08 danneu: i use https://github.com/ztellman/aleph for tcp stuff

22:08 justin_smith: from what I hear aleph has nice conceptual abstractions but isn't the choice if you have performance bottlenecks

22:09 amalloy: aleph has great performance

22:09 justin_smith: oh?

22:09 ok, I heard wrong

22:09 danneu: aleph offers great things right out of the box

22:11 justin_smith: https://github.com/ptaoussanis/clojure-web-server-benchmarks based on this chart, I would not choose aleph if I had performance bottlenecks

22:11 amalloy: TBH, the great conceptual abstractions are the hard part. after working with aleph/lamina for almost a year it basically makes sense to me, but when first starting with it the new ideas are pretty confusing

22:11 justin_smith: it could be that chart is wrong

22:13 danneu: amalloy: yeah, i agree and i'm new to it. however, i find it easier to fake it til i make it with aleph's higher level tools than the newbie issues i floundered with in core.async. like rolling my own introspection tools

22:13 justin_smith: actually the comparison of http-kit and nginx on there makes me a little skeptical - but if it is true that is awesome

22:13 bitemyapp: justin_smith: slowness is almost always in the application stack anyway.

22:13 lnostdal: egosum: http-kit has been excellent for me .. simple and to the point; does exactly what it needs (http) .. personally i prefer it to e.g. aleph

22:13 bitemyapp: justin_smith: we use http-kit, really happy with it. very low overheard. It's not magical though.

22:14 justin_smith: right, you always have to look for the weakest link performance wise

22:14 the thing that really blows my mind on that chart is how bad tomcat is

22:15 bitemyapp: justin_smith: that bit didn't surprise me at all.

22:15 justin_smith: interesting

22:15 bitemyapp: justin_smith: http://www.techempower.com/benchmarks/ in case you wanted corroboration of the http-kit numbers.

22:15 http-kit is why I keep telling people not to use fucking dynamic vars.

22:15 you can't use http-kit if you use dynamic vars. not safely.

22:16 egosum: is http-kit being actively developed?

22:17 bitemyapp: it's maintained but it's essentially done

22:17 justin_smith: bitemyapp: yeah, I remember you mentioning that about dynamic vars

22:17 bitemyapp: justin_smith: *grumble grumble*

22:17 egosum: danneu: so using core.async is pretty rough around the edges right now?

22:17 bitemyapp: pet peeve.

22:17 egosum: core.async is fine to use, there's just not a shake-n-bake way to make it the driver of your web stack.

22:17 I'm not utterly convinced it should or needs to be.

22:18 I'd use core.async + http-kit if I needed asynchronous processing in a web app.

22:18 oh cool, raw WAI is faster than http-kit. How nice.

22:18 egosum: bitemyapp: http-kit async?

22:18 justin_smith: just barely

22:19 bitemyapp: egosum: http-kit is async

22:19 justin_smith: yeah but look at yesod.

22:19 egosum: ah, the chart made me think there was a sync version as well

22:19 bitemyapp: justin_smith: Yesod does some weird fucking shit.

22:19 egosum: they're talking about their handler, not http-kit itself.

22:19 egosum: ah, got it

22:19 it almost seems too good to be true; no more callback hell?

22:19 no more promise bullshit?

22:19 lovely

22:19 justin_smith: that is what core.async is for

22:19 bitemyapp: it's not too good to be true. This sort of niceness exists in other languages too.

22:20 just not very many.

22:20 egosum: bitemyapp: I know, CSP and all. I'm mostly being dramatic; getting fed up with Node, though it's given me the opportunity to make some cool hacks and thrash the stack.

22:20 bitemyapp: The cool kids async club is basically restricted to Akka users (kinda icky), Erlang, Go, Clojure, and Haskell.

22:20 egosum: I really hated writing code for Node.js

22:20 justin_smith: egosum: you can do CSP on node, thanks to cljs :)

22:20 bitemyapp: it was less productive than Python

22:20 egosum: bitemyapp: it was fun for a bit, but yes, i found python more productive

22:20 bitemyapp: Golang was less productive than Python too.

22:21 Clojure was faster *and* more productive than Python.

22:21 egosum: I was writing node code entirely functionally, as much as possible anyway

22:21 Clojure is the most productive I've been

22:22 justin_smith: yes, clojure is definitely a high-developer-productivity language

22:23 especially once you figure out the workflows / concepts that match its impedence

22:23 (so to speak)

22:38 uvtc: Is there any way to copy a file out of a project's resources directory? Or can you only read files from there (and write them out if necessary)? Currently, I see that I can do:

22:39 `(let [content (slurp (io/resource "the-file.whatev"))]`, then `(spit "the-file.whatev" content)`.

22:39 justin_smith: (spit "/path/to/dest" (slurp (io/resource "relative/path/to/resource"))) maybe?

22:39 bitemyapp: uvtc: you can read the contents of resources into memory or stream it out somewhere else.

22:39 spit/slurp will load the whole thing into memory

22:39 justin_smith: true

22:39 uvtc: Right. Ok. Thanks. For my case, it's a small file, so slurp/spit is fine. Thanks for the info.

22:40 bitemyapp: justin_smith: probably one of the major changes I've made in the last year of programming professionally is I default to laziness/streaming/async-safety by default more often.

22:40 it's made my stuff more reliable ^_^

22:40 justin_smith: cool, I am gradually going that way

22:40 bitemyapp: well, I default when it's a production thingy

22:41 obviously I don't care when it's a one-off script.

22:41 justin_smith: I changed our image resizer so it can resize from the asset bucket to the asset bucket - next step is doing it without needing the whole thing to be in ram

22:41 bitemyapp: ahhh always the tricky part :)

22:41 uvtc: bitemyapp, so, just curious, how would I do it lazily? If I just wanted some lines, with possibly needing more (up to the end of the input file)?

22:41 bitemyapp: uvtc: most people just use the vanilla Java streaming interfaces.

22:41 same stuff you use for Files, Sockets, etc.

22:42 justin_smith: would io/copy do it without the whole thing in ram?

22:42 bitemyapp: but don't do this if you don't need to.

22:42 justin_smith: depends on the type of the input.

22:42 uvtc: Hm. Not something with line-seq?

22:42 bitemyapp: justin_smith: https://github.com/richhickey/clojure/blob/8c9b0574a83f6c77576325b724c837cf4143eb33/src/clj/clojure/java/io.clj#L368

22:42 amalloy: slurp/spit isn't a good idea for binary files

22:43 nothing that converts to strings is, so that rules out line-seq too

22:43 justin_smith: true enough

22:43 amalloy: just use streams and io/copy or something

22:43 bitemyapp: I've abused base64 way too much for this.

22:43 uvtc: io/copy will do what you want as long as you pass it the Stream, not a string.

22:43 or the File handle

22:44 uvtc: bitemyapp, Ok. Trying io/copy, since that seems to be closer to what I want.

22:44 bitemyapp, thanks.

22:48 Oh. Nice. This worked: `(io/copy (io/file (io/resource "my-file.whatev")) (io/file "my-file.whatev"))`

22:48 justin_smith: that (io/file (io/resource)) part will fail if you deploy in a jar

22:48 try io/input-stream instead of io/file

22:49 bitemyapp: uvtc: the concept of a "file" is loosey-goosey in a jar.

22:50 justin_smith: bitemyapp: IllegalArgumentException Not a file: jar:file:/media/justin/806084F16084EEEA/m2/repository/clojure-complete/clojure-complete/0.2.3/clojure-complete-0.2.3.jar!/project.clj clojure.java.io/fn--8522 (io.clj:67)

22:50 uvtc: bitemyapp, works. Thanks.

22:51 bitemyapp, (works when the app is uberjar'd too. :) )

22:51 justin_smith: it's not loosey-goosey in a jar, it just plain doesn't work

22:52 uvtc: justin_smith, thanks for the help.

22:53 justin_smith: np

23:06 bellkev: justin_smith: If you have a second, I'd love to get your opinion on this topic: https://groups.google.com/forum/#!topic/clojure/BNIdWCehEAI That's the project that was the source of my various newbie questions the other day...

23:06 Someone on that thread pointed out an interesting library, prismatic/schema, for doing validation-ish stuff

23:07 It looks pretty cool, though it kind of reminds me of JAXB with its abundance of classes...

23:19 sm0ke: isnt someone rewriting emacs in clojure

23:19 would be very cool

23:23 echo-area: Hi sm0ke :)

23:23 sm0ke: heh hello

23:24 justin_smith: hey bellkev

23:25 echo-area: sm0ke: I think you meant this: https://github.com/hraberg/deuce

23:25 bellkev: hey

23:26 sm0ke: echo-area: nice

23:26 but i think the dev has given up already

23:27 justin_smith: sm0ke: there are many rewrite-emacs-in-better-language projects

23:27 common lisp, haskell, scheme, and now I guess clojure

23:27 nightfly: lets write emacs in bash!

23:27 sm0ke: emacs in viml?

23:28 hahah insane

23:28 justin_smith: sm0ke: only if you get enough compatibility to make evil mode work

23:28 Apage43: https://github.com/tpope/vim-rsi gives you some of the keybinds ;)

23:30 sm0ke: hmm the problem with vim is its customizable by a a chosen few

23:30 justin_smith: bellkev: my opinion of macros is that they should only be used when needing a macro to leverage it is an acceptable cost

23:31 with functions, you can easily compose them with other functions - with many macros that breaks down

23:31 so if your tool will be utilized by or in conjunction with other tools, relying on macros can cause frustration

23:31 Raynes: sm0ke: Or anyone who takes a few hours to learn just enough to write a Python plugin to do what they want :P

23:32 bellkev: Yeah, that's what I've gathered to be the prevailing opinion in the community

23:33 I think for sure my approach will do all the heavy lifting with plain functions/values, but I think it would be nice to have a way to tie the whole thing (for a "template") into one "package"

23:34 justin_smith: deftemplate would be OK if it is just a thin wrapper on (def X (make-template ...)) and make-template accepts a reasonable data structure

23:34 sm0ke: Raynes: i dont think its that easy, vim scripting is doomed like pythons GIL. And both together are match made in hell.

23:35 bellkev: Like, in the latest revision of the gist (https://gist.github.com/bellkev/7653342) the middle section, which is all values and functions, I feel like it's a trillion times more readable/writable than standard JSON CloudFormation templates

23:35 Raynes: sm0ke: Well I did it.

23:35 sm0ke: https://github.com/Raynes/refheap.vim

23:35 bellkev: However, I really like the idea of packaging things in one "deftemplate"

23:36 The thing I'm wrestling with right now is basically, is it okay to have nested defs (or lets) inside my macro, so that vars/symbols introduced in part of the macro body can be used elsewhere...

23:36 sm0ke: Raynes: may be you are the chosen one :D

23:37 may be i should look into viml once more

23:38 bellkev: For example, in the ns macro, if you introduce a namespace with a :require directive, it's available later in a :use directive

23:39 That's the kind of behavior I'm going for, but I know that ns is kind of special and that :use is deprecated...

23:39 justin_smith: bellkev: in the normal ns macro they are totally independent of one another - or am I missing what you are saying?

23:39 amalloy: i think he's just confused about how ns works

23:41 bellkev: Maybe I am confused by how ns works.... I thought that you could only :use something if it was already in a :require, but that's not the best analogy anyway... I believe this slide: http://www.slideshare.net/cgrand/dsl-5537797/21 from a conj talk really gets at what I'm wondering about

23:41 That slide, and the slide after it, seem to address the pros/cons of introducing new variables or manipulating symbols in macros, but I'd like to see more discussion of that same topic...

23:42 justin_smith: he is showing a pattern for farming out most of the macro to functions

23:43 one function that extracts the bound names, the other extracts their values

23:44 seeing keywords instead of symbols is confusing in the final part of your gist - keywords are meant to be self-evaluating (stand for themselves)

23:45 bellkev: Okay, I get that part. I guess what I'm wondering is, what kind of syntax is it acceptable to use to introduce new lexically scoped variables into your macro?

23:45 justin_smith: well, macros are for when you need a new syntax, so that is really a question that depends on your domain

23:45 bellkev: Okay, I was wondering about the keyword thing too... I stole the idea from here: http://www.slideshare.net/cgrand/dsl-5537797/39

23:46 justin_smith: that is showing how you can avoid using a macro

23:46 since that is already a valid clojure data literal

23:46 and nothing needs escaping

23:47 but if you need to bind things, don't use a keyword for the target of the binding

23:48 bellkev: Okay, that all makes sense, let me whip up one more example to make one more point

23:51 amalloy: bellkev: if you're looking for examples, https://github.com/flatland/useful/blob/develop/src/flatland/useful/seq.clj#L108 is probably the only justifiable anaphoric macro i've written in my clojure career

23:52 i'm not following the discussion closely, so this may not be entirely relevant

23:53 bellkev: Here's an attempt to clarify, what kind of syntax should be used if I DO want to bind new symbols within the body of my macro? https://gist.github.com/bellkev/7670855

23:54 But thanks, amalloy, I'll check out that link

23:55 justin_smith: bellkev: that is definitely more readable - I can differentiate keywords that stand fora themselves from bindings that refer to some prior definition

23:55 bellkev: The thing with this macro I'm working on, is that it's used to generate data (JSON), but that data represents a kind of mini-program that executes in the context of an AWS CloudFormation stack, with an order of execution, inputs/outputs, some scope rules, etc

23:57 justin_smith: bellkev: if you let bindings sit outside the defining form, that could just be a long let statement

23:57 ie. (mapping my-mapping :first-level-key-one ...) -> my-mapping (mapping :first-level-key-one ...)

23:58 and that could be the clue to the function that helps you implement the macro

23:59 but imho being able to specify the bound thing inside the form defining it has very low utility compared to the overhead of remembering to read it that way

23:59 unless of course we are replicating something in the domain that makes it clearer

Logging service provided by n01se.net