#clojure log - Jun 13 2013

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

0:27 technomancy: Raynes: curious, could you do that with pdo and lein run?

0:28 point-free lein, man. it's the wave of the future.

0:29 Raynes: technomancy: Could I do what?

0:30 Prism?

0:30 technomancy: I'm not sure how I'd combine those two things to do this. Could you elaborate your idea?

0:42 jeremyheiler: Are there any examples of a library sharing code between Clojure and ClojureScript? (Unless doing that is dumb and I shouldn't worry about it.)

0:44 sinistersnare: jeremyheiler: what would be a use case for that?

0:47 jeremyheiler: I'm writing a library for App.net and I would love to share the namespace that contains the ~100 functions for hitting each endpoint. All that code is very generic, and every function calls an internal "request" function that deals with the details; which is clj-http and cheshire for Clojure.

0:48 malyn: jeremyheiler: I haven't used it (yet), but lein-cljsbuild has a feature called "crossovers" that lets you share code between Clojure and ClojureScript. https://github.com/emezeske/lein-cljsbuild/blob/0.3.2/doc/CROSSOVERS.md

0:51 tomjack: jeremyheiler: I heard solving that problem is a priority for 1.6

0:51 clojure 1.6 I mean

0:51 jeremyheiler: malyn: that looks promising.

0:51 tomjack: do you know any of the details?

0:52 tomjack: nope. but I'm guessing it involves 'feature expressions' or some derivative of that idea

0:52 jeremyheiler: That would be great.

0:53 tomjack: pedestal has shared code somehow that is not as much of a terrible hack as crossovers

0:53 but crossovers actually works I guess :)

0:54 also https://github.com/lynaghk/cljx may be worth looking at

0:54 seancorfield: that will be a really nice problem to see solved!

0:57 jeremyheiler: cljx looks cool, but is probably overkill for my use case.

0:59 tomjack: I assume data readers aren't capable of implementing feature expressions already?

1:00 jeremyheiler: I'm reading about it here: http://dev.clojure.org/display/design/Feature+Expressions

1:02 tomjack: #host {:clj :require :cljs :require-macros} ?

1:02 can't do #_ though

1:02 which may be a good thing imo..

4:58 jamii: technomancy: The repl is working now - https://github.com/jamii/lein-gnome

5:23 clgv: if I do (require '[quil.core :as q]) in my namespace shouldnt (defn bla [x] (q/fill ...)) compile cleanly?

5:24 I am trying to work around a HeadlessException when running the code on a server where I will not use th GUI parts

5:27 tomjack: clgv: are you using defsketch?

5:28 clgv: tomjack: no

5:28 I use "a/applet" directly

5:28 loading the namespaces throws the exception thus I wanted to wrap it in a try-catch

5:29 tomjack: I see, tricky

5:30 looks like processing initialization causes it?

5:31 and then you can't compile that defn unless you catch and alias some other fake ns with dummy vars...?

5:31 :(

5:32 clgv: the problem is that I cannot use (require '[quil.core :as q]) as alternative to the entry in the namespace declaration

5:32 even on my dev machine it says "No such namespace: q"

5:34 tomjack: weird, works here

5:35 but it won't help anyway I don't think

5:36 if you managed to catch the exception I predict you'd then get "no such var" troubles

5:36 er, or "no such namespace"?

5:38 https://www.refheap.com/b43b579e3f97b9fa495c775bd

5:38 yeah this gives me "no such namespace: q"

5:38 my advice I guess is to put the gui stuff in a separate namespace..?

5:41 asaleh: I have problem \w logging in my command lina app and uberjar

5:41 when I do "lein run --opts --more-opts --etc" it runs fine

5:43 but when I do "lein uberjar; java -jar my-app-0.1.jar --opts --more-opts --etc" it fails on java.lang.ClassNotFoundException: clojure.tools.logging.impl.LoggerFactory

5:43 any hints?

5:46 tomjack: that does not look like the name of an uberjar

5:46 vijaykiran: asaleh: look for *-STANDALONE-* jar

5:46 asaleh: tomjack, that is just an example :)

5:47 vijaykiran: asaleh: :) can you paste the project.clj ?

5:47 asaleh: tomjack, vijaykiran in reality I am runnin java -jar tcms-upload-0.1.2-SNAPSHOT-standalone.jar --dry-run --username asaleh --password ****** --xml-result /home/asaleh/clean-room/tcms-upload/testng-results.xml --plan 9032 --build-name new-build --manager-login asaleh --summary test26

5:48 tomjack: apparently clojure.tools.logging is not in that jar..

5:48 asaleh: tomjack, vijaykiran https://github.com/AdamSaleh/tcms-upload/blob/master/project.clj

5:48 bordatoue: could someone help, I would like to know if there is any way to automatically compile the local .java files and load then to nrepl on making changes to the local .java files from emacs

5:48 tomjack: odd

5:49 did you already look in the jar?

5:49 asaleh: tomjack, I didn't look, I just thought when I see tools.logging-0.2.6.jar in lib/ it should be in standalone jar as well

5:50 tomjack: lib/? you should upgrade lein :)

5:50 vijaykiran: asaleh: the jar on your github seems to have the class

5:51 asaleh: vijaykiran, yep, I know, but problem starts when I try to recompile

5:54 vijaykiran: asaleh: odd - I get SEVERE: testng-results.xml (No such file or directory)

5:54 asaleh: no exception

5:55 asaleh: vijaykiran, tomjack I found some difference ... the jar-file I have recompiled has only impl.clj in /clojure/tools/logging/ ... jar on github has folder /clojure/tools/logging/impl/ and Logger.class and LoggerFactory.class

5:58 vijaykiran: asaleh: how are you generating the jar ? which version of lein are you on ?

5:58 asaleh: still Leiningen 1.7.1

5:59 vijaykiran: bordatoue: I'm not aware of hot-reloading java files - may be you can try JRebel ?

5:59 tomjack: like I said.. upgrade

5:59 asaleh: vijaykiran, lein deps;lein compile; lein uberjar

6:00 vijaykiran: asaleh: upgrade is your best bet - I'm using 2.2.0

6:00 tomjack: have you tried `lein clean`? always worth trying when you're having trouble

6:00 asaleh: tomjack, but I need to have 1.7.1 :) ... can I have them side-by side?

6:00 bordatoue: vijaykiran: thanks

6:01 tomjack: when I switched over I just put it at ~/bin/lein2

6:01 I think that should still work fine

6:01 asaleh: ok, will try

6:02 tomjack: (fwiw confirmed the uberjar from your master contains LoggerFactory on my lein 2.2.0 as well)

6:03 asaleh: ok, gave it a last try with rm -Rf tcms-upload;git clone git@github.com:AdamSaleh/tcms-upload.git; cd tcms-upload;lein clean;lein deps;lein compile;lein uberjar ...

6:03 tomjack: strange problem though, were there even any AOT bugs back then that have been fixed?

6:04 asaleh: and java -jar tcms-upload-0.1.2-SNAPSHOT-standalone.jar still throws exception

6:04 tomjack: did you make any local changes not in git?

6:05 asaleh: tomjack, just tried the clean clone and compile :)

6:05 tomjack: then yeah, I'd say try lein2.. bizarre

6:11 pyrtsa: Silly thought: would it be possible to wrap `lein repl` to run all lines inside a (-> ...) macro?

6:12 E.g. to get documentation about something, I could just append ` doc` to whatever I had written first. Or play with postfix in general.

6:12 asaleh: tomjack, vijaykiran thanks, lein2 solved it :D

6:12 tomjack: weird, I skimmed the changelog for 'AOT' and didn't see anything relevant

6:22 clgv: tomjack: yeah I guess the refactoring is the only choice here

6:23 tomjack: you mean lein 2.1 changes?

6:29 tomjack: I just searched for 'aot' in everything since 1.7.1

6:30 clgv: theoretically you could take ns-publics from quil.core and create a dummy ns to require in the catch, I think

6:30 but that would be kinda nuts

6:44 ucb: ,(inc 2)

6:44 clojurebot: 3

6:50 mikerod: ##(inc 2)

6:50 lazybot: ⇒ 3

6:50 mikerod: Maybe this is a dumb question, but what is the difference between clojurebot and lazybot ?

6:53 tomjack: they are different bots, different code

6:53 many many specific differences

6:58 rbarraud_: Is there a FAQ on either or both u can give URL for?

6:58 tomjack: $google clojurebot

6:58 lazybot: [hiredman/clojurebot · GitHub] https://github.com/hiredman/clojurebot

6:58 tomjack: $google lazybot

6:58 lazybot: [flatland/lazybot · GitHub] https://github.com/flatland/lazybot

6:58 tomjack: that's about it afaik

6:59 rbarraud_: Excellent... Thanx tomjack

7:09 fsmunoz: Greeting!

7:09 Quick help: I'm trying to "translate" this: ((OracleStatement)stmt).setDatabaseChangeRegistration(dcr);

7:09 And given my lack of Java knowledge I find the ((OracleStatement)stmt)... intriguing.

7:09 Looks like some sort of cast

7:09 augustl: fsmunoz: that's a cast, you don't really need it in Clojure since it's dynamic

7:10 you could annotate smtm to be an OracleStatement to avoid reflection though, if it's a call you do a gazillion times all the time :)

7:10 stmt*

7:10 fsmunoz: augustl: ty, so my translation is likely correct: (.setDatabaseChangeRegistration stmt dcr)

7:10 augustl: yeah

7:11 fsmunoz: Great mate, thank you. I was not getting the cast since stmt is a Statement, but now talking with you I remembered that not everything is dynamic :)

7:17 mikerod: Thanks for the info!

7:35 augustl: fsmunoz: hmm, you might actually have to cast it though, to dispatch the correct method.. ;)

7:35 fsmunoz: so, (.setDatabaseChangeRegistration (cast OracleStatement stmt) dcr)

7:38 noncom: hi! if i get an exception in a future, there is no output of the exception to the console, it just silently hangs the future. is this ok?

7:39 augustl: if you dereference the future, the exception is thrown in the calling thread

7:40 noncom: i see, so if i never deref it, i never get an exception?

7:40 augustl: this is an attribute of threads, not futures

7:40 noncom: cool! thanks, now i know it

7:40 augustl: ^^

7:44 fsmunoz: augustl: ty!

7:54 mikerod: ,(+)

7:54 clojurebot: 0

8:14 deg: In a clojurescript app, I need to serialize some data in/out of browser local storage, including maps and vectors. It looks like I need to call js->clj and clj->js, but I'm not 100% clear about why; I thought cljs used the underlying js data structures.

8:15 Well, not quite true. I understand that cljs uses clj-style lazy data structures. But, I had thought that all the necessary conversions happened behind the curtains, and I would not have to think about them.

8:17 noncom: ,(-)

8:17 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core$->

8:18 noncom: ,(+)

8:18 clojurebot: 0

8:18 noncom: ,(*)

8:18 clojurebot: 1

8:18 noncom: ,(/)

8:18 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core$-SLASH->

8:18 noncom: ,(or)

8:18 clojurebot: nil

8:21 deg: (TEST - does anyone see this? Just checking because I've gotten zero replies to any queries here the past few weeks. Checking that my IRC is working)

8:21 ,(print "hello world")

8:21 clojurebot: hello world

8:25 clgv: ,(print "hello deg")

8:25 clojurebot: hello deg

8:25 augustl: deg: are you sure clj->js works? toString of a js object is probably as bad of toString on a js object that represents a clj value :)

8:32 deg: august1: I'm serializing the string from clj data. But, the data comes from the dom, and I seem to need to js->clj it before I serialize it out.

8:32 Otherwise, it writes objects like #<array ....

8:32 augustl: perhaps cljs data structures has a better .toString than the JS ones

8:33 serialization of JS data structures (objects or arrays) are typically done with JSON.stringify, not toString

8:33 deg: Does JSON.stringify also do the "right thing" for clj data?

8:34 augustl: I would imagine not, clj data structures contains metadata etc.

8:34 what exactly are you putting into localstorage? Dom elements?

8:34 (ref "the data comes from the dom")

8:35 deg: For my purposes, metadata is not relevant. I'm just trying to persist arrays and maps that are mostly in the dom, but that I also manipulate in my cljs code.

8:35 augustl: (that's parenthesis in english, not a clojure snippet :))

8:35 deg: It feels like I must be doing something wrong; I'm thinking too hard about what should be a simple case.

8:35 Yes, data comes from the dom.

8:35 augustl: well, putting DOM objects in localstorage is certainly wrong, so I don't hope that's what you're doing :)

8:35 s/DOM objects/DOM elements/

8:36 deg: Not dom elements themselves. Just values in controls.

8:36 augustl: so it's just strings?

8:36 I can't think of DOM APIs that yields something other than strings or numbers..

8:36 deg: Most were simple strings, but I get an array/vector from some of the more complex controls.

8:37 Like a selection box.

8:37 augustl: are you talking about code that traverses the dom and builds a data structure from that?

8:38 deg: I'm moving towards that. But, right now, my code is even simpler. I have a form, and I want to save the user-entered data when I move to a different page.

8:39 augustl: so essentially you have a JS data structure, the fact that the source of it is the DOM isn't really relevant?

8:39 deg: Yes, I suppose so

8:39 I'm coming from the clojure world. JS and DOM are equally new to me, so I've conflated concepts.

8:39 augustl: I've never used cljs.. But I would imagine it's more convenient to build a cljs data structure instead of a js data structure

8:40 and in the cases where you build js data structures, you make sure that what your function actually returns is a cljs data structure

8:40 local mutation, etc ;)

8:41 deg: The structures I'm building are all cljs; at least that was my intention. But (using hiccups library) askig the DOM for the value of a control, I get back what seems to be a js array.

8:41 augustl: David Nolen recently blogged about just that - a function that internally builds up a data structure with raw mutable JS objects, and returns a cljs immutable value

8:42 deg: I'd be very careful about passing js data around, since it's mutable

8:42 deg: Sounds relevant. I'll search for that blog entry (or do you happen to still have the link?)

8:42 augustl: and whenever you encounter js data, turn it into cljs values

8:42 deg: http://swannodette.github.io/2013/06/10/porting-notchs-minecraft-demo-to-clojurescript/

8:42 deg: specifically, the gist under "Local mutation"

8:43 deg: thanks. I'll read that in a second. But, sounds like I'm probably doing the right thing -- explicitly converting js data to cljs as soon as I see it. But, I was just surprised that this doesn't happen automatically and under the covers.

8:44 augustl: deg: this is similar to the interop story for clojure on the jvm - if you call something that returns js data, you'll get js data

8:44 hopefully people are careful with it, though, so you only get js data when you use very specific functions or do interop

8:45 the question then becomes how to turn cljs values into a string you can put in local storage. I would guess cljs has this built-in

8:46 deg: Makes sense. I've not done any significant interop in clojure either. I'll just wrap the library calls. I guess, though, I'll digress and read the hiccups source, to understand why it doesn't already do so.

8:46 I assume there is some efficiency concern, i.e. some common case where the data is passed right back to js.

8:46 Anyway, thanks for your help. I think I'm on the right path now.

8:47 augustl: deg: np ^^

8:47 how can hiccup be related to this, though? Doesn't hiccup only turn clojure data into HTML strings?

8:49 deg: Right. I read the wrong line from ns requires at the top of my file. I meant domina.

8:49 (Again, conflating too many new concepts together. Now that my code is working, taking the time to understand all the code I copied).

8:50 augustl: :)

8:50 does sound a bit weird that domina doesn't always return immutable values

8:50 the dom is inherently mutable, though, so if domina returns a DOM object, well..

8:51 deg: Right. That's where I had the feeling I was doing something wrong. Time for me to read the source and learn what domina is really doing.

8:51 No rest for the innocent.

8:51 augustl: deg: there are some ways of dealing with that, such as RFP, and other things, which basically lets you work with an immutable data structure and treats the mutable DOM as I/O

8:52 deg: RFP is what? (I know if I google it i'll hit a million Request For Proposal pages :-) )

8:52 augustl: reactive functional programming

8:52 deg: thx

8:52 augustl: oh, it's FRP. Functional reactive programming

8:53 piranha_: it's FRP

8:53 :)

9:12 deg: Would I be over-simplifying to say that FRP is basically modern constraint propagation?

9:27 jcromartie: OK so, let's talk about clojurescript output

9:28 my hello-world .cljs results in 800KB of JavaScript in the "out" directory

9:31 maleghast: jcromartie: Yeah, that's not optimal, huh?

9:31 jcromartie: I didn't delete "out" before passing {:optimizations :advanced}

9:31 but after doing that, it's 676K in out

9:32 I know most of this is boilerplate cljs/closure stuff

9:33 maleghast: jcromartie: Hmmm… Still not great… Aren't you supposed to use Closure, after the CLJS to JS transformation, to 'improve' the resulting Javascript.

9:33 jcromartie: maybe? I thought that it included Closure optimization

9:33 maleghast: Hey, I'm guessing here - I've not gotten around to playing with CLJS at all yet :-)

9:35 BobSchack: Take a look here https://github.com/magomimmo/modern-cljs

9:36 tutorial 7 should have the optimizations you're looking for

9:37 jcromartie: "modern" cljs :)

9:37 as if a bleeding-edge language weren't modern enough

9:38 (I get the reference)

9:38 hyPiRion: hah, I never realized this

9:38 ,(let [v (vec {:a 1, :b 2, :c 3, :e 4})] [(keys v) (vals v)])

9:39 clojurebot: [(:a :c :b :e) (1 3 2 4)]

9:39 hyPiRion: ,(let [s (set {:a 1, :b 2, :c 3, :e 4})] [(keys s) (vals s)])

9:39 clojurebot: [(:e :b :c :a) (4 2 3 1)]

9:40 hyPiRion: oh, clojure, you keep surprising me from time to time.

9:40 jcromartie: ah ha, you can emit a single JS file, optimized and minified, at 13K with gzip

9:40 not too bad for a baseline

9:40 maleghast: jcromartie: You have just persuaded me that I want to know about CLJS, so thanks for that :_)

9:40 jcromartie: maleghast: I'm persuading myself as I go along

9:41 maleghast: I think it would be a boon for HTML game/interactive type dev

9:41 maleghast: Fairy snuff ;-)

9:41 jcromartie: I prefer Lisp over Coffeescript's rather syntaxy-syntax

9:41 i.e. Coffeescript has lots of rules about whitespace and colons and whatnot

9:42 maleghast: I am getting quite excited about Pedestal, but again, I need time to __actually__ try it out - there's only so much you can learn / judge from just reading about something

9:43 BobSchack: jjcromartie: chris granger has a nice post about writing a game in clojurescript here http://www.chris-granger.com/2012/12/11/anatomy-of-a-knockout/

9:44 mucker: I find myself abusing the -> macro. How do I get past the inside out evaluation of lisp ? In ruby I would have a bunch of foo = expr ...

9:45 hyPiRion: mucker: Hmm. using `let` works, but the best trick is to just get more familiar with functional programming

9:46 and with lisp, of course. With time, you end up being more immutable and the inside out evaluation is rarely a problem (at least in Clojure)

9:47 mucker: hyPiRion I can't use let freely, can I ? It needs to be (let (bindings) expr) I just want to say ((let foo bar) (+ foo bar))

9:49 hyPiRion: mucker: well, (let [foo 1, bar 2] (+ foo bar)) is easier to write than (do (let [foo 1, bar 2]) (+ foo bar)), isn't it?

9:50 I understand your concern, and really, the best way to "get used" to it is by experience and practise. At least that's what I think

9:50 jcromartie: w00t, success

9:50 I want to at least understand how to use the CLJS compiler before using lein-cljsbuild

9:51 mucker: hyPiRion: yup :)

10:16 jweiss: how long have multiline strings with """ delimiters been available? Could have sworn that didn't exist before

10:17 or maybe it doesn't exist but it's shown here http://adambard.com/blog/clojure-batteries-included/

10:17 Bronsa: yeah, they don't.

10:19 clgv: jweiss: no there is no special multiline string - but string literals can span multiple lines by default

10:19 hyPiRion: huh, never seen that before

10:19 augustl: jweiss: single quote strings can be multi-line

10:19 arcatan: """foo""" is like "" "foo" ""

10:20 so I guess the docstring in there will be "", but otherwise it works :P

10:21 oh right, he has un-escaped "s, so it won't work anyway.

10:22 tranceholic: hi, im new here, could i ask a question?

10:22 girl: shopping site verry chaeap and quick go .

10:22 hi

10:22 this is a good site of shoping

10:22 http://team-browser.com/

10:22 card visa maser .... all

10:22 enjoy

10:22 i have buy iphone 5

10:22 good by

10:22 maleghast: tranceholic: Sure - go for it

10:22 tranceholic: my `lein repl` hangs at the root directory of a project, but does not outside the project. Why?

10:25 maleghast: tranceholic: That's quite odd… What version of Leiningen are you using?

10:26 Anderkent: tranceholic: it might be trying to compile your main namespace and hanging on that, or maybe you have some weird injections?

10:28 murtaza52: What does this form mean - #_(dev/start) - (dev/start) is a call in a specific ns, however whats #_ for ?

10:28 Anderkent: murtaza52: #_ is a way of commenting out a form

10:28 tranceholic: my lein is 2.2.0

10:29 murtaza52: Anderkent: Thanks, and all this while I was wondering why it wa snot executing :)

10:32 simon_: Hello! Im new to clojure and have a question about memoize, it seems like it doesnt work for me.

10:32 http://pastebin.com/djd94092

10:33 (status-page "rbx") takes a couple of seconds to return.

10:33 The next time i run (status-page "rbx") i would expect it to return instantly, but it takes as long as the first time I called it.

10:33 maleghast: tranceholic: Can you paste your project.clj here -> refheap.com and paste the URL in here, please?

10:34 tranceholic: please wait a minute...

10:34 jweiss: simon_: looks right to me

10:34 jcromartie: simon_: works fine for me

10:35 XPherior: I think my Java interop knowledge is failing me here. I have the class shown there, and want to access the _Fields enum on line 39. https://gist.github.com/MichaelDrogalis/ca1bd4629221b9c16ee1

10:35 jcromartie: simon_: are you sure you're calling the status-page you think you are?

10:35 XPherior: Shouldn't it be (DataUnit/_Fields) ?

10:35 Anderkent: XPherior: it's a class, not a field. DataUnit$_Fields

10:35 jcromartie: simon_: i.e. are you in a REPL and perhaps haven't reloaded the namespace where status-page was originally defined with a non-memoized version?

10:35 XPherior: Anderkent: Ahhh, I forgot about that!

10:35 Thanks a million Anderkent :)

10:35 simon_: Just killed my repl and tried again, same result.

10:36 its nrepl. Ill try with the lein repl.

10:36 tranceholic: https://www.refheap.com/15741

10:36 jcromartie: simon_: hm, yeah, it works fine with lein repl here

10:36 XPherior: Huh, Anderkent. That's actually giving me unable to resolve symbol.

10:37 simon_: Yeah, in lein repl it seems to work, but not in the emacs one, maybe its just slow in emacs.. :)

10:37 Thanks guys.

10:37 And gals

10:38 tranceholic: `lein uberjar` worked fine and got a working standalone jar, FYI

10:38 maleghast: tranceholic: Hmmm, I just used your paste to create a quick test project and the repl launches perfectly fine for me...

10:39 XPherior: Nevermind, forgot the qualified namespace. Thanks!

10:40 tranceholic: thank you for your time, maleghast

10:43 maleghast: tranceholic: No problem - sorry to not be more help… What OS / platform are you on?

10:45 tranceholic: im on WindowsXP sp3 ; Cygwin; JDK1.7.0_21

10:48 maleghast: tranceholic: Hmmm… Should be ok… And you can run your app with lein, just not run a REPL?

10:51 tranceholic: right, `lein run` worked on the app, but simply `lein repl` hangs on the same root directory of the app's project...

10:51 maleghast: tranceholic: So you are running "lein repl" in the same directory as project.clj?

10:52 tranceholic: yes

10:52 maleghast: I figured, but worth asking, just in case...

10:53 tranceholic: according to lein tutorial, `repl` can run from anywhere...

10:53 Anderkent: lein repl does do different things in a project than outside, so it's possible there's a path that makes it go wrong

10:53 tranceholic: if you clear your ~/.lein and create a new empty project, does lein repl run?

10:54 Guest44310: hi. i'm using vectors a lot, because some datastructures I need have to have a good random access time. But every time I map a vector I get a list in return. Why is that? Why can't I just can get the datatype back I throw at the map?

10:54 Anderkent: if not, that's a lein bug. If it does, then it's something related to your profile/project config

10:55 tranceholic: what do you mean by `clear ~./lein`? `rm -r ./lein` ?

10:58 Anderkent: tranceholic: do you have anything in your user profile in %USERPROFILE%\.lein ?

10:58 IamDrowsy: Guest44310: because map takes any seq and returns a lazy seq. its implemented on top of seqs and not vectors. in the vector case you can use mapv

10:59 Guest44310: ah thanks. I didn't know about mapv

11:00 ToxicFrog: Guest44310: map is lazy, and there's no lazy vector type. So you have to- yes, what, IamDrowsy said.

11:01 tranceholic: sorry, i dont know how to get SERPROFILE%\.lein

11:02 Anderkent: tranceholic: just type %USERPROFILE% in explorer address bar

11:02 then find the lein directory

11:02 but well

11:02 if you didn't edit it

11:02 there won't be anything there

11:02 so just try creating a new lein project with lein new, go into it and see if repl works

11:03 if not, report a bug at github.com/technomancy/leiningen

11:05 ArseneRei: I'm trying to understand -> (trush) w/ vectors, but I can't see the write way to re-write these filters as a trush list. https://gist.github.com/arsenerei/5774391

11:05 dobladez: is there a way to automatically activate a lein profile based on the OS type?

11:05 tomjack: so yeah jeanniki's point on clojure-dev is.. interesting https://www.refheap.com/95b2b6be8fcacf98bce152765

11:06 tranceholic: now i typed `SRPROFILE% on explorer address bar, but no lein directory can be seen

11:06 dobladez: like maven's <profile><activation><os> ... ?

11:07 tranceholic: and `.m2` folder found

11:07 tomjack: ArseneRei: use ->>

11:08 ->> is for stuff like filter where the threaded operand comes last

11:08 ArseneRei: Hrm…why did I think it was first.

11:10 tomjack: Ah…yes, I get what you're saying. Makes perfect sense. Thanks so much!

11:10 john2x: can someone point me to a good api wrapper library written in clojure? i'd like to study it..

11:13 tranceholic: at a new project directory i just created, my `lein repl` still hangs, so it might be a bug, thank you very much folks.

11:16 futile: Good morning.

11:17 devn: https://github.com/tailrecursion/presioke

11:17 There are so many things that are cool about that. ^

11:19 This (https://github.com/tailrecursion/presioke/blob/2215b16d9add5aeb6e06a329428ad5f3636cbe24/src/html/index.html) is the same as this (https://github.com/tailrecursion/presioke/blob/master/src/html/index.cljs)

11:19 let that sink in for a minute

11:21 noncom: can an imported function know from which was it called?

11:21 *it is called

11:22 like i want to configure a library, imported in many namespaces to understand where from it is called

11:23 so in a namespace i call like (library/configure :my-name) and then when i call fnuctions in that library, it adds that :my-name to the call

11:24 so i could, for example, have a different textual output, depending on from which namespace is it called

11:24 ???

11:24 lazybot: noncom: How could that be wrong?

11:37 TimMc: noncom: Clojure doesn't have built-in namespace "instancing", but I've seen a project that gives you something like that...

11:40 amalloy_: Am I correct in recalling that you have a lib that allows one to require the same namespace several times under different names?

11:41 tomjack: devn: wow. hoplon looks crazy

11:41 hyPiRion: ,(let [f #(println *ns*)] (f) (in-ns 'clojure.core) (f))

11:41 clojurebot: #<Namespace sandbox>\n#<Namespace clojure.core>\n

11:41 hyPiRion: ?

11:42 tomjack: TimMc: what do you mean?

11:42 ,(do (require '[clojure.core :as core1] '[clojure.core :as core2]) [core1/+ core2/+])

11:42 clojurebot: [#<core$_PLUS_ clojure.core$_PLUS_@61022c> #<core$_PLUS_ clojure.core$_PLUS_@61022c>]

11:43 tomjack: oh I guess that's only require'd once but aliased twice?

11:43 hyPiRion: tomjack: yeah

11:44 ,(do (require '[clojure.core :as c1 :as c2]) [c1/+ c2/+])

11:44 clojurebot: #<CompilerException java.lang.RuntimeException: No such namespace: c1, compiling:(NO_SOURCE_PATH:0:0)>

11:44 hyPiRion: hrmf.

11:46 TimMc: tomjack: The lib I'm thinking of probably does some very naughty stuff to accomplish its task.

11:49 futile: Gotta figure out this test-nesting question.

11:50 Seems like definers should have a way to "push" onto a stack, rather than just being given *assertion-results*

11:56 Raynes: fine job with refheap I say

11:58 tomjack, mthvedt: https://www.refheap.com/15744

12:00 tomjack: futile: seems weird to me to have them in the top level

12:00 futile: tomjack: they all have to run in the top-level, right?

12:02 tomjack: even with nesting, they should probably be allowed to run outside of the context of their nest, right?

12:02 tomjack: I mean given the report you show I'd expect to see something more like (defn ^:test outer "..." [] (expect = 1 1) (testing "While signed in" (testing "It lets you do stuff" ...)))

12:02 futile: Wait!

12:03 Fixtures are inherently tied to nested tests.

12:05 tomjack: to me if 'test' a is nested inside test b, a should be inside of b in the code. def'ing a at the top level and somehow indicating "run this magically inside b" seems bizarre

12:05 futile: tomjack: by nested tests I never mean a test that's defined inside another test

12:06 I always mean, a test that has the same context as other tests

12:06 And by context I mean (1) a common scenario/pre-description, and (2) common around-each and/or around-all fixtures

12:07 tomjack: so the flow is, ignoring around-all and in pseudocode, (around-each outer) (outer) (around-each inner1) (inner1) (around-each inner2) (inner2) ?

12:08 futile: Kinda

12:09 assuming fixtures here are macros that take bodies: (do (outer1) (outer2) (around-each (inner1)) (around-each (inner2)))

12:10 tomjack: no around-each for outers?

12:10 futile: Yeah, any level can have its own set of around-each's

12:10 And each outer layer is also applied to the nested inner layers

12:11 tomjack: no clue what you're getting at :)

12:11 futile: so: (around-each-1 (outer1) (outer2) (around-each-1 (around-each-2 (inner1))) (around-each-1 (around-each-2 (inner2))))

12:12 tomjack: yeah that makes very little sense to me

12:12 futile: tomjack: https://www.refheap.com/15744#L-45

12:13 tomjack: familiar at all with RSpec?

12:13 tomjack: used to be

12:13 futile: I'm thinking, exactly what RSpec does is right.

12:14 Anderkent: futile: don't you want to just have something like defgroup that only makes all contained tests be indented, but doesn't trigger fixtures etc?

12:14 tomjack: before :each inside context?

12:14 futile: Anderkent: That makes a lot of sense.

12:14 tomjack: or alongside

12:14 futile: tomjack: yeah.

12:15 Anderkent: but should it produce a flat list of tests that just happen to be wrapped in a fn that takes into account each fixture?

12:15 That's what I'd think.

12:18 Anderkent, tomjack: aha! https://www.refheap.com/15744

12:19 tomjack: the "while signed in" confuses me

12:19 the inner group is going to have an extra each fixture which signs in?

12:19 futile: Then each "group" could have once-fixtures, each-fixtures, a description, and optionally its own :parent.

12:20 tomjack: yep

12:21 tomjack: seems like there's two separate things: 1) testing-like conj'ing of descriptions into the reporting context 2) adding fixtures per-test-fn

12:21 those two features should be sufficient to implement something crazy like defgroup, yes?

12:21 futile: tomjack: hmm

12:21 tomjack: no I don't think nesting should be something you actively do, like conj

12:22 tomjack: it should be something that's described statically.. like how in this refheap each test can have a :parent key which names a group

12:23 tomjack: eventually that's going to have to turn into some side-effect right?

12:23 like "hey now we're running assertions under a new heading \"foo\""

12:24 futile: tomjack: nope. it just needs a change to the runner to produce nested test-results, that's all.

12:24 tomjack: https://www.refheap.com/15744

12:24 tomjack: I see

12:24 futile: tomjack: the runner will have to make sure they're all run in the proper group

12:24 tomjack: the downside of this solution is that it's biased towards 1 very specific implementation of fixtures

12:25 tomjack: the upside is that it actually works, and it's very static and compile-time friendly, instead of side-effect-based

12:25 tomjack: plus using this, im pretty sure i know how to emulate both speclj and clojure.test perfectly

12:26 tomjack: I still maintain that it is impossible for you to emulate clojure.test perfectly without a custom runner :)

12:26 futile: tomjack: here let me show you exactly how it would be done

12:27 tomjack: I get what you mean now though, and test groups seem to make sense to me

12:28 your last refheap seems to imply I don't understand how you're going to do fixtures - I thought the fixtures would be baked inside the (defn ^:test ..) bodies

12:29 if the default runner knows about fixtures then I retract my claim

12:30 futile: tomjack: https://www.refheap.com/15752

12:31 tomjack: yeah makes sense

12:31 futile: tomjack: but you're right, the downside is that fixtures are now hard-coded into the spec.

12:32 pepijnde-: Why is Lisp in Small Pieces so expensive? $100 for a book sounds kind of rediculous.

12:32 futile: It's probably just that good.

12:32 pepijnde-: :o

12:33 futile: Not that I would know.

12:33 But why else? Supply/demand knows what it's doing.

12:33 hyPiRion: pepijnde-: http://www.amazon.com/Handbook-Neuroevolution-Through-Erlang-Gene/dp/1461444624

12:33 They are academic books, they usually cost that much. At least from my experience

12:34 pepijnde-: why? because poeple *have* to buy them?

12:34 hyPiRion: yeah

12:34 pepijnde-: btw, the french version of lisp costs less than half :)

12:34 hyPiRion: no wonder, it was originally written in French

12:35 pepijnde-: and there is probably less demand...

12:36 hyPiRion: probably

12:45 justin_smith: with emacs nrepl, I get this state where after an external nrepl is killed, every time I try to connect to another nrepl, it just shows "equal: Wrong type argument: bufferp, nil" but does not pop me into the normal elisp stack trace view

12:45 futile: tomjack: oh but the runner's implementation will be a pain, since you have to build a tree starting with only nodes.

12:46 justin_smith: I have debug-on-error set to t - most elisp failures actually pop up the debugger so I can trace the error

12:46 nrepl must shadow that variable or something

12:46 hiredman: https://github.com/kingtim/nrepl.el/issues/280

12:46 justin_smith: any known fix for this other than restarting emacs?

12:47 OK, restarting emacs yet again

12:59 seangrove: Is there a pmapcat equivalent to pmap?

13:00 Beyond just (apply concat (pmap ...)) of course

13:04 futile: seangrove: I don't see one.

13:09 finishingmove: what do you guys think of Racket?

13:10 futile: finishingmove: I couldn't get into it nearly as easy as Clojure, mostly a stdlib thing

13:10 finishingmove: everything about Clojure has spoiled me except the jvm/lein startup time

13:11 technomancy: finishingmove: racket is pretty amazing

13:11 especially for people new to programming

13:12 there are two really bad things about it: no docstrings, and hash tables that really suck compared to clojure. but they do a better job than any other non-clojure lisp at supporting immutability.

13:12 hyPiRion: The best thing is that you can walk through SICP with it

13:13 technomancy: you can fix the hash table thing with a #lang directive in your own code, but it doesn't help when reading others' code. culturally they appear to prefer structs to coding straight against the data, which is unfortunate

13:13 htdp.org is no slouch either

13:17 finishingmove: so basically racket is better for learning and clojure for real world application?

13:17 technomancy: finishingmove: yeah, I wouldn't expect anyone without prior programming experience to learn clojure unless they were just insanely dedicated

13:18 rbxbx: finishingmove: that's probably fair

13:18 technomancy: there's an assumption woven throughout the whole ecosystem that the user is a professional programmer

13:19 finishingmove: there's a bit of irony in that, since you'll need a relatively industry-adopted language to make a living as a programmer... so in the end what to recommend to someone who wants to learn? :)

13:21 maleghast: finishingmove: The tide is beginning to turn in the direction of Functional Programming in certain industries for a variety of good reasons, and Clojure is a very powerful, battle-tested Func Lang that is becoming popular in banking / finance, data insight etc. If you want to be able to move effortlessly job to job to job being a Polyglot Developer will help, as long as you can show you have the chops in each of your langs, and Clojure is fun to learn as

13:21 well, so what's not to like

13:21 ?

13:23 finishingmove: i don't think any of the Clojure-supporting IDEs are good enough to support a beginner programmer

13:24 technomancy: I'm not aware of anything in any language as good as DrRacket for beginners.

13:24 finishingmove: maybe LightTable will be there in a year

13:24 rasmusto: finishingmove: why needs an IDE to learn programming?

13:25 wink: notepad is good enough to support beginner programmers.

13:25 rasmusto: finishingmove: s/why/who

13:25 maleghast: finishingmove: Who the heck __needs__ an IDE - emacs + Emacs Live and you are golden

13:25 technomancy: well, Scratch is easier to learn, but that's cheating.

13:25 futile: Woot. Spec is probably 99.9% stable now.

13:26 wink: DrRacket is nice

13:27 futile: https://github.com/evanescence/test2/blob/master/SPEC.md :)

13:27 * futile gets coding!

13:31 Anderkent: I know this ain't the heroku channel, but someone probably knows how to escape args to `heroku run` so that it doesnt pick up the -c 'java -cp' as it's own '--confirm' ?

13:32 futile: Anderkent: i dunno, but thanks for solving this spec problem for me :D

13:46 finishingmove: is anyone using emacs on windows?

13:50 pisketti: finishingmove: at work occasionally

13:51 finishingmove: how would i install emacs-live (or anything else for that matter) on windows?

13:51 maleghast: finishingmove: I'm not sure why anyone would, at least not by choice, but it does appear to be completely compliant...

13:51 finishingmove: maleghast, probably because they don't have a separate unix machine :p

13:52 and are already stuck with windows

13:52 due to circumstances

13:52 maleghast: yeah, but why not use Emacs under Cygwin in that case?

13:52 pisketti: finishingmove: just as do on linux. First install emacs 24 and replace .emacs.d on the users home dir with the contents of emacs-live

13:53 and _then_

13:53 http://ftp.gnu.org/gnu/emacs/windows/ emacs from here

13:54 finishingmove: yeah i have emacs for windows running

13:54 pisketti: by contents of emacs-live I mean the checkout from https://github.com/overtone/emacs-live

13:54 finishingmove: just not sure what to copy from that repo ?

13:55 pisketti: finishingmove: then the rest is easy

13:55 finishingmove: checkout the whole thing

13:55 git clone

13:55 maleghast: finishingmove: git clone [emacs-live repo] .emacs.d

13:58 finishingmove: did that but not sure if it worked..

13:58 papul: I am trying to run a program written in clojure. When I run the command 'lein uberjar' I get this http://codepaste.net/xv5sbp. But I have jdk installed. I did 'whereis javac' and got this http://codepaste.net/boan6p

13:58 finishingmove: looks the same after starting up

13:58 papul: what am I doing wrong?

13:58 pisketti: finishingmove: then its not working

13:59 maleghast: papul: I don't think you have a full JDK installed - just having the runtime is not enough.

14:00 papul: maleghast: But I have javac in /usr/bin

14:00 and I did install openjdk 7

14:00 ToxicFrog: maleghast: 'javac' is the compiler and part of the JDK, not the JRE

14:00 maleghast: papul: ToxicFrog Yeah, I know

14:01 what Clojure are you trying to run?

14:01 ToxicFrog: papul: what's "type -a java"?

14:01 maleghast: Have you tried "lein run" instead of trying to create a .jar?

14:01 pisketti: finishingmove: did you have an empty .emacs.d in your user dir after the instalaltion of emacs?

14:01 ToxicFrog: It might be finding the JRE JVM before the JDK JVM and exploding.

14:01 papul: ToxicFrog: java is /usr/bin/java

14:01 finishingmove: pisketti, no i didn't have it actually

14:02 i think it's probably installed like a portable version

14:02 papul: maleghast: I am following instructions really. This is my first time with clojure. Just wanted to try that app

14:02 pisketti: I don't have a windows box nearby so I can't go check but I think that was the case. Then I just replaced it the contents of with emacs-live

14:02 maleghast: papul: fair enough - what's the app?

14:02 papul: maleghast: Nightweb

14:02 pisketti: and of course kept the name

14:03 papachan: what is the best way in clojure to render 00010010 ?

14:03 llasram: papachan: In what sense of "render"?

14:03 papachan: ,(Integer/toString 18 2)

14:03 clojurebot: "10010"

14:03 papachan: llasram like this

14:04 finishingmove: pisketti, i have these folders in my emacs root : bin, etc, info, leim, lisp, site-lisp. Is that where I should extract emacs-live ?

14:04 llasram: papachan: Looks like you already have it then, yes? :-)

14:05 jcromartie: I don't like it when people use "CLJ" instead of "Clojure"

14:05 hyPiRion: well, you can use cl-format for that

14:05 ,(require '[clojure.pprint :refer [cl-format]])

14:05 clojurebot: nil

14:05 hyPiRion: ,(cl-format nil "~b" 18)

14:05 clojurebot: "10010"

14:05 holo: hi

14:05 futile: holo: hi again

14:06 holo: hi! again? was i here recently?

14:06 papachan: hyPiRion: nice one

14:08 futile: holo: few days ago, you said hi and that was it

14:08 maleghast: papul: Sorry, I am in a conf call and I need to start paying attention again...

14:08 pisketti: finishingmove: try M-: (expand-file-name user-init-file)

14:09 to find the place where you should put it

14:09 holo: when running `lein run -m script.ipsql` I get "java.lang.ClassNotFoundException: script.ipsql" I've always ran this script without any problem. I think some refactoring outside the script (doing alot recently) may have caused this problem but can't find the reason

14:09 futile, wow, nice memory. thanks

14:11 futile: holo: ok

14:12 holo: I think I only remembered because your name reminded me of Halo (the original game) and Rolos and Hulo

14:12 the first two of which I only like

14:13 holo: futile, what are rolos and hulo?

14:13 futile: hulu.com

14:13 (typo first time around)

14:13 http://en.wikipedia.org/wiki/Rolo

14:13 holo: i know that one.. always stating the fact i don't live in the us, so no fun for me

14:14 futile: most people arent in the us

14:15 holo: looks delicious

14:15 futile: it's in the uk too you know

14:15 and elsewhere

14:16 holo: rolos are in the uk and elsewhere?

14:16 futile: holo: they were developed in the UK according to that article

14:19 holo: "Do you love anyone enough to give them your last Rolo?"

14:19 i must say today was my first contact with the rolo cult

14:19 futile: Is there a Rolo cult?

14:20 Wouldn't doubt it.

14:21 ToxicFrog: That's kind of alarming

14:22 I'd give someone my last rolo in a heartbeat, they aren't that tasty

14:22 jcromartie: holo: is that some kind of marketing attempt?

14:23 holo: just copy pasted from wikipedia

14:24 patchwork: How did rolos marketers get in the #clojure channel?

14:24 Is not even IRC safe anymore?

14:25 ToxicFrog: awhat

14:25 holo: it's my 15 minute attention

14:25 pisketti: insidious

14:25 patchwork: I've heard of viral campaigns but this is ridiculous

14:26 futile: ToxicFrog: lies! they are quite tasty indeed

14:27 maleghast: Rolos are made by Nestlé so they are fundamentally EVIL

14:27 futile: Oops.

14:27 hyPiRion: Why is suddenly #candies renamed to #clojure?

14:28 I have no idea.

14:28 maleghast: *chuckle*

14:28 ToxicFrog: We ran out of clojure.

14:28 There's none left.

14:28 futile: I didn't take into account that I need some way to tell if one group is the same as another.

14:28 ToxicFrog: So we had to find something to fill the channel with.

14:28 futile: Right now it literally compares the entire group-map.

14:28 ToxicFrog: Oh wait, futile has found some! We're saved!

14:28 futile: I guess that's fine though, right?

14:28 Guys, look at this: https://www.refheap.com/15752

14:29 * alandipert is studying The Last Rolo conjecture from a game theoretic perspective using #clojure simulations

14:29 technomancy: strategic paren reserves

14:29 futile: How should anyone tell that test-1 and test-2 belong to the same group?

14:29 Right now it just does (= (:group test-1) (:group test-2))

14:29 Is that a stupid idea?

14:31 I guess it's fine, although it kind of enforces that people probably can't reliably manually put ^{:group {...}} in their test-fn

14:31 Thoughts, you people?

14:32 tomjack: look ma no macros https://www.refheap.com/600920453ce6bcb447988510b

14:33 why oh why did the kanren people switch to scheme :(

14:34 futile: ,(partial + 1 1)

14:34 clojurebot: #<core$partial$fn__4192 clojure.core$partial$fn__4192@140240a>

14:34 futile: ,((partial + 1 1))

14:34 clojurebot: 2

14:34 futile: Oh. So it's just like #()

14:35 justin_smith: what is? partial?

14:35 futile: Actually it literally seems to be #(apply ... %&)

14:35 Yeah

14:35 Ok.

14:35 justin_smith: yeah, the latter - almost

14:36 or maybe literally?

14:37 hyPiRion: no

14:37 not literally

14:37 justin_smith: idiomatically, partial is often used by people who want currying, and #(apply _ %&) would not likely

14:37 hyPiRion: what would expose the difference?

14:40 hyPiRion: laziness.

14:43 Well, I guess that's hard to show, because my example involves apply partial

14:45 But you can apply partial with an infinite list

14:45 tomjack: $findfn inc 3 4

14:45 lazybot: []

14:45 tomjack: why doesn't it find deliver, I wonder?

14:45 jweiss: you'r elooking for a fn that takes inc and 3 as args and returns 4?

14:45 justin_smith: so (apply partial + (range)) vs (apply #(apply + %&) (range)) ?

14:46 tomjack: jweiss: no, just curious why it doesn't find deliver

14:46 jweiss: tomjack: (deliver inc 3) returns 4?

14:46 tomjack: &(deliver inc 3)

14:46 lazybot: ⇒ 4

14:47 jweiss: that is weird

14:47 inc is not a promise

14:47 tomjack: hyPiRion: I don't follow

14:47 &(#(apply take 3 %&) (range))

14:47 lazybot: ⇒ (0 1 2)

14:47 clojurebot: It's greek to me.

14:48 hyPiRion: tomjack: How would the following work in #() form?

14:48 jweiss: tomjack: i would have expected it to return apply, not deliver

14:48 tomjack: $findfn inc [3] 4

14:48 hyPiRion: ,(apply (apply partial take 10 (range)) (range))

14:48 lazybot: []

14:48 tomjack: :O

14:48 clojurebot: #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>

14:48 jweiss: oh right, 3 wasn't a list

14:49 hyPiRion: oh what, that is supposed to work

14:49 tomjack: that doesn't make sense

14:49 (partial take 10 0 1 2 3 4 5 ...)

14:50 amalloy: yeah, i agree. that's a nonsense partial, hyPiRion

14:50 hyPiRion: hush, I had some smart idea and then you guys came along and broke it

14:51 tomjack: partial is not literally #(apply ... %&) because there is no ... in core

14:51 amalloy: ((partial bake idea) "#clojure")

14:51 tomjack: it's literally what it says right there in core.clj

14:51 hyPiRion: ,(apply (apply partial (fn [& v] (take 10 v)) (range)) (range))

14:51 tomjack: which appears to be equivalent to what #(apply ... %&) is supposed to mean

14:51 clojurebot: (0 1 2 3 4 ...)

14:53 tomjack: hmm, scratch that?

14:53 alandipert: piranha: https://github.com/tailrecursion/presioke contains all new hotness from hlisp/javelin world

14:53 jweiss: weird, i never looked at the impl for deliver before, it just calls its first arg with its 2nd. but the docs sure make it sound like it only works on promises, not IFn's.

14:54 so deliver doesn't really do anything, you can just invoke the promise to deliver it.

14:54 technomancy: jweiss: clojure is chock-full of functions that do undefined things on arguments they're not documented to work with

14:54 amalloy: technomancy: that sounds like a correct description of every function ever

14:55 hyPiRion: yeah

14:55 technomancy: amalloy: every function lacking preconditions I guess?

14:55 hyPiRion: ,(conj {:a :b} {:c :d}) ; woo!

14:55 amalloy: technomancy: every function including them too, surely

14:55 clojurebot: {:c :d, :a :b}

14:55 jweiss: technomancy: yeah, i know, i'm more surprised that deliver isn't even needed than by its undocumented feature

14:55 justin_smith: every function lacking preconditions in a language that is not statically typed?

14:56 murtaza52: would the datomic free version run on android ?

14:56 tomjack: alandipert: does flapjax really solve "pervasive use of ... shared, mutable state"?

14:57 technomancy: amalloy: throwing an assertion error is technically undefined I guess

14:57 alandipert: tomjack: if you're quoting me... yes?

14:57 technomancy: "You are technically right, which is the best kind of right."

14:57 tomjack: doesn't flapjax pervasively use shared mutable state?

14:57 technomancy: I mean unless the docstring calls it out

14:57 amalloy: technomancy: my point is that if it's not documented to work with arguments xyz, then any behavior it takes in response to xyz is undefined

14:57 alandipert: tomjack: the key with any attempt to mitigate is a library structured to separate the mutation from your application logic

14:58 tomjack: the same way FP lang evaluators heavily mutate when they run your code, but the programming model they present tries to eschew immutability

14:58 technomancy: amalloy: I guess that works if you define "works" to include exceptions

14:58 jweiss: i have a hard time avoiding the mistake of assuming clojure would tell me if i did something crazy like accidentally pass a function to deliver.

14:58 justin_smith: in some languages "undefined" has a specific technical meaning (nostril demons)

14:58 alandipert: *eschew mutability

14:59 amalloy: justin_smith: provide an example of a language in which "undefined" means something other than "anything at all"

14:59 hyPiRion: amalloy: is it defined if you say it is undefined for any other values except xyz?

14:59 it's very meta, after all.

14:59 jweiss: lol

14:59 good question. is "undefined" a definition?

15:00 justin_smith: amalloy: well in that case I think clojure does a bit better than "undefined" with random function arguments

15:01 dobladez: technomancy: Is there a way to automatically activate a lein profile based on the OS type?

15:01 justin_smith: ie. if passing (+ nil nil) was an undefined behavior, crashing the vm would not be a bug

15:01 tomjack: alandipert: afaict flapjax is not capable of separating mutability from application logic

15:02 technomancy: dobladez: that's been discussed but not implemented. seems like a fine idea.

15:02 tomjack: I mean, it's miles better than what we had before

15:02 if the goal is to mostly separate, makes sense that flapjax satisfies the goal

15:02 dobladez: technomancy: I'll try to find some time and try to do it myself. Any pointers? You think it's possible with a plugin or hook?

15:03 I'm thinking... may be something more generic than "by OS type" would be "by JVM property" (say, via regex matching on a JVM property)

15:03 technomancy: dobladez: definitely possible with a hook, but it'd be better to put it in Leiningen itself. basically it comes down to changing the :default profile in the default-profiles atom in leiningen.core.project.

15:04 tomjack: oh, I see presioke is using javelin not flapjax?

15:05 hyPiRion: dobladez: what do you mean by jvm property though? By the jvm properties given to lein?

15:05 technomancy: dobladez: actually this would be very difficult in a plugin due to chicken/egg issues

15:05 dobladez: hyPiRion: No, I mean, you say "activate this profile if propery X matches Y"

15:06 hyPiRion: you know, JVM system property "os.name" gives you the OS name

15:06 hyPiRion: yeah, and you can dispatch on java version probably too

15:07 dobladez: so, activating a profile by java system property is more generic that hardcoding it to be by OS

15:07 right

15:07 hyPiRion: but I'm not sure whether I see the rationale for that behaviour.

15:07 Well, I mean

15:08 dobladez: I do... I've used than in the past when using backported libs from JDK 1.6 to 1.5 (java.util.concurrency comes to mind)

15:08 tomjack: are flapjax and javelin meant to be used together in hlisp?

15:08 dobladez: (on maven)

15:08 tomjack: are they alternatives or complementary?

15:08 technomancy: in general I favour flexibility, but I'm also a bit wary of implicit profiles being added silently.

15:09 that has historically been a pain point around lein repl

15:09 dobladez: no no, I don't mean adding implicit profiles

15:09 technomancy: well, not that the profile is implicit, but the activation is implicit? that is a fair bit different.

15:09 dobladez: I mean, having a way to activate an explicity profile automatically, given an "activation rule"

15:10 technomancy: yeah, and typically these would be present in project.clj, which makes them very visible.

15:10 less so when in ~/.lein/profiles.clj, but I don't think it would be used for that as much

15:11 tomjack: oh I guess hlisp is now hoplon?

15:11 hyPiRion: hmm....

15:11 dobladez: say.. something like this on profile.clj: :profile-activation { :myprofile (when-jvm-property "os.name" "Linux") }

15:11 laliluna: @seancorfield: I checked the Jira issue of java.jdbc, but none of those seems to be a simple issue. The transaction thing sounds interesting, but I wonder if I could start with something simple like adding left join to the DSL.

15:12 hyPiRion: {:profiles {:profile ^{:when (fn [] (some-prop))} {profile-data-here}}} ?

15:13 well, :when is kind-of a bad name perhaps.

15:13 technomancy: if you only want to match against system properties it's easy, but a more general way of declaring things might also be useful

15:14 {:profiles {["os.name" #"Mac"] {:dependencies [...]}}} or something

15:14 tomjack: javelin seems to make even less sense for those goals than flapjax to me

15:15 technomancy: need to grab lunch; can continue this when I get back or in a github issue or list thread

15:15 hyPiRion: technomancy: well yeah, but what if you want to do something without that profile?

15:15 dobladez: ok... that would be inside the profile itself... I like that... may be some explicit :activation keyword to make it obvious

15:15 technomancy: hyPiRion: the predicate only determines whether it's included it the :default profile; you can still `with-profiles` to get a different set of profiles.

15:16 hyPiRion: oh, so something like `with-profile -default` then?

15:16 or explicitly use a pair of profiles

15:18 dobladez: hyPiRion: hmm I think of cases where I what `with-profile xyz` to turn off the auto-activated ones... and other cases where I'd want the auto-activated ones still active :-\

15:18 s/I what/I want/

15:20 hyPiRion: dobladez: well, you can do `with-profile default,xyz ...` to use the auto-activated ones, and `with-profile xyz ...` to turn them off

15:21 If I understood technomancy correct

15:22 dobladez: right, but I mean I'd like (in some cases) for the auto ones to always auto-activate

15:22 and leave the option to do -xyz to stop them from doing so

15:22 seangrove: Wow, there's no :as :xml in clj-http?

15:23 hyPiRion: well, then use `with-profile +default` or something

15:23 it sounds like a very complex task anyhow

15:23 but not impossible with aliases

15:24 dobladez: hyPiRion: thing is, I want it to be automatic... otherwise, we are back to where we are today :-)

15:25 hyPiRion: dobladez: what? they are on by default. You explicitly set them off by specifying something like `with-profile abc`, and leave them on by specifying `with-profile +abc` or `with-profile default,abc`

15:25 dobladez: my current use case: I need different dependencies depending on OS type. This is always the case for this particular project. So, I'd use a couple of os-specific profiles. However, I also use profiles for other things (dev, prod, etc)

15:28 today lein doesn't have that - or + prefix on profiles, right ?

15:29 tomjack: hmm I think I see why minikanren is full of macros

15:30 not lazy so you need to use a macro to avoid being to eager..

15:31 * futile is thinking about nested data structures

15:35 tomjack: YES! https://github.com/thheller/clojurescript/commit/ac764ec98b1e90af3667047cef8ca292e2a9eb58

15:38 dakrone: seangrove: xml is... xml

15:39 seangrove: I (thankfully) don't have a lot of experience parsing it, but if you'd like to add support for it, it might be useful

15:39 seangrove: that being said, output coercion is pluggable, so you could alway implement it

15:43 futile: How would you guys solve this?

15:43 https://www.refheap.com/15758

15:43 Recursion or something?

15:44 * arrdem curses slow work internet

15:44 arrdem: futile: so you are trying to express that some set of tests triggers others?

15:45 futile: arrdem: no, they have a shared "context" aka group

15:45 which for now doesnt mean anything except how they're grouped/nested

15:45 Basically, given all the terminal-nodes of a tree, which contain data about their parents, how do you build up the tree?

15:46 arrdem: so how to invert a bottom up directed graph into a top-down parent -> children tree?

15:47 futile: Sounds right.

15:47 deg: Is there an idiomatic HOF that applies a function to each value in a map, building a new map with the results?

15:48 futile: What I love about this is that the inputs and outputs are simple and understandable.

15:48 What I don't love is how hard it is to implement.

15:48 (for a beginner like me)

15:48 deg: Basically map for maps or update-in that acts on all elements.

15:50 XPherior: Has anyone in here had any experience using Clojure Cascalog and Pail from the up and coming Big Data book?

15:50 I know there's a #cascalog IRC channel, but it's quieter than a ghost town in there.

15:50 arrdem: futile: pondering... this should be recursive and cute if my gut tells the truth.

15:50 chronno: deg: I don't know one, but you can do something like (into {} (for [[k v] {:a 1 :b 2}] [k (inc v)]))

15:51 futile: arrdem: hmm recursion, yeah sounds right, but a little scary

15:51 arrdem: I can't see any way without recursion really

15:51 llasram: XPherior: I use Cascalog pretty extensively. Pail, not so much

15:51 futile: arrdem: btw I updated it, refresh to see

15:51 deg: chronnon: yup, thanks. That's exactly what I'm doing already but it feels a bit awkward... both verbose and does a round-trip into a seq and back to a map.

15:52 futile: arrdem: updated to make it easier to understand

15:52 XPherior: llasram: My place is trying to use Hadoop in an append-only fashion. Can't for the life of us figure out how to work with Pail.

15:53 arrdem: futile: I think that the approach is going to be to follow the parent link all the way back up, then group children based on their parent value.

15:53 XPherior: llasram: Can't even find a good example on how to write a custom tap. :/

15:53 amalloy: arrdem: "all the way back up" will work for trees of depth one, but not deeper trees

15:54 llasram: XPherior: In what sense do you mean "append-only"?

15:54 amalloy: i think you walk over the node-list once, building up a list of maps like {:node-id x, :parent y, :children [a b]}

15:54 XPherior: llasram: Only ever reading a Hadoop file, or adding to the end of it.

15:54 amalloy: then you go over that list, and for each node whose :parent is nil, you recursively produce its tree

15:54 arrdem: amalloy: yep that's what I was thinking.

15:55 XPherior: That's supposedly the point of Pail. "Updating" a Hadoop file in a safe way.

15:55 llasram: XPherior: Taps aren't so bad. There's pretty much just an interface in Cascading you implement, generally in Java. Cascading itself has lots of examples

15:55 arrdem: amalloy: you just solve the root location better

15:55 futile: amalloy: the first part makes sense, the second part still confuses me

15:55 XPherior: llasram: I've seen them. I'm not sure why, but it's not clicking.

15:56 arrdem: futile: he's saying that the children of node N are (let [id <something>] (filter #(= (:parent %1) id) nodes))

15:56 llasram: XPherior: Oh. You never append to actual individual files in Hadoop. Hadoop distroes with 2.x code or with backported patches do support it for e.g. HBase, but you still can't do it from MapReduce jobs

15:56 XPherior: Instead you just add to a collection of files, usually with something like a new directory per day

15:57 arrdem: futile: so you just apply that to every node, recuring as long as the resulting list of children is non-empty

15:57 XPherior: llasram: Hm, yeah. I get that. But Pail is supposed to make that transparent.

15:57 llasram: XPherior: No slight to all the great work nathanmarz has done with Cascalog and Storm, but Pail seems to be something they made up for their book and nobody actually uses

15:57 futile: Oh, and then you start with those whose parents is nil!

15:58 amalloy, arrdem: that sounds perfect, thanks! Trying now :)

15:58 XPherior: llasram: Heh, yeah I got'cha. Do you have any custom Tap code that I can look at?

15:58 cbp``: deg: reduce-kv is slightly more efficient than that

15:58 futile: Raynes: please implement elisp and all emacs features in refheap so I can use it easilier without refheap.el

15:59 Raynes: lol

15:59 I'll get right on that futile.

15:59 futile: Thanks.

16:00 XPherior: llasram: Do you recommend we just straight up work with HDFS?

16:00 llasram: XPherior: Unfortunately nothing recent and open source.... But really, the implementations in Cascading are no more complex than anything else would be

16:00 XPherior: Hm, alright.

16:00 llasram: I need to drop off IRC for a meeting, but would be happy to chat more about Clojure<->Hadoop later

16:01 XPherior: No worries. Thanks for the info, llasram!

16:02 arrdem: futile, Raynes you're looking in the wrong place! go help port emacs to clojure!

16:02 futile: Actually that doesn't sound like a half-bad idea.

16:02 tomjack: lazy logic :) https://www.refheap.com/7cb54abc300fc4f470f919774

16:02 futile: Not that I have the time or knowledge to do it, but it would by default be pretty portable, and Clojure seems like a fine language for an editor.

16:03 cbp`: Isn't that kind of what lighttable aims to be?

16:03 arrdem: tomjack: what are you building? a new logic system?

16:03 tomjack: 60 LOC

16:04 I'm just porting Control.Monad.Logic as an experiment

16:04 futile: cbp`: no, that's a completely different editor.

16:04 cbp`: emacs is great because of its extensibility.

16:04 arrdem: cbp`: ibdknox would answer that better than I can but LT does provide the "editor as a single object" structure I'd expect to see in a clojure-idiomatic *macs

16:04 tomjack: eventually will either try to improve core.logic, or, yeah, new logic thing.. but the latter seems unlikely

16:04 futile: cbp`: or maybe LT is extensible too. i didnt look into it

16:04 arrdem: tomjack: mmkay cool!

16:04 cbp`: light table aims to be extensible too I think

16:05 tomjack: minikanren seems so unmini..

16:05 futile: cbp`: oh then maybe its awesome.

16:05 tomjack: eh actually it is really small

16:05 futile: I just remember really hating LT's concept of "move a snippet of code around on your screen, detached from the file it's in"

16:05 tomjack: just conceptually big

16:06 cbp`: I'm not sure about the whole implemented in clojurescript thing though. I'd like a multithreaded editor

16:06 futile: cbp`: for what?

16:06 cbp`: emacs got along just fine without multi-threading for years

16:06 the vast majority of things I do with my editor can be single-threaded, and the few that can't should realistically not be part of an editor

16:07 cbp`: And now emacs live brings along a bunch of git utilities that slow my emacs to a crawl while searching for a file :(

16:07 arrdem: futile: LIEZ. out of band compile and code analysis is awesome!

16:07 Bronsa: isn't emacs still single-threaded?

16:07 futile: arrdem: oh.

16:07 see, i told you im not very smart about this stuff

16:09 The main feature I love about emacs is that it's really just an extensible text-navigator/manipulator, which works on any text. If LT doesn't have that it's not going to be so fun to use.

16:10 never mind. i dont know what im talking about.

16:10 cbp`: I was trying to teach some friends clojure and got them to try lighttable for the instarepl and "easy connect" to projects but they preferred notepad++ + lein repl :P

16:11 futile: heh

16:14 amalloy: that tree-building thing was a fun little exercise, futile: https://www.refheap.com/78caa69723d40f0f04139e531

16:14 futile: amalloy: Well I'm glad you had fun solving the hardest algorithmic part of test2 remaining :)

16:15 amalloy: I was still stuck on (group-by (comp :group meta) test-fns)

16:16 SegFaultAX: futile: The easiest way would be to take the transitive closure of the dependency graph, then group accordingly.

16:16 futile: SegFaultAX: that sentence assumes I've been to college, doesn't it?

16:16 * futile feels disadvantaged

16:16 futile: :P

16:17 Raynes: It assumes you know how to google.

16:17 SegFaultAX: futile: Or that you've read I suppose.

16:17 amalloy: futile: all of wikipedia is available to you

16:17 Raynes: I haven't been to college either, bro.

16:17 futile: oh.

16:17 * futile googles.

16:17 pisketti: Raynes: Are you planning to?

16:17 amalloy: that may be a better approach, SegFaultAX

16:17 Raynes: pisketti: I have a full time job.

16:18 So nope.

16:18 * SegFaultAX thinks that most people shouldn't go to Uni right after HS.

16:18 pisketti: Raynes: Yes. Full time job and college studies don't go well together. I know

16:19 gzmask: question about uberjar: I have an ring/compojure web which has some static js/css files under resource folder. when I conjured my uberjar, it appears that I lost those files when I run only the standalone jar file.

16:20 Raynes: I don't need college, pisketti, I have an amalloy.

16:20 pisketti: Fair enough

16:21 amalloy: if just being near me were a substitute for a college education, i'd switch careers to "standing next to people, as a service"

16:21 Raynes: Better switch careers then./

16:21 pisketti: amalloy: If you could scale that a bit, you'd be a millionaire

16:21 cbp`: gzmask: are you referring to them by url?

16:21 CaptainLex: pisketti: He doesn't need to scale, just find the right demographic

16:22 gzmask: cbp`: by relative url

16:22 cbp`: is the jar file containing the static public files or I'll have to externally host them?

16:25 SegFaultAX: amalloy: You could be the first SNPaaS!

16:25 amalloy: SegFaultAX: i can't help but feel you're calling me a snap-ass, and if i knew what that meant i'd be offended

16:26 cbp`: gzmask: the jar contains the files

16:26 SegFaultAX: amalloy: Relevant (I think) http://xkcd.com/37/

16:26 amalloy: For some reason that's what it made me think of )

16:30 arrdem: pisketti: he lurks here doesn't he? I think he's scaling pretty well, but the monitization needs work

16:30 cbp`: gzmask: you should refer to them by like: "/css/foo.css"

16:35 gzmask: cbp`: i figured it out. I use gaka/css to generate the static file. so I'll have to run the function before I uberjar my app

16:35 cbp`: I assume the function is ran at compile time, which is when I run lein uberjar. but it is not being run

16:36 can I specify a function to be run at 'lein uberjar" ?

16:39 jchauncey: i have a deftype that i want to create in another namespace whats the best way to do that

16:40 ive tried (my.ns.MyType. args) in the repl and that dosnt work

16:41 SegFaultAX: jchauncey: Is this a namespace you control or are you trying to monkey patch an external ns?

16:41 (If it's the latter, why would you want to do that?)

16:42 jchauncey: i control it

16:42 SegFaultAX: jchauncey: Then just open the file and add it?

16:43 jchauncey: i just have a generic http api call that creates a wrapper type for convience, normally i only create them in 1 spot but in this case i need to do it in another namespace

16:51 tomjack: futile: arrdem: do we really need multithreading to handle that?

16:51 i.e. 'concurrent vs parallelism' or whatever

16:51 concurrency.

16:52 does LT run on node.js?

16:53 or does it open a browser

16:53 ..I guess the latter

16:53 callen: tomjack: it's a node.js desktop app toolkit that works by rendering a web page.

16:53 tomjack: it doesn't really "open" a browser.

16:53 SegFaultAX: tomjack: What they should have said is that emacs needs and async solution. The underlying model doesn't matter in particular.

16:54 gzmask: how do I serve dynamic content in compojure as css type? I use (get "/aaa.css" (some_fun)) and browser outputs the css as plain text

16:54 tomjack: sweet

16:54 so we really don't need multithreading for any of tat

16:54 that

16:54 just if you actually want to use multiple cores, then we'll have to have multiprocessing or something :(

17:02 futile: amalloy: this is what I was thinking, except it doesn't quite work yet: https://www.refheap.com/15764

17:02 re tomjack and arrdem too

17:03 Is this an inefficient/terrible solution?

17:03 tomjack: that `:nested (partial attach-children all-groups)` sticks out

17:03 SegFaultAX: tomjack: multiprocessing? No.

17:03 futile: Also I think attach-children is wrong, something about needing to return a seq of maps rather than a map. But it's kind of confusing me

17:03 tomjack: yeah that's a bit ugly

17:03 tomjack: not that it's ugly

17:03 amalloy: futile: you've made it O(n^2) for no particular reason

17:03 tomjack: who ever calls :nested?

17:04 SegFaultAX: tomjack: But potentially some implementation of green threads.

17:04 futile: amalloy: okay so it is inefficient then.

17:04 amalloy: it was mainly because I couldn't understand your solution, being so really smart.

17:04 tomjack: SegFaultAX: in node.js?

17:04 futile: tomjack: its the way it nests groups

17:04 SegFaultAX: tomjack: I thought we were talking about emacs.

17:04 tomjack: no, LT

17:05 technomancy: SegFaultAX: there are OS threads implemented on a branch

17:05 SegFaultAX: tomjack: For what?

17:05 technomancy: ^

17:05 * SegFaultAX thought we were talking about threaded emacs

17:05 tomjack: well, I wasn't :). I was talking about someday (today?) when LT is calling out to git and compilers and shit

17:06 futile: tomjack: yeah this thing is really broken, never mind

17:06 SegFaultAX: My mistake then.

17:07 tomjack: cbp` unfairly dissed cljs and I had to defend it :)

17:12 futile: amalloy: (your solution being the thing that's really smart; dang ambiguity)

17:23 gzmask: http://stackoverflow.com/q/17097254/914774

17:36 arohner: what is the proper way to refer to a protocol in another namespace w/ (extend-protocol)?

17:36 I'm doing (extend-protocol foo.bar/Baz ...), and getting "Could not resolve Protocol"

17:37 I've required foo.bar

17:47 mindbender1: arohner: just tested it. It works for me

17:47 how are you referring to the protocol

17:48 technomancy: devn: how goes?

18:07 mikerod: Why does (require 'clojure.main) seem to hang forever?

18:10 Sometimes I suppose.

18:21 tomjack: core.async-logic seems kind of like a nightmare, hopefully I'm going about it wrong

18:22 seems like with cljque it would have been a mechanical translation from the sync code

18:32 mindbender1: ,((fn [& coll] (when coll true)) nil)

18:32 clojurebot: true

18:33 amalloy: mindbender1: (list nil) is truthy, of course

18:34 mindbender1: amalloy: that causes NullPointerException

18:34 hyPiRion: what, no

18:34 amalloy: huh?

18:34 no it doesn't, that's a crazy claim

18:34 mindbender1: when passed to for

18:34 hyPiRion: ,(list nil)

18:34 clojurebot: (nil)

18:34 hyPiRion: what passed to for?

18:35 mindbender1: ,(list nil)

18:35 clojurebot: (nil)

18:35 mindbender1: try it

18:35 hyPiRion: ,(for [a (list nil)] [a a])

18:35 clojurebot: ([nil nil])

18:37 mindbender1: sorry

18:37 file-seq was the culprit

18:37 I had a file-seq inside for

18:39 hyPiRion: yeah, you have to doall those

18:40 mindbender1: hyPiRion: ok thanks

19:03 tomjack: looks like I basically reimplemented part of core.logic

19:03 I knew that should have been the case

19:03 but I didn't understand take*

19:05 now I understand why map-sum and -inc and conde and all that :)

19:07 back to debugging my core.logic program :(

19:21 dnolen: tomjack: heh, were you playing around with lazy sequences or something?

19:22 SegFaultAX: So I asked this the other night but unfortunately I dozed off and didn't see the replies...

19:22 What are some good task/work queues for Clojure. I've played around with Die Roboter, but it's essentially unmaintained at this point.

19:23 It doesn't seem like there is a solid winner, either. Is everyone just rolling their own solutions for async job processing?

19:26 muhoo: SegFaultAX: i've seen examples in clojure programming of using a blocking queue for that. i was going to go that route.

19:26 jodaro: SegFaultAX: do you need a client/server type thing?

19:26 or just in process?

19:27 i've used gearman off and on in the past

19:27 http://www.gearman.org/gearman

19:28 and started writing a clojure lib for it: https://github.com/joshrotenberg/clearman

19:28 but

19:28 it definitely suffers from the "hasn't been looked at in a while" syndrome too

19:28 SegFaultAX: I'm not particular about the implementation. Being able to shove jobs into a queue and have a worker pool (somewhere) process them.

19:29 Think of like, Sidekiq or Resque or Celery

19:29 mthvedt: segfaultax: doesn't java itself have things for async processing in simple use cases?

19:29 SegFaultAX: mthvedt: Sure. But this is #clojure

19:30 mthvedt: It's stunning to me that there isn't a standard solution for this.

19:30 [in Clojure]

19:31 mthvedt: segfaultax: yes, it would be nice if there was a clojure lib, but there's no law saying you can't use java

19:31 jodaro: if something out there works already and its not pure clojure

19:31 then it probably makes sense to just write a wrapper/implement the protocol

19:31 mthvedt: in fact one design goal of clojure was to make it easy to use "java for java things"

19:31 jodaro: i think i went pretty "clojure-y" in my implementation

19:32 SegFaultAX: I think both of you are missing the point a little.

19:33 muhoo: i mean, isn't this what send-off is for?

19:33 i.e. agents?

19:33 SegFaultAX: Why doesn't Clojure have a standard "async job queue" solution already. I don't care if it's new or something based on Java etc.

19:33 muhoo: Well, no. Because you probably don't want to waste cycles on your app server processing background jobs.

19:33 tomjack: well there's core.async..

19:34 SegFaultAX: tomjack: Nope.

19:34 muhoo: SegFaultAX: so wait, did you mean across servers, or in process?

19:34 SegFaultAX: muhoo: The former, probably.

19:34 muhoo: there's rabbitmq

19:34 tomjack: 'standard'?

19:34 as in, 'popular'?

19:34 SegFaultAX: muhoo: Sure, as the queue part.

19:34 muhoo: and a good clojure wrapper for it, IIRC, if you're going cross servers

19:35 SegFaultAX: muhoo: There's more than just the queue part to running a worker pool though.

19:35 tomjack: dnolen: https://www.refheap.com/2883107ad83013c34a6acf7cd

19:35 somehow I acquired the delusion that run* didn't return a lazy seq

19:35 (in core.logic)

19:36 SegFaultAX: muhoo: Also "across servers or in process" is a false dichotomy. There /might/ be a working running on the same server but not in the same process, for example.

19:37 muhoo: SegFaultAX: then i'm not sure. i've used java blocking queue for messages. i'm about to start playing with worker queues in clojure right now. examples i've seen use either agents or java blockingqueues.

19:37 SegFaultAX: muhoo: You realize that agents and blockingqueues are two /parts/ of the solution right? And really don't have anything to do with each other.

19:39 tomjack: are you saying you want a contrib library for that?

19:39 or just a popular project?

19:39 and presumably it's a bit more than a library?

19:40 SegFaultAX: tomjack: Let me give you an example. In the Ruby world, there are a number of standard libraries for this.

19:40 Delayed job, sidekiq, resque, etc.

19:41 tomjack: I guess bin/resque is the "bit" I was referring to

19:42 jodaro: resque is redis backed

19:42 so already you've got some other piece

19:42 SegFaultAX: Sure, you could use redis as the transport or queue.

19:42 But that's just part of the problem.

19:42 jodaro: wow, sidekiq has a fancy dashboard

19:43 https://github.com/jxa/resque-clojure

19:43 looks unloved

19:43 but

19:43 could be a good starting point

19:44 tomjack: hmm, why does the resque readme never mention redis config?

19:44 oh I was looking at the dev readme

19:45 so wow resque-web is a whole deal

19:45 SegFaultAX: tomjack: Resque is less than ideal. Stick with sidekiq.

19:45 tomjack: It's really inefficient.

19:46 jodaro: oh yeah

19:46 another fancy dashboard

19:46 muhoo: SegFaultAX: well i'm curious, since it seems i'm about to have to tackle what sees to be a similar problem.

19:46 SegFaultAX: Anyway, the point is it baffles me that this isn't a solved problem already.

19:46 This is an absolutely common use case.

19:46 tomjack: do you think you can solve 'the' problem with one project?

19:46 jodaro: SegFaultAX: well, it is solved, just in a few places in various states of "solved"

19:46 SegFaultAX: tomjack: Sure.

19:46 tomjack: your problem, surely

19:47 technomancy: SegFaultAX: part of the point of die roboter is that you can do it in ~100 lines, so rolling your own isn't the worst thing in the world

19:47 SegFaultAX: jodaro: From a community standpoint it isn't solved, then.

19:47 jodaro: gearman is protocol based which is kind of cool

19:47 SegFaultAX: jodaro: You have a bunch of half-assed or unmaintained solutions.

19:47 jodaro: but you don't have clojure all the way down

19:47 then again

19:47 SegFaultAX: technomancy: Well and the fact that it uses in-band job specs because they're just clojure forms.

19:47 jodaro: if you liked the protocol you could write the server in clojure as well

19:48 SegFaultAX: As opposed to out-of-band job specs.

19:48 technomancy: SegFaultAX: code-as-data, yeah

19:48 muhoo: https://github.com/bdesham/simple-queue actually seems designed for what i need

19:48 SegFaultAX: technomancy: That's a useful feature of Die Roboter. But it has some rather obvious shortcomings.

19:48 technomancy: But it doesn't seem like there is a "standard" solution for "I need an async job/work queue"

19:48 jodaro: SegFaultAX: yeah, i agree, although i'd say that often half-assed is more like good starting point

19:49 SegFaultAX: jodaro: Usually not.

19:49 technomancy: SegFaultAX: we used that model for petabyte-scale indexing pipeline, so if there are shortcomings inherent in sending the job over the wire, I don't think they're obvious =)

19:49 jodaro: in a glass half full kind of way

19:49 SegFaultAX: technomancy: Evaling jobs seems less than ideal.

19:50 technomancy: Was this for Pulse?

19:50 technomancy: SegFaultAX: no, before heroku

19:50 muhoo: eval? o_0

19:50 technomancy: pulse uses redis because it's OK being lossy

19:50 SegFaultAX: muhoo: Die Roboter uses clojure forms to convey job specifications (eg raw code over the wire)

19:52 technomancy: the only practical downside I can think of is that you don't get line numbers for exceptions in die-roboter's model

19:52 tomjack: I think I like that idea, but I want my services to know their SHA

19:52 if you solve my problem, it's ok that you don't get line numbers. just take the job and run it locally. you will get the same error.

19:52 technomancy: tomjack: oh absolutely; I would never deploy that to a mixed cluster

19:53 I don't think it's the responsibility of the job system though

19:53 muhoo: SegFaultAX: OIC, it's using rabbbitmq, and so it's dealing with text

19:53 tomjack: right

19:54 muhoo: doesn't seem like a limitation of die-roboter, seems like a limitation of using a MQ service and having to serialize the job.

19:54 SegFaultAX: Doesn't seem very DRY either. Having the option to send the job on the wire is nice, but also chews up a lot of extra bandwidth re-transmitting the same data over and over.

19:54 tomjack: well, yeah

19:55 transact the job code into datomic :)

19:55 technomancy: SegFaultAX: why?

19:55 just have the job delegate to an existing defn

19:55 muhoo: abusing datomic as a message queue?

19:55 tomjack: no

19:55 abusing it for code distribution

19:55 technomancy: SegFaultAX: it's a superset of a model that requires predefined job declarations

19:56 muhoo: oh, hmm. sure, no security implications there :-)

19:56 SegFaultAX: technomancy: Well I hadn't thought of that, good point.

19:57 technomancy: Would you use die roboter again for this type of thing?

19:57 technomancy: SegFaultAX: if I needed guaranteed delivery of idempotent jobs, I would dust it off, yeah.

19:58 if you don't need guaranteed delivery, I'm not sure I'd tie myself to AMQP because the protocol is very baroque

20:00 I feel like the hard part in that kind of system is dealing with errors and making them highly visible; maybe if I had the luxury I would read up on Erlang and OTP and lean more in that direction.

20:02 tomjack: kafka and kestrel seem much more approachable to me

20:02 SegFaultAX: Maybe porting die-roboter to Redis would be worthwhile.

20:02 tomjack: technomancy: what did you mean 'lossy'?

20:03 losing jobs?

20:03 technomancy: tomjack: with AMQP if you don't ack a message after a given timeout the worker is assumed lost, so the message is put back on the queue for another

20:03 tomjack: but there's some problem with redis that prevents doing this?

20:04 technomancy: yeah, all you can do with redis is pop an item off a list

20:04 SegFaultAX: tomjack: Redis doesn't broker messages like that. So yes.

20:04 tomjack: I had struggled to try to understand how the redis-backed queues were doing it

20:04 but assumed there must be some way I hadn't found

20:04 technomancy: well redis isn't HA to begin with

20:05 so I don't think you're ever going to get the same kind of guarantees that you do with amqp

20:05 even if you build some kind of "in-progress" quarantine set for claimed jobs

20:06 callen: SegFaultAX: I still think a "Jiraph for task queues" would be nice.

20:06 SegFaultAX: technomancy: For my use case I basically never need to be guaranteed that a job ran. And the jobs usually don't return data to the thing that enqueued them.

20:06 So for me, Redis is a totally worthwhile backend for a job queue.

20:06 tomjack: this was my point about solving 'the' problem

20:07 could you build one project which handled e.g. both cases?

20:07 SegFaultAX: tomjack: Sure, you could extend die-roboter to be agnostic.

20:07 technomancy: SegFaultAX: my noodling near the end of my involvement with die-roboter was some mildly-nutty handling of serializing exceptions so they can get punted back to the sender

20:07 SegFaultAX: tomjack: And degrade appropriately based on the transport.

20:08 mthvedt: can storm be turned into a job queue

20:08 tomjack: so you figure out some abstraction which is general enough to cover everyone's use case

20:08 technomancy: if you don't care about timeouts and error handling you could probably toss like half of the lib

20:08 mthvedt: storm is clojure

20:08 technomancy: mthvedt: storm is crazy complicated

20:08 jodaro: https://github.com/ptaoussanis/carmine

20:08 tomjack: well, if you can, please do :)

20:08 jodaro: that looks pretty awesome

20:09 i bet you could write a bad ass work/job queue with that and redis and a weekend of clojure hacking

20:10 technomancy: jodaro: I should put that on the seajure hack night projects list

20:10 I bet you could have something that works in 2 hours

20:11 jodaro: probably

20:11 great

20:11 there goes real work

20:11 technomancy: yeah, now that you've thought of it you have to go implement it

20:11 jodaro: needs a cool name

20:11 technomancy: thems the rules

20:11 jodaro: thats one hour right there

20:11 technomancy: (that's how slamhound happened anyway)

20:13 callen: mthvedt: turning storm into a job queue would be the most extreme case of overkill I've ever heard of.

20:13 mthvedt: that said, you could translate workflows into storm topologies.

20:13 tomjack: storm plugs in to job queues

20:13 callen: mthvedt: but why do you need a clustered real-time infrastructure for it?

20:13 tomjack: well, queues..

20:13 mthvedt: callen: was spitballing

20:13 jodaro: brew install redis; lein new werken

20:14 halfway there

20:14 callen: mthvedt: sure. funny thought though.

20:14 technomancy: probably won't be able to beat die-roboter in the theme song department but you can give it your best shot

20:18 hiredman: http://www.youtube.com/watch?v=SqqCyM6v6B8

20:18 callen: Raynes: http://inchingforward.blogspot.com/2013/06/adding-markdown-support-to-clabango.html

20:19 tomjack: I wonder if closure's advanced is deterministic in a useful way

20:19 jodaro: challenge: accepted. https://github.com/joshrotenberg/werken

20:20 maybe i'll call in sick tomorrow

20:20 call in hacking

20:21 callen: jodaro: task queue lib?

20:21 jodaro: yeah

20:21 callen: SegFaultAX: that's some expert-mode Tom Sawyer dude.

20:21 SegFaultAX: teach me your secrets.

20:21 jodaro: spur of the moment "holy shit! that sounds way more fun than work!" project

20:22 [18075] 13 Jun 17:17:57.697 # Server started, Redis version 2.6.13

20:22 3/4 of the way there

20:22 heh

20:22 callen: jodaro: I know that feel. I have a backlog of projects like that. #sadface

20:22 jodaro: totally

20:22 callen: jodaro: one request - pluggable backends ala Jiraph.

20:22 jodaro: hmmm

20:22 well ....

20:22 the challenge was kinda redis specific

20:22 technomancy: I thought about doing pluggable backends for die-roboter

20:22 callen: jodaro: satisfy a set of methods/protocol that make it work, then it works with different backends.

20:22 technomancy: but IMO it's just not worth it

20:22 jodaro: mainly because carmine looks so rad

20:22 technomancy: different queues have different semantics

20:23 callen: technomancy: it's an itch for me because I had to work on a job queue about a billion items long once.

20:23 jodaro: callen: i'll definitely try to keep that in mind

20:23 callen: technomancy: so stuff like RabbitMQ/Redis was pretty much straight out.

20:23 jodaro: but even a simple redis task queue would be very nice

20:23 jodaro: baby steps

20:23 callen: SegFaultAX: have you tried Carmine's?

20:24 technomancy: rabbit can keep queues on disk these days

20:24 jodaro: i've actually only toyed with redis in the past

20:24 so

20:24 it will be a learning experience for me

20:24 callen: technomancy: from my tests, rabbit choked several orders of magnitude away from a billion.

20:24 jodaro: my coworker is all hot on redis, though

20:24 callen: jodaro: redis is sexy.

20:24 jodaro: maybe i can get him involved and he can get his clojures on

20:24 callen: jodaro: you'll like it.

20:24 jodaro: yeah it seems pretty nice

20:25 lua support

20:25 that could come in handy here

20:25 callen: technomancy: rabbit's really not made for long-lived job queues.

20:25 technomancy: you'll end up with something a lot simpler with redis because there are certain guarantees you simply can't make =)

20:25 jodaro: heh

20:28 i'll be able to guarantee your job might get run

20:28 seems good enough

20:28 devn: hm, is there a way to destructure cleanly in a ->>

20:29 jodaro: between the repl and redis-cli, this is a darn nice environment, i'll say that

20:29 callen: jodaro: redis is a happy place.

20:31 devn: it'd be cool to do something like (->> {:a 1 :b 2} [[{:keys a b}] [a b]]) => [1 2]

20:31 muhoo: what's the appeal of redis? it's a kv store, right?

20:31 callen: devn: I'm not sure, if you figure it out, let me know.

20:31 muhoo: data structures as a service with atomic commands.

20:32 devn: it's really not ->> anymore if it does that

20:32 it's just a shame I can't just drop a let into -> or ->>

20:33 justin_smith: ,(->> {:a 1 :b 2} ((fn [{:keys [a b]}] [a b])))

20:33 clojurebot: [1 2]

20:33 callen: muhoo: sproc'ish lua scripting, low latency, nice cli. It's just a very low overhead and smooth experience to use redis most of the time as a developer.

20:33 muhoo: callen: thanks

20:33 callen: muhoo: so queues for example, in Redis are trivial because it as things like LPUSH and RPOP

20:33 jodaro: strings, hashes, lists, sets and sorted sets.

20:33 nice

20:34 callen: muhoo: bitmaps, for which it was good commands for doing population counts, etc.

20:35 muhoo: http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps/

20:35 muhoo: http://redis.io/commands

20:36 muhoo: I talked to the guy on the phone, I should be talking to him again about the project tomorrow.

20:43 tomjack: callen: that is a neat trick

20:44 is the requirement for sanity that you've got an idempotent monoid?

20:45 hmm, I dunno what I mean

20:46 oh, yes, a=(a*b)*b <=> a=a*(b*b)

20:46 well, that's wrong too, but anyway neat trick

20:48 callen: tomjack: wait, what did I do?

20:48 * callen looks around nervously

20:48 tomjack: the bitset blog post

20:48 callen: oh

20:48 tomjack: the rest of what I said was meaningless I think

20:48 obviously it's gonna work out when you're working with a set of bits..

20:50 but 'setbit' is dangerous

20:54 I think every time I've said "garbage-in garbage-out" about clojure to someone, I've thought "I don't believe what I am saying"

20:55 bbloom: tomjack: it's a trade off

20:55 tomjack: if you want to prevent garbage in, you need to add asserts or static verification

20:55 that comes with complexity

20:55 or performance impact

20:56 tomjack: complexity of implementation?

20:56 for the language author

20:57 bbloom: no

20:57 tomjack: for language users?

20:57 bbloom: depends on the particular restriction you're trying to impose

20:58 for example ##(keyword "x y") could incur a performance penalty by regex matching it's input

20:58 lazybot: ⇒ :x y

20:59 tomjack: that's a good one

20:59 bbloom: that would be complexity for the language implementor, who needs to consider all those possible error cases & handle them & throw nice errors

20:59 you could imagine a type system with variants of asset

20:59 like you could have assert, check, and assume

20:59 assert throws an error if some condition isn't met

20:59 check would check the condition & then annotate the symbol as meeting the condition or not

21:00 and assume would just say "eh, fuck it" and opt in to garbage in / garbage out

21:00 tomjack: eh, I remain unswayed

21:00 bbloom: i'm not suggesting you actually do this

21:01 tomjack: I mean by your keyword example

21:01 bbloom: i'm saying that there are dynamic properties that you'll never be able to check or verify either satically OR at runtime or that you wouldn't want to check

21:01 there can be much more complex things to check

21:01 mindbender1: garbage in garbage out is the law of truth

21:02 tomjack: these things I do not want in my language

21:02 bbloom: let's say i have a function that accepts a lazy sequence and needs to know that the number of entries in the sequence is even

21:02 but the seq does not fit in memory

21:02 you can keep a count & throw an error… AT THE END

21:02 you can't throw an error up front

21:02 that's garbage out

21:02 you got a lazy seq out that was invalid

21:03 garage in / garbage out is the only sensible design for a dynamic language without a type system when performance is critical

21:04 tomjack: ok, yeah

21:04 that I can agree with

21:04 that a static type system adds complexity.. dunno about that

21:04 bbloom: *shrug* i think that optional typing is the way of the future, but we're not quite there yet :-P

21:05 tomjack: I've thought about that, but I see one problem

21:05 bbloom: s/optional/pluggable/

21:05 clojure has a type system. it has like 9 types: 8 java primitives plus "object" :-)

21:05 tomjack: making things the way I want them would require e.g. fixing the behavior of keys

21:06 bbloom: i assume you're talking about my msg to the mailing list just now? are you in favor of my suggestion?

21:06 tomjack: it's hard to say

21:06 brehaut: bbloom: and arrays?

21:06 tomjack: I think so

21:06 bbloom: my hesitation now was jean's msg that i overlooked

21:07 tomjack: but if I get the optional typing I want, there will be many other problems in clojure.core

21:07 bbloom: apparently keys is, logically, (partial map first)

21:07 but that is bugged too

21:07 tomjack: I can't fix them all, it'd be a different language. so, oh well :(

21:07 bbloom: so i want either my proposal, or fixing keys to properly mimic (partial map first)

21:07 tomjack: I'd definitely rather have your proposal

21:08 bbloom: me too :-P

21:08 but the jean's comment basically means that my proposal is a breaking change, so i don't think we can get it

21:08 tomjack: exactly

21:08 no one can even tell if they rely on garbage-out behavior in previous versions

21:09 bbloom: in the absence of my proposal, i don't really care about fixing the illusion of (partial map first), even though i think it is in fact a bug in that interpretation of keys

21:09 tomjack: I always wondered why sometimes calling keys on the wrong thing caused craziness in my repl

21:09 bbloom: tomjack: yea, relying on garbage-out is the biggest issue facing dynamic language APIs

21:09 brb

21:10 tomjack: and yet if you try to embed a language which attempts to solve some of these problems inside clojure, people won't use it, because it's not clojure :)

21:11 I guess the approach could be to bootstrap inside clojure and then fork off

21:13 ..oh, yes, like bodol

21:15 papachan: ,(cl-format nil "~{~R~^, ~}" [1 2 3 4])

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

21:16 bbloom: ,clojure.pprint/cl-format

21:16 clojurebot: #<CompilerException java.lang.ClassNotFoundException: clojure.pprint, compiling:(NO_SOURCE_PATH:0:0)>

21:16 papachan: ,(require '[clojure.pprint :refer [cl-format]])

21:16 clojurebot: nil

21:16 papachan: ,(cl-format nil "~{~R~^, ~}" [1 2 3 4])

21:16 clojurebot: "one, two, three, four"

21:17 bbloom: bwa? you can require/refer in clojurebot?

21:17 papachan: bbloom: yes

21:19 bbloom: ,(require '[clojure.core :refer (inc) :rename {inc cl-format}])

21:19 clojurebot: #<IllegalStateException java.lang.IllegalStateException: cl-format already refers to: #'clojure.pprint/cl-format in namespace: sandbox>

21:19 bbloom: ,(require '[clojure.core :refer (inc) :rename {inc cl-format2}])

21:19 clojurebot: nil

21:19 bbloom: odd, so i can mess up clojurebot's names if i'm the first person to import a namespace?

21:20 ,clojure.walk/prewalk

21:20 clojurebot: #<walk$prewalk clojure.walk$prewalk@636c8d>

21:26 Denommus: damn

21:26 I was able to run a clojure app in android

21:27 but now I want my launcher activity to be a Java activity, but no matter what I try, the application crashes. And since I don't have a backtrace or something similar, I have no idea on what's happening

21:57 I think I understood the problem

21:57 when my clojure application is compiled, it defines a class called "Application", which is then used by the AndroidManifest

21:58 but this class is being generated by android code

22:02 papachan: Denommus: any github to see your project?

22:06 Denommus: papachan: no, I'm just starting

22:06 *this class is being generated by clojure code

22:06 papachan: Application class?

22:06 Denommus: yes

22:06 with the defapplication macro

22:06 (defapplication com.spell.chat.Application)

22:07 I think clojure needs this class to run correctly, I can't just remove it from AndroidManifest

22:07 but if I try to put a bootstrap Java activity, it crashes. I guess because it tries to run before the Application class is even loaded

22:08 is there any tutorial covering how to use a bootstrap Java activity?

22:08 papachan: generally you can extends the Application Class

22:09 Denommus: yes. Clojure is doing that with (defapplication com.spell.chat.Application)

22:09 but I don't know what would be the implementation under the hood

22:10 I think the implementation under the hood actually loads the clojure environment, so that clojure code can run

22:11 difficult sittuation

22:11 clojurebot: clojure is the best

22:11 Denommus: have you ever done android development with clojure, papachan?

22:12 papachan: Denommus: not yet

22:12 Denommus: I'm successful if I don't use a java activity as my launcher

22:12 but then the application takes 5~10 seconds to load

22:13 beppu: What could it possibly be doing to make it take that long to load?

22:13 callen: that sounds about standard for Android Clojure apps.

22:13 Denommus: it loads the whole clojure environment. That's expected, actually

22:14 the problem is not taking that long to load, I could be away with it in my application because I could use the time to log the user in asynchronously

22:14 while showing some loading animation

22:15 but, to do that, I'd need a Java launcher, which I don't seem to be able to use

22:19 well, I'm going home

22:19 bye

22:21 dcooper8: so is emacs/swank still used for clojure?

22:22 technomancy: dcooper8: swank still works but isn't actively maintained; nrepl.el is recommended instead

22:22 brehaut: http://technomancy.us/163

22:23 thanks technomancy, now i look like an idiot

22:24 bbloom: heh, that domain name w/ that tld sounds like a verb

22:24 problem? technomancy it!

22:25 technomancy: the guy who owns technomancy.org is a php hacker

22:25 brehaut: im sorry to hear

22:26 technomancy: oh, no it's just python

22:26 my bad

22:26 brehaut: maybe he got a clue since you last looked

22:26 bbloom: could be worse. there could be a gay canadian porn star with the same name as you (as there is for me)

22:26 brehaut: awkward

22:26 bbloom: you can imagine how that would be confusing if you were looking for my github account, right? :-P

22:27 the day i got that google alert was… surprising

22:27 brehaut: haha

22:28 technomancy: heh: http://www.kindle-maps.com/blog/how-to-walk-across-dublin-without-passing-a-pub-full-publess-route-here.html

22:29 bbloom: technomancy: awesome.

22:30 they say "here's the route", but i wonder if they could show the union of all the routes

22:30 like is there only one route? is this a bug that one pub closed?

22:30 brehaut: bbloom: but then they'd have to write more code with open street maps javascript, which is roughly comparable to performing surgery on yourself with only a darning needle

22:34 bbloom: surely the solution is mobile pubs.

22:34 motorized beer carts

22:34 technomancy: you mean ... epubs?

22:34 brehaut: ~rimshot

22:34 clojurebot: Badum, *tish*

22:35 brehaut: open source ipa http://yeastieboys.tumblr.com/post/52208987616/digital-ipa-recipe

22:35 good luck sourcing the hops

22:40 related: http://yeastieboys.co.nz/beer/gunnamatta-ipa/ earl grey IPA

22:50 sineer: lamina looks pimp! Exactly what I needed and much more!! and the doc... amazing stuff

23:00 dpwright_: I'm trying to create a function inside a macro and add it to a list during execution of that macro (ie at compile time)

23:01 I have the body of the function stored inside a variable called body, so that (fn [] body) doesn't work because what I really want is (fn [] ~@body) or something, except since this is happening as part of the macro and not the value returned from that macro, it's not quasiquoted or anything like that, so ~ style syntax won't work

23:02 is it possible to do this? Or am I being stupid and should I just return commands to do that from the macro and have them execute outside of the macro like a sane person would do?

23:02 actually, I think that's probably the answer, isn't it? :-P

23:16 cgag: i'm playing with clojurescript and node-webkit and getting this error when i try to connect with the browser repl

23:16 Uncaught Error: URI file:/robots.txt is invalid for field ppu

23:16 I can get rid of it by just manually deleting any lines referencing robots.txt in the compiled js, has anyone run into this and solved it in a more elegant way?

23:26 futile: Now then.

23:45 I'm not gonna lie about it: programming is hard.

23:58 This whole thing feels...

23:58 ...futile

Logging service provided by n01se.net