#clojure log - Nov 12 2013

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

0:01 akurilin: Unrelated: what's the most idiomatic way of configuring a library in Clojure with some state? For example, you have a library which wraps an API that needs a key, and you want to set it once at init. Is an atom in the library's ns to contain that state a bad idea?

0:01 and a call (set-library-key! "foo")

0:02 swarthy: i use a let over lambda for that, func that takes in the api stuff and sets a local that returns a new function

0:02 with that state encapsulated

0:02 not sure how idiomatic that is

0:03 justin_smith: swarthy: the lispy version of a factory :)

0:04 akurilin: we use a config function that loads an edn file based on current running environment, and then execute with config bound to that value lexically

0:04 swarthy: justin_smith: I guess so

0:05 justin_smith: that way, if I need to connect to the staging and prod dbs from dev, I can make a pair of macros in the repl that execute in the context of each of those configs when doing db queries

0:05 so I am not stuck having to run a repl for each env, or restart my repl in order to switch env

0:05 akurilin: that's fancy!

0:05 justin_smith: the main repl I use is launched from ring inside the :init function, inside the context of my current environment's default config

0:05 which is usually enough :)

0:06 bitemyapp: akurilin: I was saying something about AOP

0:06 akurilin: emphasis on the P

0:06 justin_smith: the macro is just (defmacro in-staging [& body] `(with-app-config staging-config ~@body))

0:07 bitemyapp: akurilin: I linked you the damn articles too

0:07 `cbp: I'm back.

0:07 `cbp: READY TO ROCK SOME NOOBS?! hue hue hue hue

0:07 akurilin: swarthy's suggestion of let over lambda is the closure pattern I was talking about yo.

0:07 akurilin: that is mad-idiomatic for Clojure. Do it!

0:10 swarthy: totally idiomatic. be proud.

0:11 swarthy: bitemyapp: I can't tell if this is real or sarcasm. lol

0:12 bitemyapp: swarthy: mad sincere. I'm serious. closures, let over lambda, etc etc are allllll gooood.

0:12 swarthy: I wish people would use the nice functional patterns from Common Lisp more

0:12 and less of the Ruby-esque monkeypatch bullshit.

0:13 justin_smith: the hilarious thing is ruby people think they are emulating lisp when doing that stuff

0:13 * bitemyapp bashes head against wall and growls in the background behind justin_smith

0:14 swarthy: bitemyapp: ahah, thanks!

0:14 bitemyapp: swarthy: it's actually a semi-hobby of mine to hammer out safe, clean, functional ways to do encapsulation, DI, and the like.

0:15 especially ways that don't rely on globals, are async-safe/thread-reentrant, etc.

0:23 justin_smith: how about multi-config re-entrant

0:24 bitemyapp: justin_smith: are you mocking me?

0:24 justin_smith: nope

0:24 that one is my priority (being able to have multiple configs for my app running at once)

0:24 bitemyapp: justin_smith: multi-config I'm down with, ditto re-entrant, but you're going to need to help me with the peanut butter and chocolate thing you're doing

0:24 justin_smith: ohhh! yeah I do that all the time.

0:24 justin_smith: ie. talk to staging and prod dbs at the same time

0:25 bitemyapp: justin_smith: my @work project has that.

0:25 justin_smith: you can just fire off instances of the service with an arbitrary config (environ first, then gets overridden by closures), the instantiation returns its own shutdown function.

0:25 justin_smith: you stash the running instance shutdown fns in an atom.

0:25 justin_smith: do you have a good way to do that for multiple libs sharing a config, without using a special var? we have a special var macro that is working nice, but if we could avoid using that...

0:26 bitemyapp: justin_smith: environ + closures. To be more helpful I'd need to know what you mean

0:26 justin_smith: if my guess is right, your problem is that the data is a global in the library

0:26 justin_smith: I avoid that and just DI the data dependency with a closure to the library and get constructed fns with the config provided.

0:26 justin_smith: hmm, I thought environ used a file to put your app in a specific config, so it prevented multi side-by-side configs

0:26 bitemyapp: or just directly provide in a vanilla fashion as arguments.

0:26 justin_smith: naw, it's an onion man.

0:27 environ is outer layer, closures and arguments are the inner layer.

0:27 justin_smith: bitemyapp: no, no longer aglobal we moved it out of that, and now each of our libs refer up to the var which gets special bound

0:27 bitemyapp: yes, environ is global and all that, but it just provides the global defaults, it has lower precedence than your closures/arguments at all time.

0:27 justin_smith: I guess the other option is to spawn a clojure let over lamabda for each libs functions?

0:27 bitemyapp: justin_smith: yeah, that could work, I'd do it with closures/arguments instead, but that seems viable.

0:28 justin_smith: well I used to do that in JavaScript all the damn time.

0:28 justin_smith: the top level module of my JavaScript would have a lexical closure around the entire library. that sort of thing.

0:28 that or just make the dependency explicit as an argument.

0:28 nuthin' stoppin' ya.

0:28 justin_smith: right

0:28 technomancy: bitemyapp: are you talking about functors again

0:28 justin_smith: the tricky thing is the chaining, when a lib gets used multiple places you then have to pass it in explicitly everywhere

0:29 bitemyapp: technomancy: actually no, but what we're talking about could be modeled as a comonad.

0:29 justin_smith: instead of just refering to a function in its ns

0:29 bitemyapp: technomancy: so if you'd like to make this about functors...I can make it happen cap'n.

0:29 technomancy: I just thought I saw parameterized namespaces floating by

0:29 justin_smith: bitemyapp: ideally, config could be an ml module that is specialized with your app settings :)

0:30 yeah, clojure needs paramaterized namespaces

0:30 bitemyapp: justin_smith: well, I typically pull all the closed over fns into a core/main namespace of some kind

0:30 justin_smith: but you've inspired me to think about an ns+ or some kind of wrapper thingy to do what you're talking about.

0:30 justin_smith: bitemyapp: and how do you export them?

0:31 technomancy: bitemyapp: btw: doesn't work yet but http://p.hagelb.org/edgestow.ml.html

0:31 justin_smith: I bet we could make ml style modules work in clojure

0:31 bitemyapp: justin_smith: depends on how many there are and how much variance there is in the data provided, because I'm kind counterbalancing how much repetition I want to tolerate. Sometimes a vector, sometimes a map.

0:31 justin_smith: well that's what I'm saying, I think it could be done.

0:32 justin_smith: technomancy: woah, the default ocaml highlighting in emacs? I recognize those goldenrod lets anywhere

0:32 technomancy: justin_smith: zenburn+tuareg

0:33 justin_smith: that's the name I was forgetting

0:33 tuareg

0:34 bitemyapp: ML modules are a good example of what happens when you work with a set of well-designed constraints

0:35 justin_smith: bitemyapp: so I think the general outline of it could be an ns with defns that each wrap a let-over-lambda generator with a config arg - and the one arg that all of them get when you realize the module is the ns you are generating

0:35 bitemyapp: technomancy: the haskell alternative: http://learnyouahaskell.com/functors-applicative-functors-and-monoids

0:35 justin_smith: so from a app-module ns, I can generate my-app.prod, my-app.staging, etc. as needed

0:36 so when you call those generators, they create and fill the config specialized ns

0:36 bitemyapp: justin_smith: which is pretty easy to reason about and see why it'd be helpful, but I think applicative functors are a more powerful and general way forward with that whole problem class.

0:36 justin_smith: do you know Haskell?

0:36 justin_smith: bitemyapp: barely, more familiar with ocaml

0:36 bitemyapp: justin_smith: okay yeah, you'll want to grok applicatives and functors.

0:37 justin_smith: the rabbit hole goes much deeper in Haskell, it's a great time.

0:37 justin_smith: I'm one of those fluokitten nuts.

0:37 justin_smith: https://github.com/uncomplicate/fluokitten

0:37 justin_smith: yeah, I take a taste every once in a while, it starts to make a little more sense each time

0:37 bitemyapp: justin_smith: it's like acclimating to the water temperature in the ocean, just dive in yo.

0:38 justin_smith: heh, maybe if I get some time off work

0:38 bitemyapp: justin_smith: I recommend http://yannesposito.com/Scratch/en/blog/Haskell-the-Hard-Way/

0:39 justin_smith: I love learning and try to do it often, but this kind of thing takes up a limited reserve. Right now I am focusing on packing (subproblem quad-trees for marking a space at the moment)

0:39 bitemyapp: I've seen that one, like the title

0:39 bitemyapp: justin_smith: well, it's more information dense and useful than LYAH/RWH

0:40 LYAH/RWH are too little butter on too much toast.

0:40 HTHW is proper awesome. you only read the important bits that lead to grokful awesomeness.

0:45 jared314: with lein-cljsbuild, is there a setting to stop it from including cljs.core?

1:03 coventry: technomancy: Do you know why, if I put a println in nrepl.discover/wrap-discover's anon fn (and inside its push-thread-bindings), I don't see the output in the repl, but I do see output from println's in the fns it calls such as nrepl-op?

1:11 muhoo: sorry if i've asked this before, but what does (let [{[foo] :bar} x] ...) do? it's a weird pattern, i'm used to seeing (let [{:keys [foo] :as bar} x] ..) but never seen the former before

1:11 jared314: muhoo: it looks like nested destructuring

1:12 muhoo: you can nest destructures?

1:12 noidi: muhoo, I think you asked this two days ago or so and I answered :)

1:12 muhoo: noidi: auugh, memory agai

1:13 sorry

1:13 i didn't see the answer though.

1:14 jared314: muhoo: http://logs.lazybot.org/irc.freenode.net/%23clojure/2013-11-10.txt

1:14 noidi: (let [{foo :bar}]) assigns the value under the key :bar to name foo. (let [[foo] [1 2 3]]) takes the first item in the list and assigns it to foo

1:14 bitemyapp: ,((fn [[[x]]] (println x)) [[1]])

1:14 clojurebot: 1\n

1:14 bitemyapp: muhoo: ^^

1:14 noidi: that's just putting the two together and assigning the first item in the list under the key :bar to foo

1:14 brainproxy: clojurescript compiler has started telling me "no such namespace at line..."; i've looked over every line of code, my git diffs and for the life of me can't figure out what it's complaining about; is there a way to get more info about the error?

1:15 i'm using `lein cljsbuild once ...`

1:16 to make it even more frustrating, despite the warning, the output of the build passes all the tests and I'm not getting any errors in my browser console

1:17 muhoo: jared314: thanks

1:17 bitemyapp: brainproxy: lein clean?

1:17 jared314: brainproxy: i assume you have run a lein cljsbuild clean?

1:21 sm0ke: why isnt there a let-while in clojure?

1:22 brainproxy: bitemyapp jared314: yep, made sure to do clean

1:23 jared314: sm0ke: what about doing a for?

1:24 sm0ke: for has a :when option

1:24 sm0ke: jared314: isnt "for" for list comprehension stuff

1:24 muhoo: nice: {{:keys [bar baz]} :params} :as request}

1:24 saves a let line in a ring handler

1:25 bitemyapp: muhoo: dude, this is Clojure. of course it works. :)

1:25 jared314: sm0ke: what did you want to do with your let-while?

1:25 sm0ke: i would like to wait over a core.async channel

1:25 in a while loop until channel closes and returns null on <!

1:26 jared314: sm0ke: in a go block?

1:26 sm0ke: yea

1:26 or a (thread) with >!!

1:26 i mean <!!

1:27 hmm i seem to have a metal blockade from time to time

1:27 may be i am losing brain cells due to radiation

1:29 bitemyapp: sm0ke: fly a lot?

1:29 muhoo: bitemyapp: actually, the above does not work

1:29 justin_smith: sm0ke: how would this be different from (loop ...)

1:29 bitemyapp: muhoo: oh, :(

1:29 jared314: sm0ke: loop recur would do it

1:29 muhoo: the :as appears to not be happy, but the destructuring works without the :as

1:31 sm0ke: yeaaa

1:31 but it seems like loop [a (<! c)] whould not terminate by itself

1:31 does loop checks for truthly values?

1:32 jared314: not that I know of, you would need a check in the loop

1:32 sm0ke: i would have to do a (nil? a)

1:32 yes

1:32 justin_smith: ,(let [{{:keys [bar baz]} :params :as request} {:params {:bar 0 :baz 1}}] [bar baz (+ bar baz)]) ; muhoo

1:32 clojurebot: [0 1 1]

1:33 sm0ke: isnt that unnecessary

1:33 if i had a let while

1:33 you see the point?

1:34 jared314: almost, it sounds like you want to avoid an if

1:34 justin_smith: muhoo: see above, you just had :params on the wrong side of the }

1:34 rs0: question about the command line: lein spec -a is awesome, but i'd find it a bit easier to read the output if it cleared the screen each time before running the tests and displaying output. is there any way to do this?

1:34 sm0ke: jared314: isnt clojure all about simplicity?

1:35 i may be too lazy also

1:35 jared314: sm0ke: i remember a Rich talk about that word

1:35 sm0ke: i think he defined it

1:35 justin_smith: sm0ke: this is clojure, you can write let-while :)

1:35 muhoo: now, this works https://www.refheap.com/20757

1:35 sm0ke: yes :(

1:35 i dont yet know macros

1:35 justin_smith: no you have a reason to learn

1:35 muhoo: destructuring ftw

1:36 justin_smith: *now

1:36 muhoo: if you're lazy, then (doall sm0ke)

1:36 sm0ke: justin_smith: you are right

1:37 bitemyapp: `cbp: that was intense and awesome.

1:38 muhoo: actually if (doall) worked in real life, i'd have no problems.

1:38 `cbp: bitemyapp: :D

1:40 bitemyapp: `cbp: you and that bane did a great fucking job

1:40 the cc was critical

1:41 jared314: does a cljs build always include cljs.core?

1:42 muhoo: justin_smith: ah, i didn't realize you can have stuff after the :params

1:42 justin_smith: :as name always goes last

1:42 after the individual sub bindings

1:44 Raynes: As God intended.

1:44 justin_smith: OT: how do I make the sound system on an ubuntu headless server initialize without a user GUI login happening?

1:44 never mind, off to #ubuntu

1:46 bitemyapp: justin_smith: http://askubuntu.com/questions/211039/getting-system-to-boot-in-headless-mode-set-up-without-display-problems

1:47 justin_smith: bitemyapp: it boots, but no audio devices get initialized

1:47 if I do the gui login, bam, audio devices

1:47 bitemyapp: justin_smith: that's a different question. ask the right question >:|

1:48 justin_smith: http://raspberrypi.stackexchange.com/questions/3632/running-headless-how-do-i-create-a-boot-sound

1:48 justin_smith: I asked how to make the sound system on a headless server work without gui login

1:48 I was very precise

1:48 bitemyapp: justin_smith: also, sudo service pulseaudio start

1:48 justin_smith: I did that

1:48 bitemyapp: justin_smith: check the other link then

1:48 justin_smith: pacmd list_sinks shows nothing before the gui login

1:50 ok, second link looks right so far, thanks

1:51 bitemyapp: all that second link does is call aplay

1:51 it does not initialize audio devices

1:51 I don't want a startup sound, I want to run 16 channels of audio into a fingerprinter daemon :)

1:52 bitemyapp: though, you are still more helpful so far than #ubuntu has been

1:52 lol

1:52 I think the real solution is to use debian or something, the boxes owners wanted ubuntu

1:53 bitemyapp: justin_smith: in a more truthful world, #ubuntu would be ##cuntsville

1:53 but with two ##'s, because it's not Official.

1:53 lazybot: ⇒ s

1:53 bitemyapp: lazybot: shut it.

1:53 I haven't had a good experience in #ubuntu since 2005.

1:53 sm0ke: can a core.async channel have multiple consumers?

1:53 bitemyapp: sm0ke: 'course.

1:54 sm0ke: what is the message policy?

1:54 i mean does everyone gets same message

1:54 bitemyapp: sm0ke: it's a programming language, the policy is whatever you make it.

1:54 sm0ke: or only one of them?

1:54 bitemyapp: sm0ke: you want repeat propagation, then do that. if you want sharding, then do that.

1:54 sm0ke: how?

1:54 clojurebot: with style and grace

1:55 bitemyapp: ^^ that.

1:55 sm0ke: :)

1:55 bitemyapp: sm0ke: why not take a wild guess, and see what happens?

1:55 swarthy: sm0ke have you written any Go, the language that stuff is based on?

1:55 bitemyapp: justin_smith: kindly explain to me how sudo service pulseaudio start doesn't work?

1:55 swarthy: don't talk about that language in here.

1:55 my liver starts oozing bile whenever I hear about it.

1:55 then the fangs come out, then people start screaming.

1:55 swarthy: bitemyapp: ahah why?

1:56 sm0ke: no..i have used actors in akka though

1:56 but thats more explicit you have routers

1:56 bitemyapp: swarthy: Go sets programming back to about the ~80s.

1:56 maybe the 90s.

1:56 justin_smith: bitemyapp: it starts, and sees no sound devices

1:56 sm0ke: an a pool of actors

1:56 justin_smith: after GUI login, all sound devices are visible

1:56 some initializing is waiting for the login

1:56 I don't get it

1:56 bitemyapp: justin_smith: toss me an error message.

1:56 justin_smith: juked@juked-maudio:~$ aplay -l

1:56 aplay: device_list:268: no soundcards found...


1:56 that's it

1:57 the whole thing

1:57 bitemyapp: justin_smith: that's after starting pulseaudio?

1:57 justin_smith: yes

1:58 jared314: with autospawn?

1:58 bitemyapp: justin_smith: lspci plz

1:58 justin_smith: now, after login I get http://sprunge.us/eNjV


1:58 bitemyapp: justin_smith: alsamixer + F6 plz

1:58 justin_smith: bitemyapp: same message from alsamixer

1:58 refuses to launch, claims no cards found

1:58 bitemyapp: justin_smith: try speaker-test

1:59 justin_smith: ok, have to reboot I think, I logged in and now devices are visible

1:59 bitemyapp: justin_smith: well do that then

2:01 justin_smith: as soon as I log out, speaker test hangs and no sound cards are visible

2:01 (gui log out, ssh logged in)

2:01 * bitemyapp sips tea and nods sagely

2:01 bitemyapp: justin_smith: aplay -l?

2:01 justin_smith: once again, no soundcards found

2:02 same message from alsamixer

2:02 ambrosebs: 60 minutes left :) http://www.indiegogo.com/projects/typed-clojure/x/4545030

2:02 bitemyapp: justin_smith: ubuntu 13.04 or 13.10?

2:03 justin_smith: well, more precisely, cannot open mixer: No such file or directory

2:03 Linux juked-maudio 3.11.0-13-generic #20-Ubuntu SMP Wed Oct 23 07:38:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

2:03 bitemyapp: justin_smith: with sudo?

2:03 justin_smith: that was it

2:03 d'oh

2:03 of course

2:04 bitemyapp: justin_smith: I'm a fucking pro.

2:04 justin_smith: thanks!

2:04 bitemyapp: justin_smith: I was one of those rare souls to get Linux wireless working in the bad old days.

2:04 justin_smith: heh

2:04 bitemyapp: I have the limitless patience and hatred necessary to get such things.

2:04 Also useful for: suicidal assassination missions.

2:04 justin_smith: well, hat's off, this thing was driving me crazy, and that solved it

2:05 bitemyapp: and people wonder why I use a mac in addition to my thinkpad...

2:05 * bitemyapp goes back to drinking tea, nodding sagely, and being awesome.

2:06 justin_smith: I have a mac that my company bought me, sitting on my desk on work

2:06 andyfingerhut: ambrosebs: Thanks for the reminder, and the work on typed Clojure

2:06 justin_smith: it was last turned on 3 weeks ago

2:06 macbook pro

2:06 ambrosebs: andyfingerhut: thanks!

2:07 bitemyapp: justin_smith: I prefer Linux for the package management and XMonad, but having a mac as a fallback doesn't hurt...

2:07 justin_smith: bitemyapp: now that you've helped me once, beware, I may be coming to you asking for geometry / space partitioning / packing algorithm help

2:09 bitemyapp: justin_smith: algorithms are probably my weakest point, but you know, why not? maybe I'll learn something.

2:09 justin_smith: it'll need to be another day

2:10 bitemyapp: sure.

2:12 justin_smith: good night

2:13 bitemyapp: justin_smith: night night

2:39 ambrosebs: final call! 20m left! http://www.indiegogo.com/projects/typed-clojure/x/4545030

3:22 brainproxy: congrats, ambrosebs!

3:22 ambrosebs: brainproxy: thanks!

3:43 bitemyapp: ambrosebs: grats :)

3:44 ambrosebs: bitemyapp: thx :)

6:22 noncom: in order to organize a proper bi-directional communnication with core.async, do I have to create 2 channels? one for direction A->B and the other - for B->A, is this idiomatic?

8:38 mattrepl: If any NoVA residents outside the beltway want to carpool to Clojure/conj, get in touch

8:41 john2x: for those who hate parentheses https://github.com/one-more-minute/chiara

8:44 tbaldrid_: noncom: yes, you need two channels, and there's several ways to do this, but the way you mentioned is fine

8:49 noncom: tbaldrid: cool! thanks!

9:00 TimMc: ambrosebs: Why did I only hear about the campaign just now?

9:03 llasram: TimMc: A tragic failure on the part of the community. Although I'm really not sure how you missed it :-)

9:04 ambrosebs: TimMc: :)

9:06 pjstadig: mattrepl: cool, you'll be at the conj?

9:06 mattrepl: i'm driving up tonight and going to the scheme workshop tomorrow

9:07 ambrosebs: man I wish so badly I was going to scheme workshop

9:07 mattrepl: pjstadig: yep! nice. let me know if you need a place to crash.

9:07 TimMc: Of course, if I subscribed to the ML, I'd hear about more of these things.

9:08 pjstadig: ambrosebs: are you going at least be at the conj?

9:08 ambrosebs: pjstadig: no

9:08 pjstadig: ambrosebs: oh :(

9:09 ambrosebs: I think I've had my share of Clojure-related success this year. Next year!

9:10 pjstadig: ambrosebs: hehe, yeah you've had a good year :)

9:10 ambrosebs: I actually submitted a talk but it was rejected

9:11 Might have been able to attend, but I decided to only crowdfund one thing at a time ;)

9:19 seangrove: Idead #4298: DoS attack the ml via questions re: licenses.

9:31 noncom: if i want to subscribe a channel to several topics within core.async, do i have to do the corresponding amount of (sub)s ?

9:37 tbaldrid_: noncom: yes

9:39 rstandy: what book would the clojure community would suggest to a CL guy coming from CL+Emacs+SLIME

9:39 ?

9:44 pjstadig: rstandy: maybe "Joy of Clojure"?

9:44 there aren't a ton of clojure books, nor is any of them targeted specifically at CLers

9:44 but that one is generally considered a good "second" book for someone who knows clojure/lisp

9:56 rstandy: pjstadig: thanks for your suggestion!

9:56 another question: are cidar ritz modes compatibles?

10:01 noncom: tbaldrid: i am making a gui which consists of a hierarchy of elements (much like swing or any other), and am coming to a design where each element must have 2 messaging cycles: 1) the channel-out & channel-in which go outwards the element, to the upper layers of hierarchy and 2) the channel-out and channel-in which go "inside" the element, to the lower layers of hierarchy.

10:01 is that ok or am i overcomplicating?

10:03 dnolen: tbaldrid_: it may be possible that go blocks need more help from the CLJS compiler - currently we only use vars to generate source map information

10:04 cark: ddnolen : oh you're there, let me take the chance to Thank you for your very quick fix from cljs 2024 to 2030

10:06 tbaldrid_: dnolen: yeah, I figured I'm missing something like that.

10:06 dnolen: tbaldrid_: I think this also why setting breakpoints at times is a bit finicky

10:07 tbaldrid_: noncom: I tried something like that, and was pretty happy with it. A pub for events coming out of a widget, and a pub for events going in.

10:07 noncom: nice!

10:07 tbaldrid_: dnolen: yeah, the meta-fix branch seems to have metadata on all call forms, but not perhaps on all vars.

10:07 dnolen: tbaldrid_: yeah we definitely need that information on vars

10:08 tbaldrid_: source mapping was really bad until the tools.reader started providing line/col info on symbols

10:08 tbaldrid_: dnolen: what would be cool would be if line/col info defaulted to the most recently executed form. So it'd be nice if this worked: ^{:line 42} (= 1 (+ x y))

10:09 dnolen: it'd be nice if line 42 applied to both the inner and outer forms.

10:09 dnolen: tbaldrid_: as far as I know this is true for tools.reader

10:10 tbaldrid_: and every symbol there will have that :line information + :column

10:13 tbaldrid_: dnolen: I'm seeing that, in my debug output. Every var that originates from the source has metadata, but new code generated by the macro (state transition code) does not have metadata on the symbols.

10:13 dnolen: tbaldrid_: so if you splice in the symbol it loses it's metadata?

10:14 tbaldrid_: that doesn't make sense to me as :tag etc. works just fine etc.

10:17 tbaldrid_: no, that is fine. but much of the core.async blocks is auto generated code. So things like state transitions, new state creation, etc, are generated without any metadata.

10:47 dnolen: so I move metadata to vars, updated to the latest version of cljsbuild and source maps work much better, I'll commit changes later today when I have the time

10:47 dnolen: I have about 50% source map coverage in the core.async tests now.

10:51 dnolen: tbaldrid_: excellent!

10:54 tbaldrid_: I'll try your changes plus tweaking how we generate source map info in cljs.compiler to see if we can get better coverage

11:01 seangrove: Goodness, it's been such a long time since I got to play with SOAP, I can't even remember why I would avoid it now...

11:03 nDuff: seangrove: Heh. The available Python bindings to SOAP are pretty much universally awful; it's not as amenable to dynamic use (as opposed to ahead-of-time code generation) as one might want.

11:03 seangrove: ...but beyond that? *shrug*. Been a long time for me too.

11:05 jared314: seangrove: SOAP, some good ideas drowning in a sea of incompatible vendors and XML formats

11:09 seangrove: clojure.data.xml still the way to go for xml in clojure?

11:21 amoe: hello, I'm looking for a clojure book that has good exercises (with answers). can anyone recommend one? I am new to clojure but experienced with java and lisp.

11:21 seangrove: Honestly I blame technomancy for all of Salesforce's convoluted APIs and documentation

11:21 swarthy: amoe: not a book but 4clojure.com is what you're looking for in terms of exercises

11:22 hyPiRion: amoe: while not a book, 4clojure.com is a good webpage for exercises

11:22 ah, swarthy beat me to it

11:22 swarthy: hyPiRion: lol, but now we have made it sound authoritative!

11:22 seangrove: He works at a company that is at least vaguely associated with them, and he also made lein, which is clearly a beautiful piece of work meant as penance

11:22 indigo: Hahah

11:22 hyPiRion: ~4clojure

11:23 clojurebot: Titim gan éirí ort.

11:23 hyPiRion: clojurebot: 4clojure is the place to go for Clojure exercises

11:23 clojurebot: c'est bon!

11:23 joegallo: seangrove: causality violation. he wrote leiningen before he worked for salesforce/heroku

11:23 hyPiRion: ~4clojure

11:23 clojurebot: 4clojure is the place to go for Clojure exercises

11:23 hyPiRion: there we go, now we are 3

11:24 amoe: thanks swarthy, hyPiRion

11:24 swarthy: lol

11:24 amoe: there are great books too. Clojure Programming, Programming in Clojure, Web Development in Clojure, etc.

11:24 amoe: just check Pragmatic Programmers and O'Reilly for the Clojure books. They are all current sold by one of those two I believe.

11:24 danneu: Typed-clojure is huge when you have a lot of java interop (crypto, in my case). Can't imagine writing this without it.

11:25 I've been playing with it

11:26 seangrove: joegallo: I can probably work around that in my desire to assign a face to this formless mishmash of docs and code

11:26 llasram: danneu: If you just want something informing you of Java type mismatches, turning on reflection warnings does enough for me

11:28 danneu: llasram: it's mostly for my mental model. is this an ECParameterSpec, ECCurveParameters, ECCurve, etc

11:28 i don't know how else to handle that beyond marking up my code with layman's typed-clojure anyways

11:29 llasram: Well, that's about what regular core Clojure JVM type hints amount to

11:29 (fn ^ReturnType [^ArgumentType arg] ...)

11:30 jcromartie: hey, does anybody have an extra room for the Conj?

11:30 not necessarily *a* room but any kind of room

11:30 danneu: llasram: yeah, but i've found that those make the codebase hard to read, especially since ^Annotations are purely just for me while i'm writing it

11:31 llasram: danneu: Fair enough, if that's your situation. But if you're doing Java interop and your code is performance sensitive, then they're not just for while writing it -- without them every Java method call will devolve to reflection

11:32 danneu: right, i'd add them once the namespace is farther along

11:32 i dont start out solving reflection problems

11:33 maybe i just need to try a new color theme

11:37 ambrosebs: fwiw Typed Clojure will complain loudly if it finds reflection

11:37 ie. it's a type error

11:37 llasram: Ah, cool

11:38 ambrosebs: also type syntax is more expressive than type hints

11:38 I find it useful to completely separate the two things

11:39 IMO type hints aren't the best documentation

11:40 danneu: is your annotated code open source?

11:42 danneu: ambrosebs: it will be. i will try to get feedback when i release it since i'm new to typed-anything

11:43 ambrosebs: danneu: great. I'm just interested in how you use interop with core.typed

11:48 danneu: i have naive/modest needs and just use it on this first-pass to remove all my type-related comments

11:51 ambrosebs: can you point to any example projects i can check out?

11:52 ambrosebs: danneu: https://github.com/typedclojure/core.typed-example

11:54 danneu: https://github.com/kshramt/sicp

11:54 danneu: great, thanks

11:54 ambrosebs: not much else that I'm aware of, except for internal annotations in core.typed itself

11:55 (there's lots in core.typed)

12:02 meingbg: I'm looking for a framework/language/utility/setup for a web application that would allow automatic updates to propagate from UI all the way to db and to other UI elements affected. I don't know where to begin.

12:02 seangrove: meingbg: Well, pedestal might be a fit, but it's a biiiig leap for most people from what they're used to

12:03 You're asking for quite a bit in that small paragraph, expect it to take some work to udnerstand the different approaches

12:07 bja: anyone here use lein-droid?

12:08 I was hoping to figure out a way to force a UI redraw without navigating to other open apps

12:08 Morgawr: small question, I have a function that needs to test on the data type passed as a parameter, I want to know if the second argument is a list/vector or something else. Either list or vector is fine but seq? returns false for a vector

12:08 what should I use to test for both vector/list?

12:08 S11001001: Morgawr: sequential??

12:08 lazybot: S11001001: Definitely not.

12:08 justin_smith: bja: what is the ui toolkit? most have an explicit repaint message you can send to elements, that will propagate to their children

12:08 S11001001: lazybot: you like

12:09 s,k,,

12:09 Morgawr: S11001001: thanks! that's exactly what I needed

12:09 justin_smith: bja: for example in seesaw it is (repaint target)

12:09 Morgawr: what's the difference between ISeq and Sequential interface?

12:09 bja: justin_smith, it's neko. I'll check for something similar

12:10 S11001001: Morgawr: well, I'd start with `seq' doing nothing to non-empty ISeqs

12:10 maybe

12:10 ,(let [x '(42)] (identical? x (seq x)))

12:10 clojurebot: true

12:10 S11001001: ,(let [x '[42]] (identical? x (seq x)))

12:10 clojurebot: false

12:10 S11001001: ,(let [x '()] (identical? x (seq x)))

12:10 clojurebot: false

12:11 sritchie: cemerick: saw the new oauth2 workflow!

12:11 great stuff

12:11 S11001001: Morgawr: that's not to say that sequential circumscribes the domain of `seq'; for that, you need seqable? from core.incubator

12:11 or wherever it is now

12:11 Morgawr: I see

12:12 cemerick: sritchie: that's ddellacosta :-)

12:12 Morgawr: S11001001: thanks

12:12 justin_smith: bja: I see neko.listeners.vier/on-layout-change - something you register there should get called when the window is created if it is anything like other toolkits

12:12 sritchie: had to shout out to someone :)

12:12 so, the oauth2 workflow looks like it's for authenticating with third party oauth services -

12:13 justin_smith: s/vier/view

12:13 sritchie: cemerick: I'm trying to absorb as much as I can about how to authenticate my REST API, now that it's come time for an iPhone app

12:14 cemerick: is oauth2 too crazy to use for auth between different clients that I control? (web and iOS). trying to set up best practices for an API down the road

12:14 justin_smith: sritchie: doesn't oauth implicitly use a third party for auth? I thought that was pretty much the point of oauth

12:15 sritchie: justin_smith: haha, that's my question - do github or facebook use their own oauth endpoint for login?

12:15 or do they have a separate security scheme for apps that they control

12:17 cemerick: sritchie: oauth is generally only used to distribute authority to third parties. I'd be really surprised if anyone used it internally.

12:17 openid has quite a presence w.r.t. single sign-on within an org (e.g. amazon!), but oauth doesn't make a lot of sense there

12:18 sritchie: cemerick: so oauth is not the way to go for, say, offering up a JSON api for a user's own data

12:19 noncom: can be a publicated channel in core async used as a simple (non-publicated) channel, along with its publications? in other words, will it be possible to read/write from/to it like it is a normal channel?

12:20 cemerick: sritchie: I don't *think* so. They already have an easy way to get authorized (form login?), so you just point them at the corresponding URL.

12:20 sritchie: cemerick: so stick everything behind SSL, and go with basic auth

12:20 cemerick: yeah, that'd work too

12:21 I try to stay away from oauth as much as possible

12:23 indigo: cemerick: Oauth isn't too bad

12:23 justin_smith: my impression is oauth is for a) when you want a user to give your app access to their credentials with a third party b) when you want a user to authenticate based on a third party's scheme (to avoid creating extra accounts, convenience for the end user)

12:27 indigo: justin_smith: Or when you're making an API

12:28 justin_smith: well, implicitly you are providing some service, likely an api, that requires said authentication to ensure the wrong people don't get the wrong data

12:29 or some other resource like CPU power or disk space

12:32 cemerick: indigo: I think you'll find that to be a pretty lonely assessment :-)

12:34 augustl: are there any logging systems where I can log both the reuqest and the response and somehow link the two?

12:34 with traditional file logging, the only thing I can think of is to give each req/res a uuid and put that in the logs

12:34 mikerod: so does calling `vec` on something lazy cause it to be eagerly evaluated?

12:34 TimMc: justin_smith: OAuth2 permits a user to consent to deputizing a software agent to see and/or modify their data.

12:35 justin_smith: TimMc: yes, like I said in case a, you want a user to let you use their data, and oauth2 provides a handy way for them to revoke you that access without changing their password or whatever

12:35 sritchie: TimMc: do you know if anyone's using oauth for their own login?

12:35 tbaldrid_: mikerod: yes, vectors are not lazy so calling vec on a lazy seq will force evaluation

12:35 sritchie: like, for their own iOS app?

12:35 TimMc: justin_smith: Authentication with OAuth2 is tricky and disrecommended; authorization is the idea.

12:35 mikerod: tbaldrid_: that was what I was thinking

12:35 meingbg: seangrove: Thanks for the hint.

12:35 mikerod: Why is there a class called clojure.lang.LazilyPersistentVector ?

12:36 the lazy + vector words sound contradicting

12:36 TimMc: sritchie: I am completely unfamiliar with mobile ecosystems.

12:36 mikerod: It doesn't make a vector until you start modifying it.

12:36 technomancy: mikerod: the value isn't lazy; the persistence is

12:36 indigo: cemerick: Haha, I guess

12:40 justin_smith: TimMc: interesting, I see it used for authentication a lot, and have had clients ask for it just for authentication, not needing any authorization

12:40 mikerod: technomancy: TimMc Hmmm, I'm working on understanding those answers :)

12:41 TimMc: Sorry, that was a very sloppy answer.

12:42 mikerod: Or rather, it gives you backa PersistentVector that has all the items just sitting in an array, and further conjing may structure that array into a 32-way tree.

12:43 It looks like if you give it 32 or more items there's nothing lazy about it: https://github.com/clojure/clojure/blob/clojure-1.5.1/src/jvm/clojure/lang/LazilyPersistentVector.java

12:44 mikerod: TimMc: Ah, that makes sense to me. Possibly "lazily persistent"

12:45 TimMc: &(let [backing (into-array (cons 5 (repeat 20 nil))), v (clojure.lang.LazilyPersistentVector/createOwning backing)] (aset backing 0 7) v)

12:45 lazybot: ⇒ [7 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil]

12:45 TimMc: &(let [backing (into-array (cons 5 (repeat 50 nil))), v (clojure.lang.LazilyPersistentVector/createOwning backing)] (aset backing 0 7) v)

12:45 lazybot: ⇒ [5 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil]

12:46 TimMc: See how when I gave it the larger array, modifying the initial array no longer allows me to mutate the vector?

12:49 mikerod: Yes, that is interesting

12:49 Sort of unexpected, that there is a "window" where the backing array can continue to mutate the "persistent" vector

12:50 TimMc: Yeah. :-(

12:50 mikerod: Good to know at least, hah

12:56 technomancy: do you get those kinds of vectors from any surprising places, or do you have to create them specifically?

12:58 TimMc: clojure.core creates some, as does clojure.string and some .java files

12:58 RT, EdnReader, LispReader, AMapEntry

12:58 technomancy: huh

12:59 danneu: How do you fully-qualify a Java instance method or a constructor?

13:00 technomancy: what would it mean to qualify an instance method?

13:00 jcromartie: danneu: just use the full package.class name

13:00 or import it

13:00 TimMc: &(let [backing (into-array (cons 5 (repeat 20 nil))), v (vec backing)] (aset backing 0 7) v)

13:00 lazybot: ⇒ [7 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil]

13:00 TimMc: technomancy: vec, of course...

13:02 clojure.string uses safe array input

13:03 RT/vector is another entry point

13:06 arrdem: offtopic: anyone know a good writeup on getting emacs set up for scala?

13:09 noncom: anyone familiar with cor.async here?

13:10 nDuff: ~anyone

13:10 clojurebot: anyone is anybody

13:10 TimMc: clojurebot: forget anyone |is| anybody

13:10 clojurebot: I forgot that anyone is anybody

13:10 TimMc: clojurebot: forget anybody |is| anyone

13:10 clojurebot: I forgot that anybody is anyone

13:10 TimMc: I hate that inference engine.

13:10 arrdem: ~inventory

13:11 clojurebot: I am carrying 0) a poorly-calibrated inference engine, currently leaking 1) a well-worn copy of clojure 1.2 tucked deep away inside a classloader 2) the last shreds of what was once my sanity

13:11 rkneufeld: arrdem: I've been using scala-mode and it seems to work pretty well.

13:11 arrdem: at least it's labeled as leaking...

13:11 mdrogalis: noncom: What's up?

13:11 arrdem: rkneufeld: just core scala-mode? what's setup with sbt like? (complete scala nub)

13:12 nDuff: noncom: "anyone familiar" is not a very useful question, because folks can't know how familiar they need to be to answer your _real_ question

13:12 noncom: see this refheap: https://www.refheap.com/20774 i expected the output to be at least to some degree predictable, however, it looks like it is completely random..

13:12 nDuff: noncom: ...so just ask the real question.

13:12 rkneufeld: arrdem: I make pretty heavy use of tmux, so I do everything apart from editing there.

13:12 mdrogalis: Ah, sorry. I'm not familiar with the pub/sub stuff.

13:13 arrdem: rkneufeld: ok. so you aren't trying to use any sort of compiler/repl embedding in emacs.

13:13 rkneufeld: arrdem: I am not. Is there one people commonly use?

13:13 arrdem: rkneufeld: idk, I can't seem to find one :/

13:14 noncom: so my question is: how does that happen? why soring on topic does not work? why it pushes things to wrong reads?

13:14 bitemyapp: arrdem: I use scala-mode2 + ensime.

13:14 arrdem: bitemyapp: yeah ensime looks like what I need to get running...

13:14 rkneufeld: http://aemoncannon.github.io/ensime/ is the closest thing it seems

13:14 rkneufeld: bitemyapp: thanks

13:14 bitemyapp: arrdem: https://github.com/hvesalai/scala-mode2

13:14 rkneufeld: for what?

13:15 arrdem: you want scala-mode2 and ensime. trust me.

13:15 arrdem: also: https://github.com/hvesalai/scala-mode2/issues/58

13:15 rkneufeld: bitemyapp: Didn't know about scala-mode*2*

13:15 bitemyapp: rkneufeld: yeah it's great.

13:15 I poked the owner to upload it to marmalade, looks like Nic Ferrier is going to do it for him :)

13:16 arrdem: bitemyapp: is the top of tree ensime working for you? I can't seem to get the ensime server started.

13:18 TimMc: hiredman: I think "anybody" and "anyone" have both been defined as "Just a heads up...", so the inference engine periodically says "anyone is anybody". Does that sound right?

13:19 noncom: sorry there was a little typo in one of the messages i am sending (a instead of b), i fixed it here: https://www.refheap.com/20775 however, that does not really change much. things become even more stranger where you can see that even the amonut of returned results can differ! (see run #4)

13:22 augustl: are there any logging libraries out there with levels and different appenders (memory, stdout, file, .... ?) but where I can create different instances? I want a separate req/rep log, a separate log file for elasticsearch/indexing operations, etc. I found https://github.com/ptaoussanis/timbre but there's only one single global instance it seems

13:24 arrdem: bitemyapp: cheers. ensime online :D

13:24 noncom: so i cannot invent reasoning for what is happening there. to me it seems wrong. how do i predict outcomes on an even larger scales? if there is some logic behind that, maybe someone can explain, because there is nothing about that in the docs or examples... maybe i'm missing something..

13:25 noidi: augustl, how about using https://github.com/clojure/tools.logging with e.g. SLF4J?

13:27 augustl: noncom: hmm yeah just realized you can specify per-namespace appenders in the slf4j config files

13:28 noncom: augustl: been thinking of noidi, i guess

13:29 nDuff: do you have an idea on why do :a messages get to go sometimes to ch1 and sometimes to ch2?

13:33 nDuff: noncom: you're making it non-deterministic by reading from ch1.

13:33 noncom: if you stopped reading from it, I'd expect everything to go to ch2.

13:35 noncom: so i cannot use ch1 as a channel if it has subscriptions because it ruins subscriptions... but then :c messages get lost? how do i then collect all messages BUT those which have a specific topic?

13:36 in other words, how do i collect all the messages which do not have an assigned known topic?

13:37 bitemyapp: arrdem: very good.

13:37 nDuff: noncom: I don't know that the feature you're asking for existed in any pub/sub framework I've used in the past. (Don't know that it didn't, but it's not something I remember).

13:37 noncom: i see..

13:37 * nDuff pokes at core.async's implementation.

13:38 noncom: well.. does it seem unnatural or a bad design?

13:39 nDuff: noncom: *shrug*. You might ask if a patch adding a :else (or such) would be accepted.

13:40 noncom: ok, we'll see... thanks!

13:41 nDuff: (because https://github.com/clojure/core.async/blob/76317035d386ce2a1d98c2c349da9b898b480c55/src/main/clojure/clojure/core/async.clj#L807 pretty clearly doesn't support that feature at present).

13:42 noncom: yeah, looks so..

13:42 even specified explicitly (to some extent)

13:51 tbaldrid_: dnolen: pushed latest changes to meta-fixes on core.async. I think better CLJS support would help quite a bit.

13:52 dnolen: tbaldrid_: excellent - will poke around likely tomorrow on train to Conj

13:52 tbaldrid_: dnolen: cool

13:54 justin_smith: in the spirit of Let Over Lambda, someone should implement a Request Over Functor Lambda Mondad Aspect Object

13:56 mdrogalis: You can have a laugh at my expense, justin_smith. I typed it out in acronym form and *then* realized it.

13:57 hiredman: /win 15

13:58 justin_smith: I am sure there is something actually useful that we could pigeonhole into that acronym

14:01 bitemyapp: justin_smith: is that a challenge?

14:01 mdrogalis: The Datomic Inference Console Kit.

14:02 hyPiRion: mdrogalis: oh dear

14:02 justin_smith: bitemyapp: probably something along the lines of what we were talking about the other night regarding parameterized modules

14:03 mdrogalis: hyPiRion: I'm really not cut out for marketing.

14:04 hyPiRion: That's like the discussion we had here, where cond-> was about to be named cont->, but uh, pronunciation risks

14:04 Segabyte: AimHere, you are even here.

14:04 Why are you everywhere.

14:05 mdrogalis: hyPiRion: Yeah, everytime I used to see a variable named "cont" I'd just shake my head.

14:05 ~cont

14:05 clojurebot: Pardon?

14:06 mdrogalis: Yeah, I think we'll just let that one rest in peace.

14:06 bitemyapp: justin_smith: not really. Applicative functors can solve the same problem plus a bunch of others and they're pretty simple.

14:07 there's a lot of ways you can skin that cat without overcomplicating your compiler.

14:08 patchwork: Let's leave the cats alone. They are better with skin

14:08 Furrier

14:10 justin_smith: bitemyapp: how did I know googling for that was going to take me to a page of haskell docs?

14:14 bitemyapp: justin_smith: so read the Haskell docs.

14:14 justin_smith: yeah, just saying :)

14:19 egghead: what's the best way to concat a bunch of files into a target file?

14:19 bitemyapp: justin_smith: not my fault Haskellers are the main ones pushing things forward.

14:19 justin_smith: I try to get Clojure people on board with Fluokitten :)

14:19 egghead: if I use 'spit' repeatedly does that mean I have to read all the contents into memory before writing?

14:19 technomancy: egghead: c.j.io/copy into a single inputstream I guess?

14:19 justin_smith: egghead: spit has an append option

14:20 bitemyapp: egghead: (spit "yo-file-yo" ya-data :append true)

14:21 justin_smith: egghead: http://sprunge.us/WLFW?clojure


14:21 bitemyapp: justin_smith: do you have emacs integration for that?

14:22 justin_smith: bitemyapp: I use a shell script, it sucks up selection, pastes it, puts the url in selection

14:22 (x11 selection that is)

14:22 egghead: justin_smith: ya but I don't want to read all the files into memory before writing them out

14:22 justin_smith: so, it's just copy text, run script, paste url

14:23 egghead: then do it with clojure.java.io/copy as technomancy was suggesting

14:23 bitemyapp: justin_smith: yeah refheap.el works nicely: https://www.refheap.com/20781

14:23 especially given how ridic lazy I am

14:23 egghead: so a bunch of (copy input-file (writer my-output-file)) ?

14:24 justin_smith: bitemyapp: nice, I didn't know that existed

14:27 bitemyapp: justin_smith: refheap.el has a paste region and paste buffer

14:27 so REPL pastes are practical.

14:27 justin_smith: I se that

14:27 *see

14:28 mpwd: Is anybody using Storm? I am trying to figure out how to setMaxSpoutPending on a topology

14:28 Using the clojure DSL

14:28 justin_smith: bitemyapp: well, with my sprclj script I can paste from a repl in emacs, or a repl in a terminal, etc. it only relies on something being copied, not being in emacs. Though realistically I am usually in emacs

14:28 seangrove: mpwd: There's also a storm users' channel in case no one here knows

14:28 #storm-user, that is

14:29 mdrogalis: hyPiRion: The Clojure Object Coordination Kernel

14:29 justin_smith: bitemyapp: http://sprunge.us/JRcg


14:29 mdrogalis: I'm available for all marketing positions in the US.

14:30 bitemyapp: justin_smith: fuck monkey? really?

14:30 justin_smith: the machine is a system76 bonobo

14:30 it was the logical hostname

14:30 bitemyapp: jesus christ lol

14:31 marco: How do I close an issue on JIRA? I can't seem to figure it out

14:38 lpvb: "Use good names, and don't be afraid to collide with names in other namespaces. That's what the flexible namespace support is there for."

14:38 what does it mean by flexible namespace support

14:38 if you have two different libraries in leiningen of the same name (different github projects) what do you do?

14:38 bitemyapp: (require '[muh.fuckin.namespace :as muhfucka])

14:39 (muhfucka/look-at-this-shit :aint :it :awesome?)

14:39 lpvb: but there are two muh.fuckin.namespace

14:39 bitemyapp: lpvb: different ns collision.

14:39 they're talking about look-at-this-shit

14:39 not the namespace itself

14:39 if your actual namespace collides, you're a fucking moron.

14:40 lpvb: https://github.com/bitemyapp/brambling/blob/master/src/brambling/moves/ya/bits/migrate.clj#L1

14:40 lpvb: collide with that and you deserve what you get.

14:40 the point is to keep the NAMES inside of the namespace brief but descriptive.

14:41 justin_smith: and the namespace name resolves collision issues

14:42 lpvb: what if someone else makes a library called seesaw

14:42 justin_smith: then make other.seesaw

14:42 lpvb: there'd be two namespace seesaw.core

14:42 how?

14:42 clojurebot: with style and grace

14:42 technomancy: lpvb: then they'll get lynched if they ever come within 100m of a conj

14:43 lpvb: if someone else makes a lib called seesaw then they're either a troll or they don't know what they're doing. no one would use it.

14:43 lpvb: okay, that's what I was looking for, the convention is just to avoid namespace conflicts

14:44 llasram: Some people do use Java-style namespaces, where the first components are the reverse-label form of a domain they own

14:44 It's not that common though

14:47 bitemyapp: lpvb: they'll get lynched and then burnt.

15:02 TimMc: mdrogalis: I still use "cnt" as a for-loop limit value, but I worry about one day pronouncing it phonetically instead of as "count".

15:03 I should probably use lim or max instead.

15:03 mdrogalis: TimMc: Just do yourself a favor and don't do it :P

15:03 I use 'k' when I feel mathy.

15:03 TimMc: Oh, but what if I'm building up a count of something?

15:03 how-many is long

15:04 justin_smith: k

15:04 TimMc: Hrm. K.

15:04 justin_smith: or idx

15:04 if the count is a position, idx is good

15:04 or even i or index

15:05 TimMc: "tally"

15:05 justin_smith: sum

15:05 llasram: TimMc: So fancy!

15:05 justin_smith: no, sum assumes quantities

15:06 arity ?

15:07 llasram: Wow, cider does not like it when you visit namespaces containing functions w/ the same names as certain clojure.core function

15:07 S11001001: TimMc: use de Bruijn indices instead of named bindings and it'll never be a problem :)

15:08 TimMc: yes, yesssss...

15:09 mdrogalis: TimMc: It's a fun thought experiment to substitute in other variables that are only one letter shy of a swear word.

15:09 TimMc: but make sure to skip indexes 4 and 13 because those are considered unlucky numbers in some countries

15:09 muhoo: what do you guys use for testing db-backed web app with dummy data? i've got my datomic connection in an atom. there's code in a few places that pulls the connection out of there, and startup code that populates it. i'd like to be able to run tests in the repl without stomping on ther "real" db. is this a with-redefs? or change the way of managing that state somehow?

15:10 seems like there a bunch of ways to do it. i'm curious what best practices is.

15:10 bitemyapp: muhoo: environment variables yo.

15:10 clojurebot: Huh?

15:10 bitemyapp: muhoo: I create test databases using in memory instance (default and test config) but production/dev have different configs.

15:11 justin_smith: I'd create a test specific db config, and wipe the db and initialize it as a pre-action

15:11 bitemyapp: I do something like that, but it's a bit nicer because I don't really have to be test specific, ephemeral and loaded from fixtures is the default.

15:12 permanence is the "unusual" case and is configured for in prod/dev

15:12 justin_smith: muhoo: or, with bigger stuff, in practice I have an "undo" for everything the test does, a test specific db, and then I recreate the test db from a script if my unit tests totally hose it, otherwise they clean up after themselves

15:12 using pre/post test actions in the test ns

15:12 muhoo: i do use environs, and there are different configs with different db setup strings. i'm curious how to have two db's going at once, one real db which the main server accesses, and a second in-mmeory for test, but this global atom is getting in my way

15:13 justin_smith: muhoo: you just said it yourself, global atoms are the problem

15:13 muhoo: also, it' datomic so there's no undo. but it's trivial to create an in-memory dummy db

15:13 justin_smith: you need re-entrant config

15:13 muhoo: justin_smith: that sounds interesting

15:13 justin_smith: bitemyapp will talk your ear off about it if you show an interest :)

15:14 muhoo: a function instead of an atom.

15:14 and it can pull from wherever based on evironment vars

15:14 justin_smith: right

15:14 bitemyapp: yeah, reproducible, clean code is a bit of a thing for me.

15:14 also, composable configuration.

15:15 muhoo: in a web app, the db handle is the one bit of global state i can't seem to shake, along with session store.

15:15 cemerick: dnolen: If I have a codebase that compiles without warnings, tests well under :simple (for example), but fails under :advanced with e.g. "TypeError: 'undefined' is not a function (evaluating 'Hh.n()')", is that a reasonable point at which to think I'm hitting a GClosure bug?

15:15 justin_smith: muhoo: my groundhog lib records and replays requests, including any cookie based session state

15:15 muhoo: dbs are the real gotcha, yeah

15:16 muhoo: justin_smith: right,, i saw that, that'll be useful

15:16 dnolen: cemerick: seems weird, turn on source maps ;)

15:16 bitemyapp: datomic makes it easier than usual to do a good job with this stuff, the in memory databases are magical for testing.

15:16 cemerick: dnolen: Yeah, I did, but will need to read up on them. Was expecting a human-readable output. :-)

15:16 justin_smith: with sql there is also h2, which has an in-memory variant that is easy to use

15:16 muhoo: bitemyapp: it is! i'm using it ina few places. but i want to test the api from the http side, and that means a dummy server

15:16 justin_smith: but then you may need an h2 specific adapter, which may not be worth your time

15:17 bitemyapp: muhoo: no it doesn't.

15:17 muhoo: when I need to test my API, I do one of a few things:

15:17 1. I start my HTTP server as a "resource fixture" in my test, then test it accordingly

15:17 dnolen: cemerick: that bug could crop up for a number of reasons are you on 2030?

15:17 muhoo: bitemyapp: right, that's what i mean bya dummy server

15:17 bitemyapp: 2. or I simply have an "identity" export content type for my API and call them like clojure functions.

15:18 muhoo: it's not a dummy server, that implies mocking.

15:18 muhoo: there's no mocking, it's the actual service running.

15:18 muhoo: DON'T MOCK ME MAAAAAN

15:18 ok no mocking, this'll be a polite test.

15:19 dnolen: cemerick: :source-map "foo.js.map" and you should be able to see what went wrong as long as :output-dir is set to something readable by your web setup.

15:19 cemerick: there are some issues still around relative paths.

15:19 which actually reminds me

15:19 cemerick: dnolen: same problem on builds from 2014 - 2036

15:20 dnolen: This is automated simple-check testing, don't have anything wired up to a web frontend at the moment :-/

15:20 muhoo: bitemyapp: good call, could just issue ring requests.

15:21 justin_smith: muhoo: if you need the request to have a valid body, there are some useful functions in groundhog for creating it out of ascii or a byte stream

15:21 gf3: dnolen: You recently tweeted about a new core.async article that your either wrote or enjoyed, I can't seem to find the link though, do you still remember it?

15:21 dnolen: CLJS users, I thinking that :source-map and :output-dir will always specifying something relative to it :output-to.

15:21 muhoo: justin_smith: i ould try that too, thanks.

15:22 dnolen: this doesn't seem problematic to me as :output-dir is about caching and :source-maps don't matter outside dev

15:22 hiredman: the lack of a simple check session/unsession for the conj makes me sad

15:22 bitemyapp: muhoo: precisely, I just make fake ring requests and ask it to export the literal data structure back

15:22 dnolen: cemerick: then make dummy index.html file and include your output js, source maps will magically work

15:22 hiredman: I want someone to tell me how to use it

15:22 bitemyapp: muhoo: there are alternative exporters for JSON and templates, but there's always an "identity" export so I can just get data :0

15:22 er, :)

15:22 hiredman: becuase I haven't even looked at the readme

15:23 dnolen: cemerick: see core.async for a simple example

15:23 cemerick: dnolen: oh, it doesn't require browser-repl shenanigans?

15:23 dnolen: cemerick: absolutely not

15:23 muhoo: bitemyapp: i'd have no problem getting json back and then cheshire decoding it again in order to (is (= it

15:23 * bitemyapp shakes head

15:23 bitemyapp: muhoo: always provide an identity export. it's nice.

15:23 dnolen: cemerick: Chrome & WebKit Nightly allow source maps even if you're looking at an index.html with file:// protocol

15:23 cemerick: dnolen: ah, cool, thanks, will try. Will need to read up. Been ignoring source maps like you avoid REPL stuffs. ;-D

15:24 bitemyapp: muhoo: sure, test the JSON export if you want, but always provide an identity export.

15:24 it lowers the friction substantially.

15:25 muhoo: duly noted

15:32 mdrogalis: Spent *most* of the day coming up with lewd Clojure acronyms. Thanks, whoever started this. D:

15:32 justin_smith: any time!

15:33 mdrogalis: IT WAS YOU D:

15:33 justin_smith: I was more doing "bad lulzy acronyms" rather than lewdness really

15:33 it emerged as a behavior of the complex system we call our channel

15:34 mdrogalis: Cue musical.

15:35 muhoo: lol is a very overloaded acronym. land of lisp, let over lambda, gee that was funny, league of legends, etc

15:36 lisp on lines, also for the CL folks

15:37 AimHere: The UK Prime Minister thought it was 'Lots of Love' when tabloid journalists used it when texting him

15:39 `cbp: on http-kit websockets, the toString of a channel includes the ip of the client but sometimes the ip is NULL. Anyone know why that might be?

15:50 cemerick: dnolen: is there a 'go to original symbol' or something in the sources tab once the source map has been loaded

15:56 TimMc: cemerick: I think you have to enable source mapping as an option.

15:57 (Never done it myself; I just recall reading this somewhere.)

15:57 cemerick: TimMc: Yeah, it's on; I see all the original .cljs sources in Chrome, etc., just haven't found any "go to original/go to outputted symbol" commands, etc.

15:58 They may not be in Chrome; that's just what I happen to need at the moment, and I see there are some demos of that functionality on some source maps tutorial pages...

16:05 egosum: does anyone know of databases that behave similarly to datomic? Or dbs which can be queried in a way similar to e.g. unification? E.g. with dataomic type querying, but forget the deductive part of the DB?

16:12 technomancy: hiredman: there was a simplecheck unsession at strangeloop; standing room only

16:13 hiredman: technomancy: ah, and here I can't even remember what unsessions(if any?) I did

16:14 poor life choices

16:24 jared314: is there a lein plugin for running post-build bash scripts?

16:24 technomancy: jared314: there's a lein-shell, yeah

16:25 reiddraper: hiredman: yeah, unfortunately I can't make it to the conj, but maybe I can make an intro screencast or something

16:25 jared314: technomancy: that works, thanks

16:26 muhoo: cemerick: i'm looking forward to the day when source mapped staktraces are available in nrepl and nrepl.el

16:26 dnolen: cemerick: if you have an exception in the JS console you can jump to it

16:26 cemerick: same for console.logs

16:26 danneu: How come you can't (.length (byte-array 5)) ?

16:27 cemerick: dnolen: yeah, it only jumps to the generated js

16:28 hiredman: reiddraper: ah, maybe I'll make the right choice unsession wise at another conference sometime

16:28 dnolen: cemerick: you might need to refresh, otherwise something messed up

16:29 cemerick: I tried to fix most causes of this but likely you need a: lein cljsbuild clean + once

16:29 reiddraper: hiredman: heh, that works too

16:29 cemerick: dnolen: did that, but will try again

16:29 dnolen: cemerick: also Chrome some times caches the the source map file and you might need to restart?

16:30 cemerick: that said, there may be issues still for source maps and simple/advanced compiled code

16:30 cemerick: will be looking in to see if we can make it more accurate soon

16:30 seangrove: cemerick: Other thing to check is that the source map is available to your browser at the url it's trying to look it up by, same with the source - it all should be, but a good sanity check

16:30 cemerick: muhoo: Perhaps. I'm generally OK reading generated JS, which is pretty decent when you're using :none/:whitespace/:simple (which is all that is available in the REPL anyway).

16:31 dnolen: cemerick: oh yeah definitely double check that browser can find source map file

16:31 cemerick: seangrove: yeah, I'm seeing the .cljs sources, so the .map file is surely being loaded...

16:32 seangrove: cemerick: And the cljs sources also open up?

16:32 dnolen: cemerick: one way to sanity check is try to try build core.async tests and open those in Chrome

16:32 seangrove: If so, then you've got an interested bug ;)

16:34 cemerick: seangrove: yup. My suspicion is growing that I'm hitting a GClosure bug, so there's that. :-)

16:34 hiredman: is anyone using tools.analyze? I seem to be getting an empty map instead of the tree for the last arg to a recur

16:34 cemerick: muhoo: that said, I'm probably just coping. Better everything would be better :-)

16:34 dnolen: noted

16:35 dnolen: cemerick: so you don't get cljs line numbers if you add a console.log to your CLJS?

16:36 cemerick: dnolen: nope, all references are to foo.js

16:37 dnolen: cemerick: seems unlikely - I would with WebKit Nightly and Chrome Canary

16:37 would check

16:45 muhoo: fwiw, this was necessary in order to make slamhound work: export JVM_OPTS="-Xmx5g -XX:+CMSClassUnloadingEnabled -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=128M"

16:46 otherwise it OOMs permgenspace

16:49 xeqi: cemerick: I can confirm working sourcemaps with cljs 2030, lein-cljsbuild 1.0.0-alpha2, austin 0.1.3 fwiw

16:49 dnolen: cemerick: just tried core.async tests in Safari 7 source maps just work for me.

16:49 cemerick: dnolen: oh, I was never claiming they didn't work :-)

16:50 I've found the area of the problem the old fashioned way, will investigate source maps properly when I'm not trying to bash out a top-of-mind problem

16:51 dnolen: cemerick: sure, but was just trying to figure out what might be causing the issues - otherwise will miss a source map case that's likely to crop up again.

16:51 guns: muhoo: Is there a project that I could clone to test the OOM?

16:51 cemerick: hrm, ok

16:52 dnolen: when I'm finished with this, I'll circle back to the current SHA and dig into sourcemaps

16:52 dnolen: cemerick: thx

16:52 muhoo: guns: not really. it's not an open source project. but it works fine with the incantations above

16:52 it's also a nice space heater too. 799% CPU.

16:53 guns: btw, the case that was causing the oom was lots and lots (like dozens) of unnecessary requires in the ns, which slamhound helpfully removed

16:54 i'd gotten into the habit of just copy/pasting massive require things rather than deal with the annoying class not found errors every time i tried to do anything. finally cleaning it up with slamhound

16:55 guns: muhoo: I've never seen the CMSClassUnloadingEnabled flag; if the problem is simply a lack of heap space, then shouldn't we just advise increasing the max heap?

16:55 justin_smith: guns: permgen != heap

16:55 you can crash from no permgen with literally gigs of heap free

16:56 muhoo: permgen apparently is to do with classloader (i'm still largely jvm ignorant)

16:56 guns: I see

16:56 justin_smith: this is a big clojure problem, because clojure makes more classes than java typically would, so it stresses this part of the jvm design

16:56 permgen is the memory for classes

16:56 guns: and The standard Oracle/Sun VM look on the world is: Classes are forever. So once loaded, they stay in memory even if no one cares anymore. This usually is no problem since you don't have that many purely "setup" classes (= used once for setup and then never again). So even if they take up 1MB, who cares.

16:56 oops

16:57 muhoo: spurious copy/paste, eh?

16:57 guns: that was from the stackoverflow page I was reading up on ÇMSClassUnloadingEnabled

16:57 justin_smith: so every top level let, every fn, etc. we get shitloads of classes in clojure

16:57 muhoo: ah, with lots of anonymous functions permgen will take a beating? interesting.

16:57 justin_smith: and many of them we are never going to use again (depending, of course, on coding style and whether you are using the repl)

16:58 muhoo: lots of functions period, but anon ones are likely to get used once and thrown away and thus we make more of them

16:58 TimMc: guns: Complete with cedilla?

16:58 justin_smith: so yeah, I think the classunloading option should be in the default project.clj

16:58 muhoo: so wait, if i've got a hof that generates a fn, returns a fn, all that gets dumped in permgenspace and not removed ever?

16:59 for every call?

16:59 justin_smith: muhoo: I think so - each fn is its own class

16:59 ToxicFrog: Wait, what?!

16:59 justin_smith: it can be unloaded if you use that option mentioned above

16:59 guns: TimMc: :) I have \eC mapped to Ç

17:00 justin_smith: thank you for the insight

17:00 justin_smith: ,(= (class (fn [])) (class (fn [])))

17:00 clojurebot: false

17:00 justin_smith: two new classes

17:00 both live forever, by default

17:00 muhoo: that's... not good

17:00 justin_smith: this bit me in the ass, HARD

17:01 it was crazymaking

17:01 ToxicFrog: justin_smith: I would have expected that each fn definition is a class, but each closure of that function that gets actually returned is an instantiation of it

17:01 Rather than an entirely new class that is not subject to collection

17:01 If it's the latter, that's bonkers

17:01 justin_smith: ToxicFrog: if the same fn is returned, it is the same class, but if you create the fn in a let (for binding locals) it is a new class

17:01 Morgawr: how do I use when-let to retrieve the value of the test? I mean, I want to test when b != CONDITION but this gives me a true/false result that is bound to 'c', how do I get the value of b?

17:01 * muhoo goes and looks for places where he's got (defn foo [] (fn [] bar)) and looks for signs of impending doom

17:02 hiredman: justin_smith: no

17:02 pjstadig: returning a clojure from a function does not mean you generate a class every time you call the function

17:02 justin_smith: ,(let [lol (fn [] (fn []))] (= (lol) (lol))) ; hiredman

17:02 clojurebot: false

17:02 justin_smith: err

17:03 llasram: Just a new instance

17:03 ToxicFrog: that is to say, I could expect that if you did this: (def mkfn [x] (fn [] x)) (def foo (let [x (mkfn 1) y (mkfn 2) z (mkfn 3)] (+ (x) (y) (z)))) - you would get one class for mkfn$anonymous, and three instances of it bound to the x, y, and z locals that get collected later.

17:03 hiredman: ,(let [lol (fn [] (fn []))] (= (class (lol)) (class (lol))))

17:03 clojurebot: true

17:03 justin_smith: , (let [lol (fn [] (fn []))] (= (class (lol)) (class (lol))))

17:03 clojurebot: true

17:03 justin_smith: yeah, you are right

17:03 ToxicFrog: Oh thank god.

17:03 hiredman: I know I am right

17:03 `cbp: :-o

17:03 patchwork: Well glad we cleared that up

17:03 pjstadig: if you 'eval at runtime, then you will generate new classes

17:03 patchwork: for a second everyone was terrified

17:04 llasram: For some uncommon usage of the word "everyone"

17:04 `cbp: ~everyone

17:04 clojurebot: Cool story bro.

17:04 Morgawr: okay I'll rephrase my question in a more sensible way. I want to avoid doing (let [a (function)] (when (not (= a 3)) (println a)))

17:04 I thought about using when-let

17:04 muhoo: patchwork: i was

17:04 Morgawr: but I can't understand how to retrieve the value of (function) in a when-let

17:05 patchwork: *everyone who didn't actually know how clojure was implemented

17:05 Morgawr: obviously doing something like (when-let [a (not (= (function) 3))] (println a)) is going to print true

17:05 pjstadig: Morgawr: when-let doesn't work that way; it is for nil punning

17:05 Morgawr: I guess

17:06 so I need to take the long way around and use a let?

17:06 pjstadig: i'm not aware of any particularly elegant workarounds

17:07 Morgawr: I am doing this for error checking with OpenAL and it's bothersome because to check for errors I need to call alGetError() and test if it's all ok or not, but when I call that function it pops the value out of the error stack

17:07 so I need to save it somewhere, uff

17:07 but yeah, I'll take the long route

17:08 `cbp: Morgawr: you could use cond-> i guess

17:08 pjstadig: you might be able to use a macro or something, but i'm not sure i exactly understand the case your talking about

17:08 `cbp: (cond-> (not (= 4 3)) (println))

17:08 with a 4 after the cond-> :P

17:08 muhoo: ~everyone is a Rorschach test

17:08 clojurebot: Ik begrijp

17:09 llasram: Morgawr: If you've got a common pattern specific to your domain, you can turn it into an internal macro

17:09 Morgawr: `cbp: mmm... interesting

17:09 llasram: yeah

17:09 `cbp: ,(cond-> 4 (not (= 4 3)) (println))

17:09 clojurebot: 4\n

17:09 Morgawr: `cbp: the problem is that I need to test "4" inside the test

17:09 like

17:10 (cond-> (function) (not (= ? NO_ERROR)) (println))

17:10 now, what goes in the ?

17:10 the result of (function) should go there

17:11 `cbp: oh

17:11 Morgawr: I could do as llasram said and make a macro for it

17:11 which makes sense

17:12 justin_smith: ,(#(or (and (%2 %) %) %3) 3 even? 2) ; Morgawr - maybe something like this?

17:12 clojurebot: 2

17:12 Morgawr: justin_smith: okay, lemme process that

17:12 justin_smith: erm maybe that isn't what you want

17:12 Morgawr: I don't understand what that does D:

17:13 justin_smith: if 3 is even, 3, otherwise 2

17:13 but really I should have made it call the third arg

17:13 but really that is just an if, so never mind

17:13 well an if-let

17:13 Morgawr: the thing is, I don't have the "otherwise"

17:13 the trick is, I know what the value is not

17:13 but I don't know what the value is

17:14 because I test if the value is the same as "no error", if it's "no error" then all goes well

17:14 if it's not "no error" I need to retrieve that value and print it in an exception

17:14 so I know what happened

17:14 I mean, trivially I'd bind that value in a let and then test with when on that

17:14 but this was to avoid using let + when

17:14 justin_smith: (fn if-error [value error? else] (if (error? value) (else) value))

17:14 maybe?

17:14 Morgawr: (not a big deal, just thinking about keeping the code elegant)

17:15 yes, that could work

17:15 justin_smith: yeah, I hear that

17:15 Morgawr: I can just do

17:16 pjstadig: you could do a macro like (when-not-error [foo (function)] ...)

17:16 Morgawr: (fn throw-error [value test exception] (if (test value) (throw (Exception. exception)) value))

17:16 pjstadig: yeah

17:16 justin_smith: Morgawr: maybe you just want assert

17:17 or a modified assert, that returns the thing you are asserting

17:17 Morgawr: yeah I could use assert instead of throw

17:19 okay, I think I'm going to use an assert, with a function like the one I wrote up there, thanks guys ;)

17:20 swarthy: why would you avoid let + when?

17:20 im simply curious

17:20 Morgawr: swarthy: because it's just two statements + indentation that makes it look more clunkier

17:21 no actual reason other than keeping the code easy to follow

17:23 swarthy: id love to see the old version and the new 'side by side' if that is possible. As a newcomer this kind of stuff is worth gold.

17:23 Morgawr: swarthy: sure, hang on

17:25 swarthy: thanks

17:27 Morgawr: swarthy: https://www.refheap.com/20784 something like this

17:28 (there are probably even better ways but this is good enough for me cause I just have to call an external function, no big deal)

17:31 swarthy: Morgawr: cool thanks, checking it out now I appreciate it!

17:31 Morgawr: you're welcome ;)

17:32 swarthy: what is the other code you are calling? audio stuff?

17:33 Morgawr: it's bindings to OpenAL stuff

17:33 for a game engine

17:34 swarthy: oh cool! Are you using lwjgl?

17:34 Jarda: what's the cleanest way to make an bytearray of a string?

17:34 Morgawr: swarthy: yeah, part of it

17:34 augustl: I have a logback.xml in dev-resources. Is there a way to add a logback.xml that overrides the one in dev-resources when running "lein test"?

17:35 technomancy: augustl: test-resources/logback.xml should do it

17:35 swarthy: thats cool. Do you find working with clojure\interop more enjoyable that just the more rote approach in plain java.

17:35 i guess you must

17:35 coventry: Morgawr: There is a slight semantic difference between your two versions, because (assert) will only throw if *assert* is true.

17:35 augustl: technomancy: doh :)

17:37 Morgawr: coventry: that's the same, when will only work when the conditions is true (using when-not in the example because I'm testing for a disequality)

17:38 (assert x) and (when x (throw ...)) are the same thing, aren't they?

17:38 justin_smith: Morgawr: the difference is people turn assertions off in prod

17:38 coventry: Morgawr: No, I mean when the dynamic var "*assert*" is bound to nil, assert won't throw.

17:38 TimMc: hiredman: So something like this could cause permgen exhaustion on clojurebot: (let [evil ((symbol "eval") (ns-publics 'clojure.core))] (dotimes [_ 50] (evil '(fn []))))

17:38 Morgawr: oh

17:38 coventry: ,(binding [*assert* nil] (assert false))

17:38 clojurebot: #<AssertionError java.lang.AssertionError: Assert failed: false>

17:38 augustl: technomancy: doesn't seem to be the case. Not entirely sure that I'm doing it correctly since I'm a logback noob..

17:38 coventry: huh.

17:38 `cbp: Jarda: (.getBytes "foo")

17:38 technomancy: augustl: maybe add :resource-paths to the :test profile? it's been a while

17:39 augustl: tried adding a logback.xml with <root level="OFF">

17:39 coventry: I must be misunderstanding the code for assert.

17:39 ~assert

17:39 clojurebot: Gabh mo leithscéal?

17:39 augustl: techmnomancy: will try that

17:39 coventry: ~def assert

17:39 indigo: Ffff clojurebot

17:39 Morgawr: okay then I can just use a throw, same thing then ;)

17:39 thanks for letting me know

17:39 indigo: Always bounces my Terminal when there is a /notice to the entire channel

17:40 Morgawr: should probably be added in the docstring for assert though :|

17:40 ,(doc assert)

17:40 clojurebot: "([x] [x message]); Evaluates expr and throws an exception if it does not evaluate to logical true."

17:40 Morgawr: as it is now it's not immedite

17:40 immediate*

17:40 indigo: TimMc: /notices the entire channel

17:40 Which is pretty annoying behavior

17:41 TimMc: No, I mean to your terminal.

17:41 indigo: Terminal bounces

17:41 TimMc: Bounces?

17:41 coventry: Morgawr: No problem. Now I want to know how to get that example working, though. :-)

17:41 TimMc: Like... turns it off and on again?

17:41 indigo: A.k.a. makes a sound

17:41 And the Dock icon bounces

17:41 TimMc: Oh, I see.

17:41 Bronsa: coventry: *assert* must be mount at compile-time

17:41 bound*

17:41 TimMc: What client are you using? /notice is supposed to be a lower priority message.

17:41 coventry: Bronsa: Ah, right. Thanks.

17:42 indigo: TimMc: irssi

17:42 Morgawr: coventry: just use the same when-not statement :P but it's in its own function so it's not a problem anymore haha

17:42 indigo: Really? I thought /notice is a higher priority

17:42 * Morgawr cheap way out

17:42 TimMc: irssi must be configured differently on mac by default

17:42 Bronsa: coventry: that's the same reason why (binding [*unchecked-math* true] ..) won't do what you would expect

17:42 indigo: TimMc: It's irssi on CentOS

17:43 I guess I'll just remove notices from beep_msg_level

17:43 But it seems to be there by default

17:43 coventry: Bronsa: Yeah, I missed that the *assert* check isn't in a syntax quote.

17:46 aaelony: leiningen.exec is nice, enabling command line scripting via clojure. I'd like now to accept user input but a link I found (http://www.beaconhill.com/blog/?p=283) usins clojure.tools.cli seems to suggest that a :gen-class and -main function are needed. Is this right? Is it possible to accept command line args and use lein exec together?

17:46 hiredman: Bronsa: is the best way to report a tools.analyzer.jvm issue in jira?

17:47 guns: aaelony: Just call -main with *command-line-args*

17:47 hiredman: I don't see a tools.analyzer.jvm in jira, so I guess tools.analyzer?

17:47 Bronsa: hiredman: I guess that would be the recommended way

17:47 hiredman: yeah

17:48 aaelony: guns: thanks, I'll try that. Do I need a -main though? It would be nice to just have access to the args

17:48 technomancy: aaelony: use -main; it gets ugly otherwise

17:49 aaelony: technomancy: ok, thanks. will do :)

17:49 thanks for the help on this

17:49 guns: aaelony: I use lein-exec to generate my WM config if you'd like an example: https://raw.github.com/guns/haus/master/bin/openbox-configuration

17:49 aaelony: guns: cool thanks!

17:49 awesome

17:51 kwertii: Does anyone have any stories about running an enterprise service bus or similar software (e.g. Apache Camel) primarily from Clojure? All of what I'm finding is heavily Java-oriented. Is there anything that's already been Clojurized?

17:51 hiredman: hey!

17:51 I got #1

17:51 http://dev.clojure.org/jira/browse/TANAL-1

17:51 bitemyapp: zomg haircuts are so relaxing.

17:53 muhoo: way OT, but anyone know what this attempted sploit is? https://www.refheap.com/20786

17:53 Bronsa: hiredman: thanks

17:54 hiredman: Bronsa: sure, it is great to have the analyzer stuff written and reusable

17:54 technomancy: bitemyapp: hey, would you mind looking at this stupid monadic problem I'm having?

17:54 bitemyapp: technomancy: wait, really?

17:55 technomancy: bitemyapp: the ocaml github lib uses Lwt for its HTTP calls

17:56 basically I'm binding to one call that lists milestones; that works fine. but when I try to bind inside that call to list issues for a given milestone, it never actually runs: https://github.com/technomancy/edgestow/blob/master/edgestow.ml#L27

17:57 though I can't tell if it's just me misunderstanding monads or some stupid library-specific scheduler junk I'm not doing

17:57 Bronsa: hiredman: I'm well aware they need tests btw, I'll be spending the next couple of days covering all the passes with tests, hopefully there will be no more of stupid bugs like this

17:57 hiredman: Bronsa: cool,

17:57 bitemyapp: muhoo: the hack showed up in some Chinese sysadmin's logs awhile back, I'm not sure what it is.

17:58 TimMc: indigo: https://tools.ietf.org/html/rfc1459#section-4.4.2 -- looks like NOTICE is intended for bot responses and similar

17:59 Jarda: Caused by: java.lang.IllegalArgumentException: No implementation of method: :emit-instruction of protocol: #'cljs.core.async.impl.ioc-macros/IEmittableInstruction found for class: cljs.core.as

17:59 ync.impl.ioc_macros.Jmp

17:59 bitemyapp: technomancy: the lack of a do-syntax in OCaml is really fucking you right now.

17:59 Jarda: anyone familiar with clojurescript error messages..

17:59 indigo: TimMc: That's fine, but a notice to a channel is a bit iffy

17:59 TimMc: Well, "recipient" in IRC-land can be either a user or a channel.

18:00 bitemyapp: technomancy: you don't need the parens btw.

18:00 indigo: I've never seen a bot send a notice to an entire channel before ;P

18:00 Jarda: on that line where it points there is just (go

18:00 technomancy: bitemyapp: bloody ML precedence rules; I basically just add parens till it compiles

18:00 brehaut: technomancy: add $ !

18:01 which might be called <| in ocaml

18:01 (it is in F#)

18:01 technomancy: brehaut: "INSERT COIN(S)"

18:01 brehaut: haha

18:01 TimMc: For example, I sent this with /msg #clojure

18:01 technomancy: brehaut: yeah, ocaml has |>; it's basically ->>

18:01 bitemyapp: ugh, I never use monads in ML.

18:01 technomancy: brehaut: where do I need that?

18:02 TimMc: indigo: A channel is just a multicast group.

18:02 brehaut: technomancy: anywhere were you would have fun (expression …)

18:02 well fun (expression …)$ to go kinda regexpy

18:02 mtp: 'target' technically

18:02 and you can also e.g. PRIVMSG #foo,bar,#baz :stuff

18:02 :)

18:02 indigo: TimMc: Well, I turned it off for notices, so :P

18:02 technomancy: brehaut: I don't have comp though, so I can't make my printf callback point-free if that's what you mean

18:03 brehaut: technomancy: its not point free per se, its the pipe operator

18:03 (it doesnt return a new function, just applies it)

18:03 technomancy: brehaut: I'm all for nicer expression of the callback, but at this point all I want is for the callback to actually run

18:03 brehaut: fair

18:03 just write it as lisp without macros then

18:03 (and some weird bits)

18:04 technomancy: but monads

18:04 meingbg: Just stumbled over pedestal dataflow, and it looks beautiful: https://github.com/pedestal/app-tutorial/wiki/Derived-Values#dataflow-visualization Now, does anyone know how database or other persistence work?

18:04 brehaut: It's dangerous to go alone, take this abstract algebra

18:05 rkneufeld: meingbg: we don't dictate anything about persistence atm

18:06 bitemyapp: technomancy: is run Lwt_main.run in this case?

18:06 this would be so much easier if it was just MVars :(

18:06 technomancy: bitemyapp: only at the bottom; inside the make_* functions it's Github.Monad.run

18:07 which turns a Github.Monad.t into an Lwt.t

18:07 brehaut: theres a github monad‽

18:07 MLers

18:07 technomancy: it's a thing!

18:07 https://github.com/avsm/ocaml-github

18:07 bitemyapp: technomancy: okay, so ordinarily bind would get the thread and wait for it to terminate, then pass that to the function, but it looks to me like the bind is getting ucrried unless that's infix?

18:08 meingbg: rkneufeld: ok, so it's up to the application developer to implement persistence then? Is there any interface to that?

18:08 bitemyapp: I am hobbled by incredibly lossy internet right now :|

18:08 technomancy: bitemyapp: I believe it's infix; I can check with the non-punctuation bind to check though

18:09 bitemyapp: technomancy: please? I can barely type in my IRC client right now.

18:09 I'm bringing up the github client's code right now...eventually.

18:09 rkneufeld: meingbg: you are correct, it would be up to the dev. Where are you imagining persistence happening? At the rendering layer?

18:09 nDuff: meingbg: Not sure what exactly you mean by "interface". I'd expect Datomic to be a very popular choice for folks using Pedestal.

18:10 technomancy: yeah... it wouldn't have compiled if it had been curried

18:10 bitemyapp: meingbg: the culture in Clojure is generally DIY

18:10 nDuff: meingbg: ...see for instance http://pedestal.io/documentation/connecting-to-datomic/

18:10 bitemyapp: technomancy: I would've thought so but it wasn't clear to me if the result of the (possible) currying was getting used in such a manner as to violate the type system.

18:10 nDuff: meingbg: in general, though, tight coupling and opinionated frameworks are seen as Very Bad Things here.

18:10 technomancy: bitemyapp: it's no big deal if there's nothing that stands out as obviously wrong; just wanted a sanity check to ensure I wasn't doing anything stupid

18:11 nDuff: (and, with a strictly-IMHO hat on, I'd argue that Pedestal could probably stand to be a little bit more effectively split out into separate concerns)

18:11 technomancy: nDuff: it's not just you

18:12 rkneufeld: nDuff: spot on. We're working to that end.

18:12 Esp. WRT app.

18:12 bitemyapp: technomancy: is () the initial state?

18:14 rkneufeld: Question for people about Pedestal. If pedestal-app was *just* the dataflow declaration and integrated cleanly with lein-cljsbuild as a library-only, would people jump for joy?

18:15 technomancy: bitemyapp: sorry; initial state of what? the github monad?

18:15 I tacked it on the end of make_milestone because that function is called by List.iter, which is all about the side-effects

18:16 bitemyapp: technomancy: https://github.com/avsm/ocaml-github/blob/master/lib/github.ml#L236-L239

18:16 technomancy: now that I say it out like that it makes me think I need to deal exclusively with values in the monadic parts and write to disk elsewhere

18:17 bitemyapp: technomancy: you were trying to iterate outside of the monad?

18:17 technomancy: bitemyapp: inside the Milestone one but outside the Issue one

18:17 bitemyapp: without using a functor I'm not sure how that would work.

18:17 especially since in this case it's a callback.

18:18 presumably, anyway.

18:18 technomancy: are you matching the failure case so that you can see a log if it breaks?

18:18 nDuff: rkneufeld: I'd love to see the dataflow engine be easy to import and use (without unrelated dependencies) in contexts that aren't web applications at all, so, in short: Yes.

18:19 technomancy: ok, so I'll see if I can just switch to gathering values and write out at the end

18:19 rkneufeld: nDuff: Cool, Brenton and I are considering neutering pedestal-app *hard* with the 0.3.0 release.

18:20 TimMcTelnet: mtp: Wow, doing this over telnet sucks

18:20 mtp: hmm?

18:20 bitemyapp: TimMcTelnet: well, yeah.

18:20 mtp: oh, using a direct socket to IRC does suck

18:21 that's why we wrote clients :)

18:21 bitemyapp: TimMcTelnet: especially because you have to keep PING'ing.

18:21 er, PONG'ing. whatever.

18:21 TimMcTelnet: But I like that it's at least possible.

18:21 bitemyapp: TimMcTelnet: even the unabomber could use telnet.

18:22 with a telegraph.

18:24 technomancy: oh hey; I don't actually need two levels here; I can just request all issues and then sort them by milestone after the fact. derp.

18:25 meingbg: nDuff: Thanks for the link. I like the functional approach with loose coupling, and having the dataflow engine put it all together. That is what I came here looking for. But I would have imagined a framework supporting for example load and save functions on top of derive and transform, for inclusion in the dataflow. Am I missing some key point here?

18:25 bitemyapp: technomancy: side-stepping or was grokhood achieved?

18:26 technomancy: bitemyapp: total side-step

18:26 meingbg: rkneufeld: I would imagine the data model being saved to disk eventually.

18:40 concur: anybody in here good with incanter charts?

18:41 technomancy: bitemyapp: I may have been a bit hasty assuming this github lib is suitable

18:41 doesn't appear to support pagination =\

18:42 hiredman: technomancy: I have a profile X, is there someway to force lein to add checkouts to that profile?

18:42 lein with-profile X classpath doesn't include checkouts

18:43 technomancy: hiredman: huh... I remember taking a patch for this a while back

18:43 bitemyapp: technomancy: sounds like it. :|

18:43 technomancy: it's just a JSON API, couldn't you use an HTTP client with Async?

18:44 technomancy: hiredman: you may have to specify :checkout-deps-shares [:source-paths] spelled all the way out

18:44 hiredman: unless you actually want lein with-profile +X classpath?

18:45 bitemyapp: yeah, but the auto-generate-type-boilerplate-from-atd stuff looks intimidating

18:45 hiredman: what is +X?

18:45 technomancy: hiredman: +profile-name means "add this profile to the set of active ones"

18:45 instead of "replace profile set with this"

18:46 hiredman: ok, that seems to do it

18:46 technomancy: just speculating as to your intentions

18:46 hiredman: I am fiddling with cheshire, and it has a benchmark profile, but the benchmark profile wasn't picking up checkouts

18:47 but changing that to + seesm to have fixed it

18:47 technomancy: yeah, you probably want to add the benchmark profile, not use benchmark exclusively

18:47 bitemyapp: technomancy: the equivalent thing in Haskell is just forkIO and MVar.

18:48 hiredman: oh, foo, the checkout is there in classpath, but this is still erroring out, as if the checkouts weren't being loaded, I'll just fiddle with it some more I guess

18:50 technomancy: bitemyapp: I'll just open an issue and pick this back up if it ever gets fixed upstream =)

18:51 that way I'll be able to cut a lein release at the conj and not be distracted

18:51 bitemyapp: oh right, the conj everybody will be at ;_;

18:57 TimMc: bitemyapp: You can still play along at home.

18:58 In past years there has been a little backchanneling on IRC.

19:03 `cbp: should buy one of those telepresence robots

19:03 bitemyapp: `cbp: I know a salesguy at one of those companies.

19:04 `cbp: with a discount!

19:04 bitemyapp: I would pay for the ability to have a robot minion of mischief running around at the conj.

19:05 justin_smith: bitemyapp: http://bits.blogs.nytimes.com/2012/08/18/double-turns-the-ipad-into-a-telepresence-robot/?_r=0 one of these?

19:05 WWWest: Hi!

19:05 I'm trying to use the crypto module on node js

19:06 ssutch: with core.match, can i match an array inside a map, eg {:rgba [r g b a]}

19:06 bitemyapp: justin_smith: yeah that's the company.

19:06 WWWest: but closure complains on calling .final on the cipher

19:06 justin_smith: WWWest: this is clojure, not closure

19:07 unless this is a clojurescript issue?

19:07 WWWest: and it turns out that final is a javascript reserved keyword

19:07 yeah it is

19:07 justin_smith: ahh

19:07 WWWest: I'm using cljs, yes

19:07 which feeds generated js to closure

19:07 bitemyapp: omg that is confusing.

19:08 WWWest: is there a work around to being able to use the final method? I can't be the only one to have run into this..

19:14 TimMc: bitemyapp: We have one of those here. I really want to play with it.

19:19 arrdem: bitemyapp: one of these days I swear I'm gonna pick up a Parrot drone and play with this... https://github.com/gigasquid/clj-drone

19:22 justin_smith: would I rather have an ipad on a segway as a coworker, or a helicoptor...

19:22 hard questions

19:23 TimMc: justin_smith: It's easier to barricade segways.

19:23 justin_smith: true

19:23 Apage43: psh, iPad + bigdog

19:24 justin_smith: now that is how to telepresence

19:24 Apage43: no escape

19:24 justin_smith: maybe an animatronic monster head instead of ipad

19:24 Apage43: if my telepresence robot can't chase down and tackle folks then why bother

19:27 arrdem: Apage43: ... tackle? trample more like...

19:28 * arrdem envisions a BigDog executing a Donkey kick

19:29 baumax: golf competition: split a string into space-delimited words, reverse the words, join the string, print it

19:29 (join with spaces)

19:30 arrdem: $karma baumax

19:30 lazybot: baumax has karma 0.

19:30 arrdem: baumax: lisps suck for code golf. believe me I've tried.

19:34 justin_smith: ,(->> "this is a test" (#(clojure.string/split % #" ")) (map reverse) (map #(apply str %)) (clojure.string/join " "))

19:34 clojurebot: "siht si a tset"

19:34 justin_smith: not very golfy :(

19:35 ,(->> "this is a test" (#(clojure.string/split % #" ")) (map (comp #(apply str %) reverse)) (clojure.string/join " "))

19:35 clojurebot: "siht si a tset"

19:35 baumax: it is not so bad :).

19:35 brehaut: arrdem: youz on 4clojure disagrees with you ;)

19:36 justin_smith: the comp actually made it worse I think

19:36 of course using clojure.string would be natural, but not what you would do with clojurebot

19:36 you never specified the input:

19:37 ,"bob"

19:37 clojurebot: "bob"

19:37 justin_smith: very concise

19:37 arrdem: brehaut: shrug. you won't get close to the evil things I've seen in Python and Perl over at codegolf.stackexchange.com with any Lisp dialect.

19:37 patchwork: Hmm… posted a comment on the clojure google group almost an hour ago and it still hasn't shown up. Does that mean I am a spambot?

19:37 arrdem: brehaut: ymmv but I've always been a factor of 4 or more longer

19:38 brehaut: arrdem: quasiquoting allows some truely astounding messes and requires appears to require a truely twisted mind

19:38 patchwork: What is the approval process, does it require human beings? weird

19:39 hiredman: patchwork: it depends, but my understanding is your first posting requires human approva

19:39 l

19:40 patchwork: hiredman: Ah, that would explain it

19:40 I guess I have never posted anything before!

19:44 arrdem: anyone have a project idea kicking around based on a DSL?

19:46 brehaut: why would you want to use a DSL rather than an API?

19:47 technomancy: "Metaprogramming in lisp is like chinese food in China; they just call it food"

19:47 TimMc: &(apply str (reverse "this is a test")) ;; baumax

19:47 lazybot: ⇒ "tset a si siht"

19:47 TimMc: Oh, sorry, wrong one.

19:48 arrdem: brehaut: school project, "do something cool using an embedded DSL" :/

19:48 TimMc: &(clojure.string/replace "this is a test" #"[^ ]+" #(apply str (reverse %)))

19:48 lazybot: ⇒ "siht si a tset"

19:48 brehaut: arrdem: write a program nominally in java

19:48 TimMc: There we go.

19:48 brehaut: call into clojure.lang.RT in main

19:49 arrdem: brehaut: hahaha

19:51 technomancy: arrdem: a domain specific language you say? https://github.com/joegallo/brainfuck

19:51 Morgawr: if I deref a ref inside a dosync twice I am guaranteed to get the same value, right?

19:51 like (if @myref (do-something @myref) nil)

19:51 or something like that

19:52 (just an example)

19:52 technomancy: Morgawr: yeap

19:52 Morgawr: alright

19:52 thanks

19:52 first time using refs

19:52 lemonodor: if i have a unit test that operates on a file, how do i represent the path to that file? e.g. i have test/mylib/foo_test.clj and test/mylib/foo.dat that the test operates on. in python i'd use __file__ to construct a path relative to the file containing the unit test code.

19:52 arrdem: technomancy: hahaha I did think of that... maybe something more interesting like malbolge..

19:52 TimMc: Unless you munge it in the transaction.

19:52 &(let [r (ref 0)] (dosync [@r (alter r inc) @r]))

19:52 lazybot: ⇒ [0 1 1]

19:52 brehaut: ,(let [r (ref 1)] (dosync (let [a @r _ (commute r inc) b @r] (= a b))))

19:53 clojurebot: false

19:53 justin_smith: lemonodor: clojure.java.io/resource

19:53 TimMc: brehaut: Poor man's sequencing.

19:53 justin_smith: lemonodor: that will expect a path relative to the classpath (which is generated from the resource and source paths in project.clj)

19:53 TimMc: Morgawr: ^

19:53 brehaut: TimMc: huh, so it is.

19:53 lemonodor: ok, i'll give that a try. thanks, justin_smith

19:54 brehaut: TimMc: how long has dosync had that?

19:54 TimMc: brehaut: Probably not guaranteed, though. :-P

19:54 Morgawr: TimMc: yeah, I was only worried about other threads fiddling with it

19:54 thanks

19:54 TimMc: Oh, not a property of dosync, just vector evaluation.

19:54 brehaut: TimMc: oh. lol!

19:54 TimMc: :-D

19:55 brehaut: arrdem: more seriously: turtle graphics

19:55 arrdem: all the commands are 'DSL' (cough, functions)

19:55 technomancy: lemonodor: wow, I think I read your blog way back when I was first getting into clojure

19:56 brehaut: arrdem: you can then write another DSL ontop of turtle graphics DSL to draw L-Systems relatively easily

19:56 TimMc: Clojure is a DSL for manipulating the JVM.

19:56 justin_smith: any executible that takes input is a DSL

19:56 lemonodor: technomancy: now you get to see me ask dumb clojure questions :)

19:56 technomancy: lemonodor: and I think I've been to the shipwreck in palos verdes on your blog

19:56 justin_smith: technomancy: lemonodor: yeah, back when I was hacking common lisp I would check that blog out religiously

19:57 lemonodor: ha, that's awesome.

19:57 justin_smith: neato

19:57 brehaut: justin_smith: i think everyone here agrees that a DLS is a silly concept; but if arrdem needs to make one for a project, it probably helps to make on that looks like one to his markers

19:57 arrdem: brehaut: ooh... that could work... the issue with this assignment is that part of the implementation has to be a DSL. I can't just build an interpreter or an API and call it there, the final product has to be based on a DSL. Stacking a user-facing DSL atop an internal DSL would work...

19:58 justin_smith: just formalize the semantics of any app, blammo, DSL

19:58 arrdem: (inc brehaut)

19:58 lazybot: ⇒ 20

19:58 arrdem: justin_smith: basically. I'm trying to get clarification on "configuration language" vs. DSL.

19:58 WWWest: pfff... I tried exporting the code using .final to an :externs js file, closure still complains

19:59 brehaut: arrdem: the difference between configuration and code is indirection via a map ;)

19:59 foo vs :foo

20:01 bitemyapp: arrdem: just show them edn and see if it flies.

20:01 justin_smith: in all seriousness, there are some really good classic examples of dsls

20:02 csound for audio programming

20:02 TeX

20:02 bitemyapp: arrdem: make it out of S-Expressions.

20:02 algal: So I am discovering the simple but delightful world of ad-hoc hierarchies with (derive ...) and friends. Quick question: can I pretty-print the whole hierarchy to, you know, see the hierarchy?

20:02 arrdem: bitemyapp: yeah an inline EDN reader for Scala was one of my original ideas

20:02 bitemyapp: arrdem: hark a DSL: https://github.com/bitemyapp/revise/#filter

20:03 brehaut: seriously though: L-Systems

20:03 its fun, relatively small implementation surface area, and it can clearly fill the bill

20:04 beppu: algal: I did not know about derive until you mentioned it. What other functions work on these hierarchies?

20:04 arrdem: clojurebot: ping

20:04 justin_smith: algal: check out clojure.reflect/reflect

20:04 bitemyapp: brehaut: fit the bill

20:04 clojurebot: PONG!

20:04 justin_smith: algal: you could probably chain something up with that with not too much effort

20:04 algal: beppu: isa? underive parents ancestors make-hierarchy etc..

20:04 brehaut: bitemyapp: sorry, i typed on IRC. i'll run it past my editor next time

20:04 hyPiRion: algal: you can do @#'clojure.core/global-hierarchy

20:04 bitemyapp: brehaut: <3

20:05 justin_smith: ,(do (require 'clojure.reflect) (:bases (clojure.reflect/reflect 1)))

20:05 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.reflect>

20:05 hyPiRion: It's a reason that the global hierarchy is private though, so the semantics may change

20:05 beppu: algal: this is an unexplored corner of clojure for me. interesting...

20:06 lemonodor: so typically data files for use by unit tests would be in dev-resources?

20:06 technomancy: hyPiRion: pshaw; how dare someone think they know better than me about their own code

20:06 lemonodor: yeah

20:06 lemonodor: ok, thanks

20:07 hyPiRion: technomancy: huh, I think I lost you there

20:07 oh nvm, I thought for some reason pshaw was a user

20:07 technomancy: hyPiRion: just mocking the crazy anti-private sentiment that is sometimes expressed here

20:07 justin_smith: algal: never mind my above, that shows what something implements but not heirarchy

20:08 hyPiRion: yeah, I figured that out in hindsight

20:08 algal: beppu: you should run over to ClojureAtlas and sign up. It's great for getting a quick overview of new things in the core language. http://nap.kn/d/kdBBWa

20:08 bitemyapp: type errors...type errors everywhere. Now I have to litter asserts all over my code. Thanks Obama.

20:09 algal: beppu: a better link, which probably works with a trial: http://www.clojureatlas.com/org.clojure:clojure:1.4.0#concept/hierarchies

20:09 beppu: algal: I'll check it out. Thanks.

20:10 WWWest: even if I declare it as a foreign lib... the fact that the js file is in resources shouldn't change anything right? I thought google closure would ignore foreign libs?

20:10 bitemyapp: "java.lang.NullPointerException: null" YEAH AWESOME

20:10 because we didn't solve this problem decades ago

20:10 beppu: algal: That's a crazy site. I was surprised by the animated graph that suddenly appeared on my screen.

20:11 hyPiRion: bitemyapp: lost the stack trace?

20:11 algal: beppu: Yes, I love it. I just wish it had more info.

20:11 bitemyapp: http://i.imgur.com/JRCxZh6.jpg

20:11 hyPiRion: it's not even about that.

20:12 hyPiRion: also the stack traces can be misleading if you don't have asserts and the nil lurks in wait until later in the program.

20:12 brehaut: bitemyapp: its really simple. everything inherits from object. object is a union of Instance … | Null

20:12 technomancy: stack trace tells you who tried to invoke a method on nil, not where the nil came from

20:12 bitemyapp: brehaut: hu hu hu.

20:12 technomancy: ^^ that.

20:13 brehaut: bitemyapp: creating implicit unions is a popular OO past-time. see also exceptions

20:13 hyPiRion: brehaut: not true, actually `null instanceof someclass` will always return false

20:13 technomancy: dear tony hoare http://p.hagelb.org/pay.png

20:13 (except that's not fair because he's actually sorry about it)

20:13 TimMc: This is why we should have metadata on nils, so you can attach their line and column of origin.

20:13 * TimMc runs

20:13 brehaut: hyPiRion: i cant help it if the implementation is broken :P

20:13 technomancy: sorry tony hoare

20:13 I didn't mean it

20:13 TimMc: <3

20:14 hyPiRion: (alter-var-root #'nil ...)

20:15 arrdem: .... this I must try...

20:15 ambrosebs: what the hell is going on here :)

20:15 * TimMc shouts from a distance: "And you'd have to attach each call frame they pass through because they get reused."

20:15 brehaut: we should monkey patch nil's var so that its not actually a Var, but a thing that complains when you deref it

20:15 technomancy: whiny_nil is a thing in rubby

20:15 TimMc: ambrosebs: We're fixing Clojure! :-D

20:15 brehaut: haha

20:16 ambrosebs: hahaha

20:16 arrdem: hyPiRion: I'm laughing too hard to repl

20:16 bitemyapp: ambrosebs: I'm complaining about NPEs and hyPiRion is trying to help.

20:16 "help"

20:16 technomancy: http://api.rubyonrails.org/v3.1.1/files/activesupport/lib/active_support/whiny_nil_rb.html

20:16 Apage43: i'm just sitting here having people confused at why i'm not thrilled to work in Go

20:17 brehaut: ambrosebs: you'd think nobody had heard of static analysis or something ;)

20:17 hyPiRion: bitemyapp: You're talking language design with the co-author of Swearjure, what do you expect?

20:17 jared314: brehaut: the new Javascripters haven't

20:17 bitemyapp: hyPiRion: are there nils in Swearjure?

20:17 technomancy: Apage43: because they got your hopes up that you'd be playing a board game I bet

20:17 Apage43: ,({} {})

20:17 clojurebot: nil

20:17 arrdem: hyPiRion: okay. good. that doesn't work.

20:18 brehaut: jared314: the authors of the language, or its users?

20:18 hyPiRion: arrdem: haha

20:18 arrdem: hyPiRion: I was really really worried for a minute

20:18 jared314: brehaut: users

20:18 bitemyapp: Apage43: god dammit.

20:18 It's even a relatively brief construct.

20:18 brehaut: jared314: well they can't be helped

20:18 bitemyapp: so unfair ;_;

20:18 technomancy: Apage43: leave it to google to have a namespace collision with what is literally the oldest extant product of human civilization

20:18 Apage43: I like how it's almost the horrified face smiley it should be

20:19 TimMc: bitemyapp: We still can't get e.g. 2.5 though.

20:19 bitemyapp: by running this batch job at 5:20pm I may have stranded myself.

20:19 TimMc: integrals only?

20:19 TimMc: And rationals.

20:19 bitemyapp: TimMc: all you need anyway.

20:19 TimMc: Freaking *rationals*, but no floats.

20:19 Fair. :-P

20:19 hyPiRion: TimMc: Swearjure is all rationality

20:20 metellus: ,(/ (*) (+))

20:20 clojurebot: #<ArithmeticException java.lang.ArithmeticException: Divide by zero>

20:21 bitemyapp: hg commit -m "fuck fucking fucky NPE fucking bullshit fuck. Batch loading seems to work?"

20:21 beppu: ,(*)

20:21 clojurebot: 1

20:22 beppu: ^-- that doesn't seem right.

20:22 brehaut: its the identity of multiplication

20:22 TimMc: It's as right as right can be.

20:22 arrdem: beppu: multiplicitive identity. it's fine.

20:22 justin_smith: beppu: it is the base case for reducing on a list of numbers by multiplying

20:22 beppu: did not know

20:22 brehaut: its also epsilon for the monoid of multiplication

20:23 bitemyapp: ,(apply * [])

20:23 clojurebot: 1

20:23 bitemyapp: KirinDave is consoling me on Twitter.

20:24 arrdem: I might keep my sanity. Also, DotA2?

20:24 ddellacosta: you're going to be really mad about nils after you learn Haskell.

20:24 arrdem: bitemyapp: still with the homework.

20:24 bitemyapp: arrdem: way too hard working to be a programmer.

20:25 ddellacosta: bitemyapp: good morning to you too, haha

20:25 bitemyapp: arrdem: are you sure you're not a spy from some other STEM branch?

20:25 ddellacosta: I've been raging about having to litter asserts in my code to find the origin of a nil that was causing an NPE.

20:25 ddellacosta: good morning!

20:25 arrdem: bitemyapp: dude... I gotta get this <cursing> calc out of the way to graduate. only one way to do it and it doesn't involve automation Q_Q

20:25 technomancy: bitemyapp: why is kirindave no longer on freenode? =(

20:25 justin_smith: the clojure web ecosystem I have been helping to develop (caribou) just got announced on the clojure mailing list finally

20:25 ddellacosta: bitemyapp: I will have to get coffee then I will be prepared to talk about nils in Haskell. ;-)

20:26 bitemyapp: technomancy: I asked him, but I got a non-answer.

20:26 justin_smith: pretty exciting (for some reason before this the repos were public but the main author did not want to "tell anyone about it")

20:26 technomancy: bitemyapp: I guess he just launched or something

20:26 bitemyapp: technomancy: well yeah, he's really busy at Level. he's also recruiting people that have a knack for Clojure.

20:27 jared314: i wish I had a knack for Clojure

20:27 bitemyapp: jared314: are you in the bay area?

20:27 jared314: bitemyapp: nope

20:27 bitemyapp: Nuts.

20:29 brehaut: knacks for clojure are more easily aquired by learning and practise than by wishing

20:29 jared314: brehaut: hoping isn't wishing

20:29 bitemyapp: ~gentlemen

20:29 clojurebot: You can't fight in here. This is the war room.

20:29 sritchie: cemerick: what's the best way to inject a "logged in successfully!" note into the flash,

20:29 cemerick: after an interactive form auth with friend?

20:30 cemerick: struggling to figure out how to do form validation around the signup flow

20:30 arrdem: jared314: just assume you do, we have technomancy to remind us that we're all wrong anyway.

20:30 sritchie: cemerick: do form validation (and potentially modify the flash), THEN pass my map in for authorization, then deal with further flash mods afterward

20:31 technomancy: arrdem: only if you use when for return values

20:31 jared314: is there an option in cljsbuild to not add cljs.core to the compiled output?

20:32 arrdem: technomancy: but it's OK because my c.c.t system is (Maybe AnyInteger) so a nil from when is fine :D

20:36 ddellacosta: sritchie: are you trying to authenticate or authorize? I'm not sure why you would be doing validation on someone that isn't authenticated, unless it is a signup form or something (is it?).

20:36 sritchie: yes

20:36 ddellacosta: I mostly just want to add a "success!" method to the flash

20:36 after a successful login

20:36 but still take advantage of friend's redirecting

20:37 ddellacosta: sritchie: ah, so the basic problem is passing that flash message around?

20:37 sritchie: ddellacosta: yeah, that's really it -

20:37 I use lib-noir,

20:37 and I used to just set it in my post handler

20:37 but now I can't really figure out how to inject that post handler

20:38 algal: anyone going to the Clojure real-time machine learning talk in about an hour in SF ( http://www.meetup.com/The-Bay-Area-Clojure-User-Group/events/146268902/ )? Know a good place to grab food near the venue?

20:39 sritchie: ddellacosta: trying to figure out some way to check the return value of my interactive-form workflow,

20:39 and get in the loop there, somehow

20:39 ddellacosta: but it looks like with friend, I no longer need to think about POST requests to login

20:42 ddellacosta: I imagine this is sort of common, injecting flash messages like "you must be authorized to see this page. log in first."

20:42 slpsys: 2 many SF meetups

20:44 ddellacosta: sritchie: yeah, I don't have a good answer for you right now, but it depends on the workflow. Have you checked out the interactive-form workflow in the codebase?

20:44 sritchie: that's what I'm using now

20:44 ddellacosta: sritchie: sorry, I mean, have you dug into that workflow's code?

20:44 sritchie: I've been doing so

20:44 and I can't really see how to get in the middle of it

20:44 ddellacosta: sritchie: ah, okay--sorry I wasn't clear on that.

20:44 sritchie: to modify this flash

20:47 ddellacosta: sritchie: and, are you writing a login-failure-handler yourself?

20:47 sritchie: yes

20:48 https://gist.github.com/sritchie/7442190

20:48 ddellacosta: it works to do that

20:48 to jam the flash in manually

20:51 ddellacosta: sritchie: I mean, it's definitely worth seeing what cemerick thinks but I'm not sure there is a better answer than something like what you are doing, honestly. The interactive form built-in is pretty simple, and the intention with friend is that you'd extend it with your own more sophisticated workflows. The configuration mostly extends to adding to whatever configuration the workflow itself makes available--so if it isn't there...

20:51 isn't there.

20:52 sritchie: so, all of that is to say, I think extending/re-writing the workflow itself--as you're doing--is probably the right one.

20:52 sritchie: I think I can wrap it and check the return value,

20:52 ddellacosta: sritchie: sorry if that's not the answer you were looking for. :-(

20:52 sritchie: no worries :)

20:53 and then switch based on that, and pass the result on through

20:53 like auth does when deciding if a workflow succeeded or failed

20:53 should be clean

20:53 thanks, ddellacosta !

20:53 ddellacosta: sritchie: sure thing, hope something I said was helpful!

20:56 xeqi: sritchie: friend's interactive form workflow doesn't include anyway to add something to the flash directly, but will include some query parameters on redirect

20:56 I've just been checking for those as part of displaying a message

21:07 coventry: How can I debug the reasons for "lein install" hanging?

21:08 With "DEBUG=true" it hangs after reporting it's written the pom file.

21:10 technomancy: coventry: does `lein compile` hang too?

21:11 it's almost always "doing something server-y at compile time"

21:12 coventry: Yes it is. I'll look for something like that. Thanks.

21:32 I went through the project and commented out everything which is not a def, defn, deftest or ns form, and it's still hanging. Any other possibilities?

21:38 amalloy: coventry: one of your defs could easily be a problem

21:38 (def foo (start-server)) is no better than (start-server)

21:39 coventry: amalloy: Yes, that occurred to me, but they're not in any obvious way.

21:39 amalloy: if i were writing a script to look for mistakes like this, it would look for every (def foo (anything-but-delay ...))

21:40 mostly false positives, of course, but i suspect it would be surprisingly effective

21:41 coventry: Oh, that explains some of the strange uses of delay I've seen in other people's code. Hmm.

21:44 So what counts as server-y? Is creating a namespace in a def server-y?

21:44 amalloy: coventry: anything side-effectful other than defining functions, basically

21:44 is the code open-source?

21:45 TimMc: server-y or app-y

21:46 coventry: amalloy: Yes, it's at https://github.com/coventry/troncle

21:46 It's a bit of a mess at the moment, though.

21:46 TimMc: technomancy: Oh, a follow-up on my "lein uberjar taking forever" thing -- it is indeed spending all of its time compiling.

21:46 Each defn takes the better part of a second.

21:47 coventry: amalloy: I think the create-ns defs in core and core_test are candidates.

21:47 bitemyapp: coventry: don't do side-effecty things in defs.

21:47 coventry: seriously, don't.

21:47 amalloy: bitemyapp: i think we've covered that

21:47 coventry: https://github.com/coventry/troncle/blob/master/src/troncle/traces.clj#L32 is a little suspicious - it shouldn't be a problem unless you send a function to it at compile time, but that it exists as a def makes me think you might do exactly that

21:48 bitemyapp: `cbp: around?

21:48 `cbp: bitemyapp: yeah

21:48 coventry: amalloy: No, trace-log is currently unused.

21:48 bitemyapp: coventry: https://www.refheap.com/20788

21:49 `cbp: DotA2?

21:49 `cbp: bitemyapp: in 10min

21:49 bitemyapp: `cbp: deal.

21:50 Apage43: hm

21:50 coventry: it doesn't hang for me

21:50 amalloy: coventry: nothing stands out to me. it all looks pretty innocuous, assuming you haven't done anything devious inside tools.reader

21:51 and of course i have no idea what nrepl-discover does, so it could conceivably be the cause

21:51 Apage43: coventry: but, try thwacking Ctrl-\ while it's hung

21:51 you'll get the stacks of running threads

21:51 bitemyapp: Apage43: it's time to plot.

21:52 Apage43: plot?

21:52 amalloy: scheme

21:52 coventry: Apage43: What does C-\ do? It's not having any effect on "lein compile" for me.

21:53 amalloy: No, I ended up leaving tools.reader unmolested for now.

21:53 Apage43: coventry: sends SIGQUIT to the foreground process

21:53 which should make JVMs print their stacks

21:53 bitemyapp: Theme song: http://www.youtube.com/watch?v=Cb1gImYbEcM

21:56 Apage43: you can also use jstack to extricate a stackdump more forcibly

21:56 jstack -F <process id>

21:57 coventry: Hmm, well now lein compile is running to completion, and I'm not sure why. Time to start backing my changes out, I suppose.

22:01 marcopolo`: ~/

22:01 clojurebot: Cool story bro.

22:08 arrdem: sudo su

22:11 amalloy: lazybot should say something snarky when you try to sudo here

22:11 hop to it, Raynes

22:13 Raynes: huh

22:13 lazybot: kill

22:13 lazybot: KILL IT WITH FIRE!

22:13 Raynes: y u be so weird

22:13 amalloy: Are you sure it should do something?

22:13 ls

22:13 lazybot: bin boot data etc home lib media opt root sbin src sys tmp

22:13 Raynes: Everything else is working.

22:13 No errors in the console.

22:13 * Raynes checks the source

22:13 amalloy: Raynes: no, i mean that would be a nice addition

22:14 TimMc: "should"

22:14 amalloy: not that i think it should already be doing that

22:14 Raynes: Oh.

22:14 Well shoot, I should stop fixing it then I suppose.

22:14 TimMc: No, no, keep going.

22:14 * Raynes gives lazybot some more snark.

22:14 Raynes: $loaded?

22:14 $loaded

22:14 lazybot: Raynes: It is not the case that you don't not unhave insufficient privileges to do this.

22:14 Raynes: -.-

22:15 amalloy: Which plugin was it that provides this functionality?

22:15 amalloy: Raynes: i think it's in utils or something? look for unix-jokes

22:15 Raynes: unix-jokes

22:15 akurilin: I find it amazing how the bot is such a community-driven work of passion.

22:16 Influenced by the personalities of some of the more vocal channel members.

22:16 Raynes: This is gonna be an awesome addition amalloy.

22:21 coventry: I'm getting an NPE when I do "lein deploy clojars". Any suggestions on how to fix? https://www.refheap.com/20789

22:22 cemerick: dnolen: AFAIK, the problem in :advanced was repeated re-defs in a top-level (do). Is that to be expected, or should it be considered a bug?


22:23 Getting a minimal failing example is going to be tricky, the code is the result of a somewhat-hairy macro.

22:24 coventry: Ah, "lein upgrade" fixed it.

22:25 Raynes: akurilin: It's true, we do love our bots.

22:25 Between lazybot and clojurebot, pretty sure marriage proposals are in the future.

22:25 bitemyapp: Raynes: never! Like Montague and Capulets, that lot.

22:29 shaungilchrist: anyone using core.rrb-vector in cljs?

22:35 muhoo: coventry: have a look at deploy.clj on the line mentiomed, and see wtf it thought itwas doing?

22:36 TimMc: sudo su

22:36 Hmm, not yet.

22:40 coventry: muhoo: Probably whatever fixed this failure fixed mine as well, it's what gave me the idea to upgrade: http://www.raynes.me/logs/irc.freenode.net/leiningen/2012-08-29.txt

22:45 akurilin: Has anybody figured out a sane pattern for dealing with static resources that one's web app depend on? Say I have a .json tree in my project with some content my app requires to run. At some point the number of these .json files grows considerably and I might need to start lazily fetching it at run-time from somewhere like S3.

22:46 However if you decouple the app from the critical piece of data, your ability to debug things and the likelihood of not booting has just gotten much higher.

22:46 swarthy: Off topic question but you guys are smart and I like you: anyone know how to get the reading of power consumption at the CLI on linux?

22:46 akurilin: *ability to debug would go lower :)

22:46 bitemyapp: swarthy: acpi?

22:46 swarthy: is that the command?

22:47 bitemyapp: swarthy: sudo apt-cache search acpi

22:47 swarthy: lol just did that

22:47 thanks, i'm going to check that out

22:48 danneu: akurilin: what are these files that are growing so considerably

22:50 justin_smith: akurilin: nginx can be put in front of your app, and told to serve out of your static dir

22:50 swarthy: bitemyapp: I should note I am on a desktop, so acpi failed. Good suggestion though.

22:50 justin_smith: so during dev it is just the static ring handler, in production, nginx serves the file directly

22:50 akurilin: danneu, in my scenario, we have several big .csv lists math questions that we ask kids. I need this content within the app to generate worksheet pdfs, do some analytics etc

22:50 bitemyapp: swarthy: kill-o-watt

22:50 akurilin: danneu, the web app is useless without the underlying content

22:51 justin_smith: akurilin: also, nginx or varnish (I recommend using both in front of an app) can be redirected to a separate server that also has that same asset directory structure (like s3)

22:52 *can be configured to redirect to

22:52 bitemyapp: akurilin: I rsync static assets until a CDN is needed.

22:52 + nginx

22:53 justin_smith: bitemyapp: thanks again for the help with this audio server, I am | | this close to turning the two 8 input cards into 16 mono cards via the magic of dmix

22:53 danneu: so far it sounds like a roundabout way of describing what i use a database for

22:53 akurilin: The one hassle of decoupling the data from the app is that now every time it boots (say you're running tests) you now have to potentially download 50 megs of content

22:54 so I'd have to have a "test static dataset" in place to avoid the hassle

22:54 justin_smith: akurilin: the contents of the app directory are authoritative, anything else either mirrors it or is synced from it automatically

22:55 akurilin: danneu, it's true, but in our case static storage is necessary because we have non-developers working in Excel generating the content, and continuously migrating those csvs to a db somewhere is not worth the hassle right now.

22:55 justin_smith, so default to whatever's in the app folder, and if it's missing (say in production), then download it or something like that?

22:55 justin_smith: nginx or varnish is going to serve static assets a lot more efficiently than a db would

22:56 danneu: yeah but the json limitation is due to their nondev content genreation

22:56 justin_smith: akurilin: no, ship the static assets inside your uberjar, the app server unpacks it, nginx serves out of that dir

22:56 or syncs to the cdn out of it, if need be

22:56 akurilin: justin_smith, well I do that now under resources/ and it works fine, except for the part where the .jar is starting to bloat up

22:57 I just slurp from disk for now.

22:57 s/disk/jar/

22:57 justin_smith: so the jar does not get unpacked on the server?

22:57 what is your app container?

22:57 or are you just running ring via an uberjar

22:57 danneu: akurilin: you could send up git-diffs to the server and rebuild the jar on the server to deploy

22:57 akurilin: justin_smith, not sure what that means. I just run it with java -jar from runit once it's on the web machine.

22:58 justin_smith: if you unzip the jar, you can then have nginx server static assets for you

22:58 much more lightweight

22:58 reduces load on your app

22:59 akurilin: justin_smith, well yeah, actually not fetching those assets from S3, but placing them on the same machine even for testing makes things a lot simpler

22:59 behind nginx/varnish

22:59 My gripe was originally with having to fetch stuff from s3, but as you pointed out that's completely avoidable

22:59 justin_smith: one of these days I am going to write a ring middleware that abstracts over local / s3

23:00 I already have the logic working in an image resizer (caribou/lichen), but it should be a standalone functionality

23:00 danneu: that sounds like a painful rubygem we used at my last job

23:00 justin_smith: heh

23:00 it works pretty nicely in caribou

23:02 akurilin: argh slowly everything turns into an integration test :)

23:02 justin_smith: I have it up in production for a few corporate brochure sites

23:04 coventry: Is there a canonical coordinate for clojure.walk2, these days? [com.stuartsierra/clojure.walk2 "0.1.0-SNAPSHOT"] seems to have gone walkabout.

23:05 justin_smith: coventry: running lein search for it right now

23:06 coventry: justin_smith: There is one on clojars, <https://clojars.org/caribou/clojure.walk2>, but I don't know whether I should depend on it.

23:06 justin_smith: yeah, that I couldn't tell you

23:06 coventry: I was using the com.stuartsierra one because it was recommended in the walk2 readme.

23:10 bitemyapp: coventry: why use walk2 instead of walk?

23:10 Bronsa: bitemyapp: protocol based, faster, works with records AFAIK

23:11 justin_smith: LOL

23:11 that clojure.walk2 you found is my org's fork of it

23:11 (caribou)

23:11 can't promise we updated recently, but I can check

23:12 I'll pull from upstream, and push a new jar if we are out of date

23:14 bitemyapp: justin_smith: oh you're the guys responsible for that.

23:15 justin_smith: OK, prismofeverything probably forked and pushed, but did not upload to caribou

23:15 yeah, I am just a lackey, patchwork is the main dev

23:15 I make client sites, he develops the lib

23:15 and I try to contribute to the lib between client work

23:18 and / or hanging out on this channel and learning about applicative functors and side work with an audio fingerprinting service etc.

23:23 coventry: This damn lein NPE is back. It looks like it's a failure in the password read. I'd like to try to work around it by using gpg-agent, but it's not clear to me how I should set up profiles/project.clj to do this with clojars. Anyone got a relevant example they could share?

23:26 justin_smith: Thanks, at least I know who to bug if it proves to be a problem. :-)

23:27 justin_smith: coventry: n/p :)

23:32 coventry: bitemyapp: I picked it up for the reasons Bronsa mentioned. Those factors don't really matter for my purposes, but my code is cleaner that way due to an implementation detail in walk2, so I'd prefer to stick with it.

23:46 technomancy: Marmalade's version of nrepl-discover.el is out of date.

23:47 I'll just stick the latest version in troncle's git repository for now I guess.

23:54 dnolen: much more accurate source maps now in CLJS master https://github.com/clojure/clojurescript/compare/91b8b44ef8...604b2a457f

23:56 tbaldridge: dnolen: nice! does it help much with core.async?

23:57 dnolen: tbaldridge: I can set breakpoints on things in go blocks now which is a first

23:57 tbaldridge: but from what I can tell core.async needs to propagate line column information for the generated forms much more aggressively

23:58 tbaldridge: yeah, I figured that'd be the case. What happens if an outer form has a line no, but the inner form doesn't? Is it inherited?

23:59 dnolen: tbaldridge: well tools.readers give line info on every form

23:59 tbaldridge: line & col info

Logging service provided by n01se.net