#clojure log - Mar 03 2014

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

0:01 devn: heh

0:05 firefaux: how could I apply a function to every value in a map, and return the key that corresponds to the greatest value?

0:05 I was thinking first I'd need to apply the function

0:05 bob2: the answers sounds pretty similar to your question

0:05 firefaux: then use map-invert

0:06 and take value of the first item

0:07 hiredman: ,(key (apply max-key (comp inc val) (seq {:a 1 :b 2})))

0:07 clojurebot: :b

0:07 gfredericks: ,(key (apply max-key (comp inc val) {:a 1 :b 2}))

0:07 clojurebot: :b

0:08 firefaux: nice

0:20 muhoo: what's the equivalent of "this" in om? how would i get the actual underlying dom node of a component?

0:21 oh, doh, get-node :-/

0:21 * muhoo is tired

0:21 muhoo: though, get-node doesn't get THIS node, i have to give it a hardcoded id

0:23 firefaux: if you have the component, can you get the id from that?

0:23 pyrtsa: hiredman, firefaux: Watch out for empty inputs, though. max-key doesn't allow zero arguments. :(

0:24 ,(apply max-key [])

0:24 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/max-key>

0:24 firefaux: good catch, pyrtsa

0:24 gfredericks: ,(max)

0:24 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/max>

0:25 gfredericks: ,(<)

0:25 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/<>

0:25 gfredericks: ,(-)

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

0:26 brandon: I'm looking to get into Clojure programming. I'm mostly interested in web applications, what are some really top-notch resources? Anything you wish you knew when you started?

0:33 muhoo: brandon: read the oreilly clojure programming book, it has good background on web stuff

0:34 devn: http://clojure-doc.org/, http://www.clojure-toolbox.com/, http://getclojure.org/, http://joyofclojure.com/, http://planet.clojure.in/, http://www.clojuresphere.com/

0:34 brandon: Thanks!

0:35 I always feel a little awkward coming into these rooms to ask a single question. What's the 'normal' thing that people do in here?

0:35 devn: https://www.4clojure.com/ another one

0:45 firefaux: alight, thanks for the help everyone, I'm off to sleep

1:04 devn: aurorcoin connects you to an irc network

1:04 their qt app does

1:06 seangrove: bbloom dnolen_ : https://github.com/sgrove/om-stack-panel There's a tiny repo that's easy to experiment with. I'm not sure this is 100% feasible, there are lots of problems (rendering glitches) and it's not clear how to get it to actually be performant. Lots of thought and experimentation needs to go into it I think.

1:06 bbloom: It's small enough that you should be able to apply some of your wizardry simply enough :)

1:12 voldyman: whats the recommended way of creating a simple socket server in clojure?

1:20 technomancy: voldyman: just use java serversockets

1:20 check out the mire project for an example

1:21 voldyman: technomancy: ok, i was looking at your fork of server-socket, whats it current state?

1:22 technomancy: it exists and works and is unlikely ever to see another commit

1:22 voldyman: :)

1:36 seangrove: bbloom: Yeah, I'm definitely doing something horribly wrong if that's supposed to be faster. The simple ScrollView component is much smoother. I think it could make a difference if each component were more expensive to render (css effects, more complicated DOM), but the difference is pretty big so far. Will have to think about how it could be improved...

1:39 effy: does anyone have an idea if this presentation https://speakerdeck.com/log0ymxm/machine-learning-fundamentals-in-clojure has been recorded in video ? "Machine Learning Fundamentals in Clojure by Paul English"

1:58 muhoo: is it evil of me that i wish get-node would just get the node of the current compoent, instead of my having to deal with refs

2:03 johann_: muhoo: isn't that the default behavior if you dont specify a ref? could be mistaken

2:04 muhoo: oh, that'd be awesome, but the docs say it requires a ref as an arg

2:04 johann_: (om/get-node owner)

2:05 muhoo: https://github.com/swannodette/om/wiki/Documentation

2:06 johann_: https://github.com/swannodette/om/blob/master/src/om/core.cljs#L697

2:29 chare: guys have you heard of quasar pulsar?

2:29 http://blog.paralleluniverse.co/2013/05/02/quasar-pulsar/

2:30 I got a question about it.

2:31 anyone alive?

2:32 noprompt: deadghost: thanks for the bug reports. :)

2:32 deadghost: sorry for tripping you up. :(

2:32 deadghost: noprompt, that's for fixing them

2:32 *thanks

2:33 noprompt: deadghost: that should do it. lemme know.

2:34 deadghost: feel free to bug me in here after you open the issue and it won't take me an hour to get back to you. :)

2:34 seangrove: Hrm, I could definitely use a dropping buffer so I only process the last scroll event, that would be a good idea. Will try that in the morning

2:34 deadghost: will do

2:34 noprompt: deadghost: i've been bouncing between several projects today and i think my head wasn't in the right place when i pushed 0.1.7.

2:35 been hacking a sass->garden script which monkey patches Sass::Script::* and Sass::Tree::* to emit EDN

2:35 deadghost: noprompt, are there any compass clones on garden?

2:36 I saw one but it doesn't seem to have much activity

2:36 noprompt: deadghost: danneu started one, not sure where he's at w/ it though. :/

2:36 deadghost: hopefully because it was written perfectly the first time

2:36 noprompt: kind of a big undertaking though.

2:36 deadghost: yes that's the one

2:36 muhoo: on a resize event, i want a component to get the .-offsetWidth of its PARENT, not itself. i have been doing this with refs. what's the more delcarative way?

2:37 noprompt: deadghost: basically what i'm trying to do is emit mostly working garden code from a sass codebase.

2:37 muhoo: and not of the window either

2:37 noprompt: deadghost: that takes care a bulk of the hand-porting.

2:37 deadghost: seems more ideal than hand porting

2:38 noprompt: deadghost: there's some difficulty around emitting calls to mixins and functions but it's not too bad.

2:39 deadghost: one of the things I wanted to do before I even touched clojure

2:39 was write something lispy that compiled to sass

2:39 but skipping a step is good too

2:40 noprompt: stuff like interpolation isn't bad "foo #{$bar} baz" => (str "foo " $bar " baz")

2:40 @mixin foo (1, 2, 3) => (foo 1 2 3)

2:40 $foo: weeble => (def $foo "weeble")

2:41 1px + 2px => (+ (px 1) (px 2))

2:41 it's just effing tedious.

2:56 chare: what exactly is the purpose of lein trampoline, whats the purpsoe of NOT using it

3:04 muhoo: is there a way for set-state! to set the state of itself, not its owner?

3:04 i.e. setting the state of the compoent not the owner of the component

3:05 and is set-state! valid within a did-mount, or must it only be used within a render or render-state?

3:12 oh, that's it. Uncaught Error: No protocol method ICursor.-path defined for type boolean: false

3:12 owner is a boolean false

3:12 because that's my data, and om hates it.

3:13 * muhoo mutters and goes to read about protocols

3:22 Nyyx: how do I 'or' a list of bools

3:22 without reduce

3:22 paulswilliamsesq: Hi all, here goes.... Is stubbing functions considered okay in clojure, and if so, is with-redef an idiomatic way to do it?

3:23 Nyyx: something like splicing

3:23 oh wait nvm apply

3:24 nvm again "CompilerException java.lang.RuntimeException: Can't take value of a macro:"

3:24 I can't (apply or ...)

3:26 ,(apply #(or %&) '(false true false))

3:26 clojurebot: (false true false)

3:26 Nyyx: no...

3:27 ,(apply #(or % %2 %3) '(false true false))

3:27 clojurebot: true

3:27 Nyyx: :( thats what I want but not vararg

3:28 Kneiva_: ,(every? true? (list true false true))

3:28 clojurebot: false

3:28 Kneiva_: ,(every? some? (list true false true))

3:28 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: some? in this context, compiling:(NO_SOURCE_PATH:0:0)>

3:28 Kneiva_: ,(some? true? (list true false true))

3:28 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: some? in this context, compiling:(NO_SOURCE_PATH:0:0)>

3:28 Kneiva_: ,(some true? (list true false true))

3:28 clojurebot: true

3:28 rhg135: ,(eval (apply #'or [true nil true nil]))

3:28 clojurebot: true

3:29 rhg135: ,(eval (apply #'or [true nil false nil]))

3:29 clojurebot: nil

3:30 clgv: Nyyx: why not reduce?

3:30 Nyyx: Kneiva_: thanks

3:30 rhg135: If you do that in real code I will find you :-P

3:30 Nyyx: clgv: because I was looking for a function like every? and some? that do that already

3:31 clgv: "or" is a macro and certainly shouldnt be used like the above example

3:31 rhg135: clgv: of course not

3:32 clgv: Nyyx: ##(some identity [false false true false])

3:32 lazybot: ⇒ true

3:32 clgv: even with short circuiting ^^

3:33 Nyyx: ,(println "test")

3:33 clojurebot: test\n

3:34 Nyyx: ,(some identity [true (do (println "hi") false)])

3:34 clojurebot: hi\ntrue

3:34 Nyyx: no short circuit though

3:35 chare: what do you guys think about pulsar for clojure?

3:36 clgv: Nyyx: it short circuits. your println is evaluated outside of some befor that vector is passed to some ;)

3:37 $source some

3:37 lazybot: some is http://is.gd/IAmtiP

3:38 Nyyx: doesnt do that in the or macro

3:38 ,(or true (do (print "hi:")))

3:38 clojurebot: true

3:44 michaelr525: howdy

3:47 Kneiva: hello

4:12 chare: I've decided to use clojure with pulsar

4:12 and you guys can't stop me

4:20 rurumate: Hello everyone!

4:20 Which profiles are active by default, when doing a "lein install"?

4:21 I've noticed that the dev profile is NOT active then

4:29 noidi: rurumate, leiningen's docs state that "By default the :dev, :provided, :user, :system, and :base profiles are activated for each task"

4:29 https://github.com/technomancy/leiningen/blob/stable/doc/PROFILES.md

5:10 lvh: Hi

5:11 If I want to use an explicit random number generator or perhaps seed inputs to rand to make a function that uses random numbers referentially transparent; do I use the java interop or is there a nice clojure way of doing it

5:11 TEttinger: yes

5:11 lvh: TEttinger: There's a nice clojure way of doing it, or yes use the java interop

5:11 TEttinger: there's at least one set of seeded random number things in pure clojure

5:11 I have it somewhere...

5:12 https://github.com/kephale/clj-random

5:13 lvh: TEttinger: Thanks!

5:14 oh my me, a :cellularautomaton generator!

8:28 mishok13: hey, i have a small question about passing JDBC PreparedStatement parameters in HoneySQL + clojure.java.jdbc combination

8:28 https://gist.github.com/mishok13/9324779 <-- here you can see the current smallest example

8:28 in a nutshell: i want to change default fetchSize for one query

8:29 reading clojure.java.jdbc code didn't bring any enlightment

8:32 CookedGryphon: Hey, does anybody have any clues about testing core.async with midje when your go loop throws an exception?

8:32 at the moment it's just crashing a backgrounded thing and then passing because the desired outcome is no output

8:33 but I want to output with no exceptions!

8:51 BartAdv: I was interested to learn about the internals of lein-droid plugin, thought it would be relatively easy to just start the repl in its sources, pass my project map to functions and start experimenting

8:51 but I don't know how to easily grab that project map

8:52 anyone has some experience with developing leiningen plugins? Checked github README, it just says 'you have to pass your project map' (for now I've managed to dump it using lein-pprint, but it seems awkward)

8:58 clgv: Nyyx: ,[true (do (println "hi") false)]

8:59 ,[true (do (println "hi") false)]

8:59 clojurebot: hi\n[true false]

8:59 clgv: BartAdv: https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md

9:00 clojurebot: leiningen plugin |is| https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md

9:00 clojurebot: Roger.

9:00 clgv: leiningen plugin?

9:00 ~leiningen plugin

9:00 clojurebot: leiningen plugin is https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md

9:00 clgv: clojurebot: botsnack

9:00 clojurebot: thanks; that was delicious. (nom nom nom)

9:01 BartAdv: oh haha

9:04 but this is generally what I've read, and it looks like one should just inspect the output of lein-pprint and prepare the project map on his own

9:04 clgv: ,(apropos "forv")

9:04 clojurebot: ()

9:05 clgv: damn. guess I have to write that thing some time...

9:06 $findfn [a [1 2 3], b [4 5 6] :when (even? (+ a b))] [a b] [[1 5] [2 4] [2 6] [3 5]]

9:06 lazybot: java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0)

9:13 CookedGryphon: does anyone have any ideas how I fail a midje test on exception in a background thread

9:14 given that it's testing the fact that nothing is emitted on a core.async channel in a given situation and so I have no further output to check

9:24 clgv: CookedGryphon: cant you test the function alone that is used in the background thread?

9:34 joegallo: is the exception uncaught in the background thread?

9:34 if so, you could consider dropping some custom code in under http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#setDefaultUncaughtExceptionHandler%28java.lang.Thread.UncaughtExceptionHandler%29

9:35 just be sure to get the current value first and put it back when you're done ;)

9:37 CookedGryphon: clgv: not really, the unit which I'm testing is a core.async go-loop which takes in some data and potentially outputs some other data in response - that's what I'm testing

9:38 clgv: CookedGryphon: ah right. go-loops can only consume and write stuff within the fo-block, right?

9:38 *go

9:38 CookedGryphon: yeah, I don't have a choice but to run it in the background

9:39 joegallo: could do... doesn't feel like something I should be doing in a unit test though!

9:39 joegallo: shrug

9:39 :)

9:39 CookedGryphon: wait, that's not the issue

9:39 I've looked at this before

9:40 I think the issue is that core.async makes its own executor, I have no way to access the threads its actually using

10:34 n0n3such: AUR seems to be taking on a life of its own

10:34 https://www.cryptocoincharts.info/v2/coins/show/aur

10:40 mikerod: It seems that I have a rogue macro that is generating a constant that is too large. This throws the dreaded: "java.lang.ClassFormatError: Invalid method Code length <N> in class file <X>__init" message.

10:40 However, I only get this error during AOT-compilation

10:40 how is that possible?

10:41 I thought in AOT and not compilation, the same byte code would still be getting generated and verfied?

10:41 verified*

10:42 stuartsierra: AOT is weird in many ways.

10:43 mikerod: stuartsierra: I wouldn't argue with that statement :P

10:43 This error that is only happening in AOT concerns me though, since I think it is pointing out a potential issue I have.

10:43 I have a macro that is generating very large constants.

10:44 Somehow, without AOT this is not revealed to me. However, it still seems like that may be a cause for concern?

10:44 stuartsierra: It's not a great idea if you can avoid it.

10:44 Alternatives: Generate them once and save in an EDN file, generate at runtime, etc.

10:45 mikerod: stuartsierra: Yes, that's the general guidelines I've heard. I think that will be the approach I try to take.

10:46 I appreciate the feedback too.

10:46 stuartsierra: You're welcome.

10:51 sdegutis: What OpenID libraries are you all using?

10:52 jarjar_prime: @sdegutis: I just use facebook connect

10:52 haven't had much success product wise when it came to openid

10:53 sdegutis: Oh.

10:53 jarjar_prime: and on iOS you can just hand a token back without having to do anything special on the server

10:54 probably going to add google+ at some point once we get android up and running

10:56 sdegutis: Ok.

11:29 wei__: anyone use kioo successfully with om? the example code uses an outdated version of om

11:44 goldfeld: i have that kioo-riosity too, plan to use it soon

11:51 johnjelinek: hihi all :)

11:51 how's it goin'?

11:51 dakrone: you around?

11:52 wei__: hi johnjelinek, fine thanks

11:52 johnjelinek: wei__: great :)

11:52 rasmusto: its a beautiful morning

11:52 johnjelinek: I'm wondering -- how should I handle "Connection Reset" exceptions with clj-http? I have {:throw_exceptions false} but this one still gets through

11:52 wei__: looking for some example code using kioo + Om 0.5.0, if anyone happens to know

11:53 you could try/catch it, at worst

11:54 johnjelinek: wei__: well it's wrapped in a future and the exception only pops up with I deref ... maybe I should filter/remove within the future to only get the successful HTTP requests?

11:54 basically the future calls 26 HTTP requests

11:54 seangrove: dnolen_: I was a little disappointed that the binary in "All the code that's fit to printf()" doesn't seem meaningful :(

11:55 dnolen_: seangrove: heh

11:55 seangrove: dnolen_: Still, nice touch

11:56 abaker: Alex Miller around?

11:59 johnjelinek: (try @requests (catch java.util.concurrent.ExecutionException e (.getCause e))) -- this catches the exception, but how would I get it to ignore this and get all of the requests that were successful in the future?

12:00 hmm .. maybe all of my requests threw this exception

12:05 dnolen_: seangrove: btw I played around a bit with nodyn, seems really slow - like 300X slower than V8.

12:06 seangrove: dnolen_: Probably a better idea (if it's important) to run a separate node process, communicate over some connection

12:06 bbloom: seangrove: just saw your msges about perf... bummer... how many items are you in your views currently?

12:07 seangrove: bbloom: It's the same for either view, scrollview is consistently better. I think it's from recalc'ing all the heights though, like we talked about. Generates a ton a garbage, forces the GC on, big stutters

12:08 bbloom: seangrove: hm yeah, can you test it w/ just a fixed height w/o measuring?

12:08 seangrove: bbloom: Yeah, suppose that would just take a minute or two

12:14 dnolen_: seangrove: btw the profile is pretty informative, appears currently all the time is lost in CLJS

12:14 seangrove: dnolen_: Yeah, recalc-heights mostly

12:15 dnolen_: seangrove: mostly mean all

12:15 meaning all

12:15 seangrove: A lot of thrashing there. Need to be more clever about it

12:15 dnolen_: no time is actually spent rendering

12:16 seangrove: dnolen_: Sure, what I was saying earlier is I wanted to limit the number of unnecessary calls into cljs to render when I know nothing has changed

12:16 dnolen_: seangrove: how big is the generated list of things?

12:16 seangrove: dnolen_: 1 vector pair for every item in the list. Give me a bit of time and I'll get a fixed-height version going and see how the performance is on that, shouldn't need to the list of offsets for that

12:17 dnolen_: seangrove: it should be easy to hack in a special version of om.core/set-state! that doesn't invalidate the path btw

12:17 seangrove: no need to wait for me :)

12:17 at least for perf testing

12:17 seangrove: dnolen_: I did, I ended up using atoms, it helped a bit

12:17 dnolen_: Then that mutated to channels which did the calculations and used set-state! to signal a rerender necessary

12:18 That helped more, but still I think I'm just missing something clever here. I'm fine to take some time to get it right.

12:21 dnolen_: seangrove: there's definitely some weird logic going on

12:22 seangrove: it scrolls smoothly then completely locks up

12:22 seangrove: dnolen_: Yeah, I'd emphasize experimental. That lockup is because it triggers a round of rendering

12:22 dnolen_: for a couple of scrolls

12:22 623000+ calls to ChunkedSeq

12:22 that just doesn't make any sense

12:22 seangrove: Hah

12:23 bbloom: lol whoa

12:23 dnolen_: I suspect something minor here

12:23 which will speed things up considerably

12:25 johnjelinek: can I make a future of futures

12:25 ?

12:25 I'd like to do (future-done? my-future) which would deref a collection of futures

12:26 seangrove: bbloom: Even being stupid with the fixed-height virtual stack panel, it's 60fps easy

12:26 bbloom: seangrove: so you're saying the slow part is your measuring code path?

12:26 seangrove: bbloom: Yeah, all the data that's being mangled keeping track of heights and offsets

12:27 johnjelinek: (future (my-running-futures)) immediately returns true

12:27 any idea why?

12:27 prolly because something is lazy?

12:29 abaker: are there any library best practices documented anywhere? I'm putting together clj-sparql, a library for dealing with SPARQL endpoints (see https://github.com/AlBaker/clj-sparql )

12:30 interested in if, say passing in a 'db-spec' style map to the query function is appropriate, or are there better ways to make the function more composable for end users

12:30 johnjelinek: I am trying (doall @my-futures-collection)

12:30 and returning a future

12:32 seangrove: bbloom dnolen_ Pushed the fixed-height stack panel with windowing, performs how you'd expect. For the variable-height, need to be more clever about keeping track of item positions (height + offset)

12:33 pyrtsa: johnjelinek: How about... (future (doall (map deref my-futures))) ?

12:34 It isn't optimal, since it's creating a new thread for just waiting for the futures to complete, but with the available interface (and not using e.g. core.async), you can't get much better.

12:35 johnjelinek: pyrtsa: I'll give that a shot

12:41 pyrtsa: lol, wrapping my (future (doalls in (future (doalls reminds me of callback hell

12:41 maybe I'm not thinking about this the right way?

12:41 pyrtsa: It's worse than callback hell. It's a spawn-thread-and-wait hell.

12:42 johnjelinek: lol -- maybe I should just be using core.async?

12:43 pyrtsa: The problem is: java.util.concurrent.Future (which clojure.core/future models) doesn't provide a callback mechanism.

12:43 Yeah, core.async. Or RxJava if you're into that thing.

12:43 johnjelinek: I see

12:43 lol, I've been trying to avoid core.async -- but now it feels like I may have no choice

12:45 pyrtsa: johnjelinek: This might be of interest as well, but beware, it's pretty new: https://github.com/Netflix/RxJava/tree/master/language-adaptors/rxjava-clojure

12:46 johnjelinek: I think I'll go core.async

12:47 pyrtsa: That's a good choice.

13:16 danneu: deadghost: once I started iterating on my Compass->Garden port in production, I ended up splitting it into two libs: CSS helpers and a build tool.

13:16 dbasch: I'm having a problem using openid with cemerick/friend. Whenever I try to access a protected resource without being logged in I get redirected to a blank /login page

13:43 sdegutis: Is there a built-in tagged literal to create strings from symbols?

13:43 Where #w[foo bar baz] would return ["foo" "bar" "baz"]

13:44 hyPiRion: It's called (mapv str '[foo bar baz]), I guess.

13:44 but no, not built in.

13:44 sdegutis: Ah. I think it would be more terse as #w, so it may be worth writing a third party lib for it.

13:44 Especially if Clojure wants to compete with Ruby, which has this built-in.

13:47 llasram: Ruby also has Perl-inspired magical global variables tied to the regular expression engine

13:47 Do not want

13:47 sdegutis: Agreed, that feature is bogus.

13:47 johnjelinek: strange ... I did async/close! my-chan and it crashed LT

13:47 sdegutis: Oh.

13:54 TimMc: gfredericks: OK, it looks like gen-class definitely requires writing out to disk -- and then reading back from disk again. :-(

13:55 bbloom: sdegutis: llasram: that feature is *great* in perl if you're writing 3 line scripts.... but it's friggin useless in ruby b/c ruby's top-level is all kinds or weirdly broken / different than than method and class bodies

13:55 jcromartie: bbloom: I thought you said "that feature is in great peril"

13:56 bbloom: it's clear to me ruby started out as "i want a better perl" and later became "oh, smalltalk is cool" :-)

13:56 sdegutis: jcromartie: :D

13:56 llasram: If only Matz had added system images

13:57 sdegutis: bbloom: Matz himself said: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/179642

13:57 technomancy: somehow they claim scheme got added into the mix, but I'm pretty sure that's just about "why not use question marks for predicates; those look nice"

13:58 amalloy: sdegutis: #w[x y z] is not very much terser than (w x y z). exact same number of characters, i think?

13:58 bbloom: sdegutis: there you go :-P

13:58 sdegutis: amalloy: ah but is it as clear?

13:59 amalloy: uh...yes? w is a macro, easily looked up in a namespace with M-. or whatever non-emacs equivalent; #w is in data_readers.clj, which you have to go digging around for

13:59 technomancy: well, it feels like a reader concern to me

13:59 sdegutis: amalloy: True. Although isn't data_readers.clj only looked up in the current project?

13:59 amalloy: If so, it wouldn't be much digging, you just open the root-level file named data_readers.clj

13:59 technomancy: I don't think it's useful enough to justify the #w shortness, but I agree the former is clearer

14:00 amalloy: sdegutis: the fact that that's even a question makes it likely that it's harder to justify. the way it's looked up is not as widely-known as namespaced things

14:00 sdegutis: technomancy: It may not be in a general project, but in one where the focus is on configuration (a la Chef) it could be very useful.

14:00 llasram: sdegutis: the implementation finds and loads all top-level data_readers.clj files on the classpath

14:00 technomancy: amalloy: M-. not working on reader literals is dumb too =)

14:00 sdegutis: amalloy: touché good sir

14:00 llasram: Ahh.

14:01 technomancy: also: aliases for reader literals should be able to be specified in the ns macro =P

14:01 so you could use #w in one namespace without stomping others

14:01 amalloy: technomancy: that'd be just one more thing making it hard to read clojure code without running it, for eg analyzers

14:01 technomancy: namespaces are cool, mkay?

14:02 llasram: And non-namespaced literals are implicitly in the namespace rhickey.decided.this.was.cool

14:02 technomancy: llasram: it's very un-egalitarian

14:02 much like the fact that you can't use namespaced :my.stuff/clauses in ns; that's super annoying

14:03 sdegutis: I'd love to see a Chef written in Clojure, although that day will undoubtedly never happen, which is a shame because Clojure is the Ruby that Ruby was meant to be.

14:03 llasram: technomancy: On these points I cannot disagree

14:03 ToBeReplaced: sdegutis: pallet?

14:04 locks: sdegutis: it is?

14:04 sdegutis: ToBeReplaced: whoa

14:04 locks: yessir

14:05 locks: but they're almost opposites :P

14:05 sdegutis: locks: It's dynamic, terse, written for extensibility and expressiveness, and ideal for sane and maintainable DSLs.

14:05 locks: yessir

14:05 ToBeReplaced: totally investigating.

14:06 ToBeReplaced: sdegutis: gl, i eval'd it with chef and ansible a little over a year go and it was a little rough around the edges at the time -> i imagine it's come a long way

14:06 sdegutis: ToBeReplaced: thanks

14:12 dbasch: I'm trying to write a webapp with compojure, and failing at what should be extremely basic: I want the user to identify with openid, and then I want to restrict resources only to identified users. I thought Friend was the answer, but I can't get it to work properly. Does anyone have examples of how to do this?

14:14 sdegutis: dbasch: I have been using openid4java but am looking into JOpenID.

14:14 I could not get Friend to work, but I think I'm not the target audience, which explains that.

14:14 dbasch: sdegutis: the openID part works, what doesn't work is restricting routes to logged in users

14:15 I cloned this example, but it doesn't have any protected urls: friend-demo.herokuapp.com/openid/

14:15 jcromartie: man, when it comes to application configuration, when did we forget about environment variables?

14:17 dbasch: what I want to do (but I don't know how) is wrap all my restricted handlers with something that checks for authentication, and redirects a user to the login page if not

14:17 sdegutis: dbasch: you'd have to wrap your route handler code in some kind of function that checks the current user's permissions

14:17 We do this with a macro that I've been trying to turn into a function for a year now with no luck.

14:18 dbasch: sdegutis: friend/authenticate supposedly does this, but it doesn't work properly

14:18 or at least I can't get it to work

14:19 jcromartie: dbasch: what's the challenge here? we do it

14:19 so long as all your restricted routes are in one place

14:19 sdegutis: Ah it should have been named "Mellon".

14:19 jcromartie: otherwise it's a bit piecemeal

14:19 dbasch: jcromartie: when I try to access a restricted resource, I get redirected to a blank login page instead of my login form

14:20 jcromartie: I

14:20 jcromartie: I'm using essentially this code: https://github.com/cemerick/friend-demo/blob/master/src/clj/cemerick/friend_demo/openid.clj

14:21 the only difference is that I set allow-anon? to false for the group of restricted routes

14:23 if I try to go to mysite/restricted without being logged in, I get redirected to mysite/login which is a blank page. I have no idea how to fix it

14:34 jcromartie: don't you need to specify mysite/login ?

14:34 sdegutis: Looks like Pallet does all that we need.

14:34 Only lacking in docs, but the source is open.

14:35 jcromartie: dbasch: I mean do you have anything to render /login ?

14:37 dbasch: jcromartie: if I render login, then after the openid login I get redirected to my login page with a url that looks like http://localhost:8080/login?openid.ns=http%3A%2F%2Fspe......

14:38 jcromartie: and debugging login shows that authentication doesn't happen

14:39 jcromartie: sorry, I don't really know much about the friend/openid stuff

14:39 dbasch: jcromartie: this is what login looks like:

14:39 (GET "/login" req

14:39 (if-let [auth (friend/current-authentication req)]

14:39 (a/home req auth)

14:39 (do (println "not authenticated" req) (c/home req)))))

14:40 jcromartie: thanks, I

14:40 amalloy: dbasch: www.refheap.com

14:41 dbasch: amalloy: sorry about that https://www.refheap.com/51256

14:42 I'm at the end of my rope, pulling my hair out in frustration

14:42 * seangrove chuckles imagining it

14:42 dbasch: cannot believe it's so hard to do something that in Sinatra would take me 5 minutes

14:43 seangrove: dbasch: There's a reasonable chance you're using the wrong tool. Friend is a big system, not something you would typically use in sinatra.

14:43 I think it's more akin to Devise

14:44 sdegutis: Yeah we have something similar: (GET "/some/page" req ,,, (with-authorized-user req (do-some-stuff)))

14:44 dbasch: seangrove: so what's the right/easier way to wrap routes so that they do one thing if you're authenticated and something else if you're not?

14:44 sdegutis: I could de-macroize it by just putting (fn [] (do-some-stuff)) instead, but I go back and forth on that.

14:45 seangrove: dbasch: We use middleware. Wrap routes you care in with it, it checks for an api-key in the query-params or a token in the session, passes through if we can find the appropriate user, otherwise 401 or redirects

14:45 sdegutis: seangrove: Ahhh, I like that solution better I think.

14:45 dbasch: yeah, I like the with-authorized-user approach

14:46 AeroNotix: any tools that given a regex pattern would generate a string which satisfies that regex?

14:46 sdegutis: seangrove: My only gripe is that you have to separate priv routes from non-priv routes even if they're conceptually related (user-routesa, etc).

14:46 seangrove: sdegutis: I suppose that could be true. I'd have to think about

14:47 dbasch: sdegutis: right, I was hoping that you could just wrap all the routes you care about with something like friend/authenticate

14:47 sdegutis: Although they could still live in the same file, just two different (defroutes ...)

14:47 dbasch: in my case, I just don't want to accidentally leave a route unprotected

14:48 sdegutis: seangrove: also, last time I tried something similar, I accidentally made it so that in the list of routes, after the first one that required authentication, *every* next route also required authentication.

14:48 Not sure how to avoid that in the future, that was a gross bug.

14:48 dbasch: conceptually wrapping routes in friend/authenticate is the right thing, except I can't get it to work

14:48 seangrove: sdegutis: Yeah, it's possible. But we explicitely separate our authenticated routes and unauthenticated routes to addresss dbasch's concern.

14:49 sdegutis: Right.

14:49 seangrove: dbasch: So just write your own authenticate method, it's simple

14:49 sdegutis: Thanks for the ideas yahl.

14:49 dbasch: seangrove: how?

14:49 seangrove: sdegutis: Then we namespace the url so that we only authenticate /api/*, or whatever it might be

14:49 clojurebot: Huh?

14:49 sdegutis: seangrove: Ah.

14:50 dbasch: seangrove: I spent too much time trying to write my own method and couldn't get it to work

14:51 seangrove: dbasch: https://www.refheap.com/2776651fdf9297bcb0a77a050 Add your checks there (presumably you're storing some token id in the session, or have a param in your url)

14:52 dbasch: seangrove: I'll give it a try, thanks

14:53 seangrove: dbasch: Then wrap the authenticated routes you care about and specify a prefix https://www.refheap.com/7a62e3170452398ee2502d656

14:53 That way you're explicit in your code about what needs authentication and what doesn't. It also helps you structure your urls so that they can be versioned/upgraded in a sane way

14:54 dbasch: seangrove: for an api, sure. This is a simple webapp

14:54 sdegutis: Same here.

14:55 seangrove: dbasch: What's the difference?

14:55 They both follow the same principles

14:56 dbasch: seangrove: I find it a bit strange to define routes in one place, and to have to explicitly specify the prefixes that require authentication in another

14:57 seangrove: dbasch: With that code, if you omit the prefixes, everything needs to be authed

14:57 If not, it's just a one line change

14:58 And if that's the case, then just wrap the routes you've defed and want authed

15:03 jchauncey: so ive asked in the leiningen chan and didnt get an answer but has anyone written a active middleware for a core leiningen task?

15:05 llasram: jchauncey: I'm not really sure what that question means...

15:05 jchauncey: im trying to write a middleware for the uberjar task

15:05 gtrak: jchauncey: my understanding is that middleware is only for the project map, not tasks, you'd have to make a new task or use a hook maybe?

15:05 llasram: Leiningen middleware doesn't apply to a task. It's just code which gets a chance to modify the map

15:06 what gtrak said

15:06 jchauncey: and doing uberjar.plugin/middleware dosnt seem to get picked up

15:06 thats fine

15:06 i just need to override a value in the project map when a task is called

15:06 it works if i explicitly set :middleware in the project.clj

15:06 gtrak: can you override it for all tasks?

15:06 jchauncey: but you can have it actively find all middleware if it conforms to a standard

15:07 thats what it does if you use :middleware in project.clj

15:07 i would rather not do that

15:07 instead only override for a specific task/plugin (uberjar

15:07 )*

15:07 gtrak: maybe there's a dynamic var somewhere that holds the current task

15:07 llasram: That sounds like maybe you want a hook

15:07 jchauncey: llasram: yeah maybe

15:07 llasram: But if not -- are you just trying to get automatic middleware?

15:07 jchauncey: could use preprend to run what i need before the uberjar function is called

15:07 llasram: Sure

15:08 jchauncey: llasram: yup

15:08 gtrak: yea, you want a hook

15:08 llasram: I've definitely done it before. Do you have a link to your project?

15:08 jchauncey: llasram: nope =\

15:08 Like hooks, middleware will be applied automatically for plugins if you put it in plugin-name.plugin/middleware. <(------------------- from the plugins.md

15:08 llasram: Yes

15:09 jchauncey: hrm

15:09 llasram: So if you have a plugin named `my-plugin` which you include in the plugins vector (as `my-plugin`), then that var-function will get invoked automatically as middleware

15:09 jchauncey: i basically want my teams to include my plugin and get this for free

15:10 no need to explicitly set :middleware or :hooks

15:10 yes

15:10 gtrak: your plugin can provide a middleware that alters the hooks

15:10 jchauncey: but how does that work if i want middleware for a core task

15:10 llasram: Dude, you are thinking about it all wrong

15:10 Human, rather

15:10 Let's not be sexist

15:10 jchauncey: hehe

15:10 isA man

15:10 llasram: Middleware is task-irrelevant.

15:11 jchauncey: correct

15:11 llasram: The namespace for your plugin needs to match the name of your *plugin*

15:12 Naming `uberjar.plugin` is completely broken

15:12 You need to have a `my-plugin.plugin/middleware` var-function

15:12 Where "my-plugin" is whatever you've named your plugin

15:12 gtrak: your plugin can provide a 'project' middleware that alters the hooks, which then hook into uberjar.

15:13 llasram: gtrak: Um, or just use Leiningen's default hook auto-activation method :-)

15:13 gtrak: oh :-)

15:13 jchauncey: yeah

15:13 gtrak: middlewares can do anything :-)

15:14 ah, I was thinking of this: 'Hooks can also be loaded manually by setting the :hooks key'

15:16 llasram: jchauncey: Here's an example of a plugin which includes an automatic hook on the `uberjar` task (as well as automatic middleware): https://github.com/timmc/lein-otf/blob/master/src/lein_otf/plugin.clj#L26

15:16 jchauncey: thanks

15:16 i think a hook is what i want

15:18 llasram: OOC, what's the end-goal you're trying to achieve?

15:21 jchauncey: ive build a series of plugins for bumping versions based on SEMVER that will be used by our CI system

15:21 er built rahter

15:22 TimMc: Anyone know of an alternative to gen-class and proxy that will allow me to extend an abstract class and get a real Class out of it? (And doesn't involve AOT.)

15:22 gtrak: what's wrong with those two?

15:23 jchauncey: that version is used when an uberjar is built and our middleware reads that version from a VERSION file. I want to insure that the file is created before uberjar is executed but only for that task

15:24 llasram: TimMc: Write a tiny stub class in Java :-D

15:25 TimMc: Or use ASM to generate a class in-memory which you then load via Clojure's DynamicClassLoader

15:26 TimMc: D-:

15:27 llasram: The former is obvious more sane

15:27 TimMc: gtrak: proxy doesn't give you a real Class; gen-class involves barfing stuff out to disk.

15:28 llasram: TimMc: What are you trying to do at a higher level?

15:30 TimMc: llasram: Write a Zuul filter loader.

15:31 llasram: Is the class found via reflection?

15:31 sdegutis: What will Clojure be in 15 years?

15:31 TimMc: Netflix Zuul will allow you to dynamically load filters, but it gives you a source blob read from disk (and the path name it foudn it at) and expects you to give back a Class that extends ZuulFilter, an abstract class.

15:31 sdegutis: What will be different about it?

15:31 TimMc: It's great for Groovy, not as much for Clojure.

15:31 xuser: sdegutis: it will be dead

15:31 llasram: Oh, so then it needs to construct instances of the class itself?

15:32 sdegutis: I hope it'll start faster :)

15:32 TimMc: llasram: Yeah. :-/

15:32 sdegutis: xuser: oh?

15:32 xuser: sdegutis: maybe with Java 9?

15:32 llasram: TimMc: I know you're not a fan, but sounds like it could be a case for the Java stub classes, unless you need to generate multiple of theses classes w/ different behavior

15:33 TimMc: Then I think you really actually might have a use for ASM :-D

15:33 TimMc: Multiple, different behavior, not known in advance. :-/

15:33 xuser: llasram: is ASM the lib that generates java bytecode in the clojure compiler?

15:34 llasram: It is, although it's not necessarily a good idea to use it. It's not exposed as a public API, and they e.g. are bumping the version of it from 3 to 4 between 1.5 and 1.6

15:34 TimMc: Not necessarily a great example, but https://github.com/llasram/esfj/blob/master/src/clojure/esfj/provider.clj#L46

15:35 TimMc: llasram: Do you know if Clojure's lack of an "extend this class" utility is ideological or technical?

15:36 llasram: TimMc: I'd guess a combination of both, but more ideology

15:36 But really have no special insight

15:37 TimMc: FYI, ASM includes the "ASMifier" http://asm.ow2.org/asm40/javadoc/user/org/objectweb/asm/util/ASMifier.html

15:38 You run it on a Java class file, and it spits out the ASM (Java) API calls necessary to generate that class file

15:38 TimMc: Neat.

15:40 fro_: ,(-> {:a 0 "b" 4} (:a))

15:40 clojurebot: 0

15:40 llasram: I think this approach will get a lot more sane once clojure.tools.jvm is "finished"

15:40 fro_: ,(-> {:a 0 "b" 4} ("b"))

15:40 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>

15:40 fro_: ,(-> {:a 0 "b" 4} (:b))

15:40 clojurebot: nil

15:40 fro_: lol

15:40 llasram: I mean, check out that code-as-data: https://github.com/clojure/tools.emitter.jvm/blob/master/src/main/clojure/clojure/tools/emitter/jvm/emit.clj

15:40 fro_: check it, guys )

15:40 funny

15:41 but

15:41 ,({:a 0 "b" 4} "b")

15:41 clojurebot: 4

15:41 llasram: (inc Bronsa)

15:41 lazybot: ⇒ 18

15:42 fro_: there is a problem with macros ->?

15:42 llasram: fro_: What there is unexpected?

15:43 fro_: ,({:a 0 "b" 4} "b")

15:43 clojurebot: 4

15:43 llasram: Yes?

15:43 fro_: ,(-> {:a 0 "b" 4} ("b"))

15:43 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>

15:43 rasmusto: ,(-> {:a 0 "b" 4} (get "b"))

15:43 clojurebot: 4

15:43 fro_: ok

15:43 llasram: ,(macroexpand `(-> {:a 0 "b" 4} ("b"))

15:43 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

15:43 llasram: ,(macroexpand `(-> {:a 0 "b" 4} ("b")))

15:43 clojurebot: ("b" {"b" 4, :a 0})

15:44 rasmusto: ,(macroexpand `(-> {:a 0 "b" 4} (get "b")))

15:44 clojurebot: (clojure.core/get {"b" 4, :a 0} "b")

15:44 llasram: fro_: ^^ all clear?

15:44 fro_: ,(macroexpand `(--> {:a 0 "b" 4} ("b")))

15:44 clojurebot: (sandbox/--> {"b" 4, :a 0} ("b"))

15:44 fro_: ,(macroexpand `(->> {:a 0 "b" 4} ("b")))

15:44 clojurebot: ("b" {"b" 4, :a 0})

15:45 fro_: yea

15:45 clear

15:45 thx

15:49 sdegutis: ,("b" {"b" 4})

15:49 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>

15:50 sdegutis: ,('b {'b 4})

15:50 clojurebot: 4

15:50 sdegutis: ,(:b {:b 4})

15:50 clojurebot: 4

15:50 sdegutis: Oh.

15:50 ordnungswidrig: sdegutis: symbol and keyword implement ifn

15:50 sdegutis: ,(4 {4 :b})

15:50 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

15:50 sdegutis: ,({} {})

15:50 clojurebot: nil

15:50 sdegutis: :D

15:51 rasmusto: ,({} {{} 'foo})

15:51 clojurebot: nil

15:51 rasmusto: ,({{} 'foo} {})

15:51 clojurebot: foo

15:51 sdegutis: :D

15:51 I'd never have guessed that one.

15:51 ordnungswidrig: ,({} {}) ;; <= clojure emoticons

15:51 clojurebot: nil

15:51 sdegutis: ,(() ())

15:51 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentList$EmptyList cannot be cast to clojure.lang.IFn>

15:51 ordnungswidrig: ,({:o :o})

15:51 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentArrayMap>

15:51 rasmusto: ,:D

15:51 clojurebot: :D

15:51 ordnungswidrig: ,'({:o :o})

15:51 clojurebot: ({:o :o})

15:52 sdegutis: Hold on now, let me remember..

15:52 ,(= () '())

15:52 clojurebot: true

15:52 sdegutis: Yes, that's a hipster.

15:53 He's wearing steampunk pilot goggles.

16:08 jowag: ,(:•_:•)

16:08 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :?_:?>

16:11 TimMc: ,'😰

16:11 clojurebot: ??

16:13 sdegutis: :D

16:45 asthasr: Good afternoon!

16:45 And/or evening, as the case may be.

16:45 rasmusto: goodaften

16:46 asthasr: I'm writing a clojure program that will be reading a large file and processing it in various ways. Unfortunately, I'm getting an error on one of my preconditions, and I'd like to be able to see the line of the file that's causing the error. How can I accomplish this?

16:48 sdegutis: The exception should have a stacktrace I think.

16:48 rasmusto: asthasr: you're talking about finding the line in the large file?

16:48 asthasr: Sure, there's a stacktrace, but it doesn't include the data, just the location where it occurred (the :pre condition)

16:48 Yes, rasmusto. I want to see what input is causing the precondition to fail

16:49 but when I try to do printlns before the fact, they never seem to be output

16:49 rasmusto: hrm, yeah I think those functions get messed with

16:50 AeroNotix: https://github.com/AeroNotix/lapse reiddraper

16:52 rasmusto: asthasr: erm, you can do a {:pre (do (prn "blah") (assert something))}

16:53 justin_smith: asthasr: or maybe even {:pre [(and datum (f datum))]}

16:53 that should show datum when it fails

16:53 rasmusto: well, what if datum is nil?

16:54 reiddraper: AeroNotix: oh neat

16:54 rasmusto: I assume nil would be bad, but I don't know the context much

16:54 justin_smith: (and [x] (f x))

16:54 rasmusto: ah, that'd do it :)

16:55 justin_smith: nope, that does not work because it prints the literal test that failed

16:55 rasmusto: ,((fn [x] {:pre [(and [x] (odd? x))]} x) 2)

16:55 clojurebot: #<AssertionError java.lang.AssertionError: Assert failed: (and [x] (odd? x))>

16:55 rasmusto: ah, darn

16:55 justin_smith: but it does not show the value it failed on

16:55 rasmusto: ,((fn [x] {:pre [(do (prn x) (odd? x))]} x) 2)

16:55 clojurebot: 2\n#<AssertionError java.lang.AssertionError: Assert failed: (do (prn x) (odd? x))>

16:55 justin_smith: better, but gives us unneeded printouts

16:56 ((fn [x] {:pre [(or (odd? x) (prn x))]} x) 2)

16:56 only prints when it fails :)

16:56 ,((fn [x] {:pre [(or (odd? x) (prn x))]} x) 1)

16:56 clojurebot: 1

16:56 justin_smith: ,((fn [x] {:pre [(or (odd? x) (prn x))]} x) 2)

16:56 clojurebot: 2\n#<AssertionError java.lang.AssertionError: Assert failed: (or (odd? x) (prn x))>

16:56 rasmusto: ,((fn [x] {:pre [(if (odd? x) (do (prn x)))]} x) 2)

16:56 clojurebot: #<AssertionError java.lang.AssertionError: Assert failed: (if (odd? x) (do (prn x)))>

16:57 AeroNotix: reiddraper: I sent a PR on github for check, not sure if it's the right place.

16:57 justin_smith: prn returns nil, so the do is not needed

16:57 rasmusto: gotcha. or seems like it'd work well

16:58 justin_smith: has the right semantics at least

16:58 though could be opaque to other users of the code

16:58 rasmusto: yeah, name is a bit inconvenient

16:58 justin_smith: I use or / and for optional chaining so it comes naturally to me, but I am aware that's just something that makes me weird

16:59 asthasr: it doesn't seem to work for me

16:59 let me show code

16:59 {:pre [(or (every? (comp (partial = Name) type) original-names) (prn original-names))]}

16:59 and in the repl

16:59 (file->records (first data-files))

16:59 AssertionError Assert failed: (or (every? (comp (partial = Name) type) original-names) (prn original-names))

17:00 no actual output

17:00 mikerod: asthasr: sounds like you'd need to hav a bit more fine-grained error checking

17:01 putting it all in the pre-condition isn't likely to get you a lot of useful context

17:01 justin_smith: if that failed, I think it should have printed

17:01 yeah, a series of assert statements is probably better here, agreed

17:02 `cbp: If anyone finds this useful: https://www.refheap.com/51314

17:03 They're a bunch of functions to send sexps to the cider repl which i stole from someone that had them in nrepl and i ported them

17:03 ..to cider

17:04 RickInAtlanta: `cbp thx

17:05 `cbp: :)

17:09 asthasr: Thanks guys. I think I'm going to have to rework some of my processing logic to make asserts at more points...

17:09 (I'm kind of a lisp noob, this is the first real project I've tried in clojure and it's kind of... awkward... so far)

17:09 TimMc: llasram: OK, I can get gen-class namespaces to compile to disk, and then load the classes. But I think that will be a bad way to handle things in production. (I'm not sure I'll have write access to the filesystem, or even *should*.)

17:10 ordnungswidrig: I want to init my app for dev from ns user, is there anything better than (var-get (ns-resolve 'my.namespace 'some-function)) to lazily resolve at runtime?

17:11 justin_smith: asthasr: another thing that helps is making more / smaller functions, making sure each one does exactly one thing, and testing their behavior individually

17:11 ordnungswidrig: repl startup will fail if anything in user refers to a broken something in another ns

17:12 justin_smith: ordnungswidrig: that's why it's helpful to have repl start out with an ns that isn't in your codebase (like user normally would be)

17:12 mikerod: asthasr: stick with it, it gets better

17:13 ordnungswidrig: yes, but I want to have some convenience functions in user to start the system

17:13 justin_smith: don't

17:13 put them in util, or something else

17:13 leave user empty

17:14 sorry, don't mean to sound bossy

17:14 ordnungswidrig: come on! is best practive nowadays :)

17:15 s/v/c

17:15 technomancy: the user namespace is really not a great place to dump convenience stuff

17:15 because it just goes away when you switch namespaces

17:15 you need commands exposed in your client IMO

17:15 justin_smith: yeah, for that very "repl failing to start" reason for starters

17:16 sdegutis: I didn't know the user ns was so transient.

17:16 technomancy: also putting one in a library is super sketchy

17:16 sdegutis: Doesn't REPLy do that?

17:16 ordnungswidrig: "exposed in your client"?

17:16 sdegutis: In that case I think it's helpful.

17:16 technomancy: sdegutis: I think it intercepts some forms to give the illusion of having them exist in all namespaces

17:17 sdegutis: Ah interesting.

17:17 technomancy: which is neat, but I don't like how it makes them look like function calls

17:17 slime does this better; it accepts commands like ,do-somethin

17:17 sdegutis: Yeah, they should be custom tagged readers.

17:17 technomancy: =P

17:17 sdegutis: #doc interpose

17:17 No srsly.

17:17 #examples cond->

17:17 technomancy: no

17:18 it shouldn't look like a value

17:18 sdegutis: But it's so terse!

17:18 technomancy: it should be something that's invalid clojure syntax

17:18 it's so simple!

17:18 and powerful!

17:18 sdegutis: xD

17:18 Invalid Clojure syntax? No such thing.

17:19 Invalid Clojure semantics, sure. But nearly everything is valid Clojure syntax.

17:19 justin_smith: ::::sdegutis:

17:19 ,::::sdegutis:

17:19 clojurebot: #<RuntimeException java.lang.RuntimeException: Invalid token: ::::sdegutis:>

17:19 justin_smith: that's invalid clojure syntax

17:19 sdegutis: ,new Exception()

17:19 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: new in this context, compiling:(NO_SOURCE_PATH:0:0)>

17:19 technomancy: ,~ohai

17:19 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ohai in this context, compiling:(NO_SOURCE_PATH:0:0)>

17:19 justin_smith: for example

17:19 sdegutis: justin_smith: ah

17:19 ordnungswidrig: ,(keyword "::::sdegutis:)

17:19 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading string>

17:20 ordnungswidrig: ,(keyword "::::sdegutis:")

17:20 clojurebot: :::::sdegutis:

17:20 sdegutis: Hey guys

17:20 justin_smith: right, the object can exist, but that read syntax is invalid

17:20 sdegutis: Look over there ------>

17:20 asthasr: ,(:::::sdegutis)

17:20 clojurebot: #<RuntimeException java.lang.RuntimeException: Invalid token: :::::sdegutis>

17:20 technomancy: whoa, batman

17:20 * sdegutis sneaks away quietly while everyone's looking over there ------>

17:22 ordnungswidrig: so, in which way is ns user special?

17:23 sdegutis: ,(do (in-ns 'user) (def foo 3) ,,, (in-ns 'somethingelse) ,,, (in-ns 'user) foo)

17:23 clojurebot: 3

17:23 sdegutis: Dunno.

17:23 ordnungswidrig: so

17:24 justin_smith: it is special because repls start up in it

17:24 ordnungswidrig: ok

17:24 justin_smith: so if it is broken the repl can't start

17:24 ordnungswidrig: "because it just goes away when you switch namespaces"

17:24 technomancy: it's also loaded at startup

17:24 ordnungswidrig: technomancy: says

17:25 justin_smith: I *think* what technomancy meant by that is that the advantage of putting things in user disappears when your switch namespaces

17:25 and it is easy to switch namespaces

17:25 ordnungswidrig: I see

17:25 technomancy: ordnungswidrig: (use 'clojure.pprint) ; great, now you have it. for a while, then it's gone when you in-ns

17:25 justin_smith: so why not put the stuff you want in a different one

17:25 technomancy: vs M-x cider-pprint or whatever

17:25 which will always be with you

17:25 till death do you part, &c

17:25 ordnungswidrig: so I better use core!

17:25 *g*

17:25 technomancy: super tempting!

17:25 ordnungswidrig: reader macro ftw?

17:26 technomancy: no, use elisp

17:26 rasmusto: eclipse?

17:26 sdegutis: lol

17:26 rasmusto: sorry

17:26 asthasr: I think I sounded a bit too pejorative when I said it was awkward above. I should rephrase. :) I like the lisp approach, it *feels* good, but I haven't yet learned to think in lisp. I need to improve my problem decomposition

17:27 justin_smith: as I mentioned :)

17:27 ordnungswidrig: M-x (cider-eval-sync "1") => no repl connection

17:27 justin_smith: sorry, that sounds smug. I mean yeah, breaking things into smaller parts will bring happiness.

17:27 reiddraper: AeroNotix: i'm afraid clojure contrib repos can't take pull-requests

17:27 technomancy: also increase your sex appeal

17:28 ordnungswidrig: oh, my repl died

17:28 johnjelinek: ordnungswidrig: don't feel bad, my repl just died too (LT)

17:28 goldfeld: have you guys seen vinyasa from zcaudate?

17:29 it's pretty cool for injecting stuff you want right into core for dev purposes

17:31 PinkPrincess: So I'm having some issues with core.async (which I have no prior experience with). I've created a pastebin if anyone can be talked into helping me. :)

17:31 It's here: http://pastebin.com/EmfuMGzP

17:31 Essentially I'm trying to distribute downloading a lot of web pages (~14000) using channels.

17:32 But I'm struggling with everything either being lazy (and returning immediately, never realizing anything) or being very eager (and blocking the main thread).

17:32 bob2: have you read http://martintrojer.github.io/clojure/2013/07/07/coreasync-and-blocking-io/ ?

17:32 PinkPrincess: I'd like to have some progress displayed during the rather long download process.

17:33 Nope. I'll go read that.

17:35 That does seem a lot simpler than what I'm getting into.

17:37 Is there an easy way to control the go block thread pool size?

17:38 bob2: http://stackoverflow.com/questions/18779296/clojure-core-async-any-way-to-control-number-of-threads-in-that-go-thread

17:38 but the point of the above is to avoid just spamming one thread per io-bound thing

17:39 johnjelinek: dnolen_: you around?

17:40 PinkPrincess: Thanks, bob2.

17:42 creese: api question: should you marshal first, or validate first? I'm undecided.

17:43 AeroNotix: creese: validate what?

17:43 creese: AeroNotix: the data coming in

17:43 AeroNotix: creese: what is the data, presumably JSON?

17:44 creese: AeroNotix: example: you have a date field, you want to be sure it's an actual date and not something else

17:44 AeroNotix: assume JSON

17:44 AeroNotix: creese: use closchema

17:44 creese: https://github.com/bigmlcom/closchema

17:44 !next

17:45 amalloy: closchema sounds like some kind of medical condition

17:45 AeroNotix: It's just a JSON schema validator

17:46 write your schema -> validate instances of it

17:46 -> delete idiotic code you were writing yourself

17:46 creese: if it's JSON you seriously should not be rolling your own validators outside of special cased fields

17:46 creese: AeroNotix: too late

17:46 AeroNotix: creese: delete the code->use closchema

17:47 dsrx: 'closchema' reminds me of 'cloact'

17:47 creese: AeroNotix: does it marshal too?

17:48 AeroNotix: creese: why would it? Use ring-json middleware for that

17:49 creese: were you manually decoding the json on each request?

17:49 * technomancy is actually going to be looking at json-schema for an upcoming project

17:49 AeroNotix: technomancy: I'm having great success with that project

17:49 technomancy: had another team use it for a big API and said it was a great fit

17:50 AeroNotix: it really i

17:50 is

17:50 tolitius: is there a way to create lein template that takes options? for example, here is that template I did for one of my presentations: https://github.com/tolitius/cccp but I also would like to do something in the lines of: "lein new cccp -with.cljs.repl [app name]", where it will also create austin based cljs repl hooks (e.g. https://github.com/tolitius/wracer/blob/master/test/wracer/brepl.clj and others)? thank you.

17:50 AeroNotix: I just added a feature where you can override certain keys with your own validators

17:50 sdegutis: technomancy: have you seen that new thing on HN?

17:50 technomancy: AeroNotix: are you using it with erlang?

17:50 sdegutis: hm?

17:50 sdegutis: technomancy: the new Q lang, kinda related to json-schema

17:50 AeroNotix: technomancy: We use Jesse but Jesse doesn't do references, we're working on adding it.

17:50 technomancy: AeroNotix: sweet

17:50 sdegutis: technomancy: https://news.ycombinator.com/item?id=7333354

17:50 technomancy: also http://www.q-lang.io/

17:51 AeroNotix: technomancy: in fact I might tackle jesse references this week

17:53 asthasr: Are there any really good books that go into the practical aspects of designing a system using lisp?

17:53 creese: AeroNotix: the project in Python, I just come here for inspiration

17:53 technomancy: the edn fans on this thread; my goodness

17:53 asthasr: I'm thinking of, by way of comparison, "Domain Driven Design" on the OO side (although I never liked DDD)

17:53 AeroNotix: creese: https://pypi.python.org/pypi/jsonschema

17:53 technomancy: I can't help but get the "stop trying to make 'fetch' happen. it's not gonna happen" feeling

17:54 AeroNotix: creese: always use a validator! There's no reason not to.

17:54 technomancy: which thread?

17:54 technomancy: AeroNotix: the one sdegutis linked to

17:54 AeroNotix: ah

17:54 sdegutis: technomancy: that's cuz EDN is the best format ever

17:55 It was almost HTML but ended up not being HTML.

17:55 creese: AeroNotix: can you execute arbitrary functions?

17:55 bja: I feel like I can write a portable EDN/schema validator for Python/Ruby as well as I could write a Q validator/serializer for python/ruby

17:56 AeroNotix: creese: As validators? In the python one I have no idea

17:57 technomancy: Even if edn is technically superior in ways that actually matter for real life, I'm too jaded to believe anything will replace json's penetration level in the next decade or two.

17:57 AeroNotix: Worse is better

17:58 technomancy: if you ever find yourself complaining about json, just be thankful there was a massive backlash against xml

17:58 because it could be a lot worse

17:58 Wild_Cat: yeah, at least JSON isn't XML :p

17:58 asthasr: sadly, in some contexts, I think XML was better :(

17:59 hiredman: Things: they could be worse.

17:59 Wild_Cat: XML is better for marked-up text documents.

17:59 technomancy: hiredman: always the optimist

17:59 Wild_Cat: which isn't surprising in and of itself. What is is that the enterprise people decided it should be used everywhere and for everything.

17:59 technomancy: "my phone went into an infinite reboot loop when I attempted to upgrade the OS, but at least it didn't catch on fire or boot into windows or anything"

18:00 sdegutis: technomancy: xaml is awesome

18:01 technomancy: sdegutis: is it simple while at the same time being powerful?

18:01 sdegutis: *whilst

18:01 technomancy: oh snap

18:01 sdegutis: but otherwise yes, exactly

18:02 * technomancy nods and scribbles in a note book

18:03 johnjelinek: I'm exploring core.async, and I'm getting some state machine exceptions, here is my defn: (defn query-api [uri] (let [out (chan) req (http/get uri)] (put! out @req) out))

18:03 (it's using http-kit)

18:04 I thought I could test it with this: (go (while true (let [[_ results] (<! (query-api "http://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=cat"))] (println results))))

18:04 but this doesn't seem to be the case -- what's the best way to test this defn?

18:04 sdegutis: But seriously, maybe XML is a pain to parse and process.. but as an end-user I haven't had a lot of problems reading/writing it as long as I have syntax-highlighting.

18:04 (end-user in the programmer sense)

18:04 (wait, that doesn't disambiguate it at all...)

18:05 Gonna so investigate Pallet soon.

18:05 Clojure's version of Chef? Heck yeah!

18:06 amalloy: johnjelinek: put! is blocking (and thus so is query-api). i don't think core.async will be happy at all with you making a call to a blocking function inside of your go

18:07 johnjelinek: amalloy: should I use >! instead?

18:09 (doc put!),

18:09 clojurebot: Cool story bro.

18:09 johnjelinek: lol

18:09 (doc clojure.core.async/put!),

18:09 clojurebot: It's greek to me.

18:09 johnjelinek: hrm

18:09 amalloy: docs say put! is async

18:09 so it shouldn't block right?

18:11 amalloy: oh, right. i guess put! is the...non-blocking primitive on which >! is built? i don't really understand put!

18:12 tolitius: I think put! is used outside of the go block while >! is used only within

18:12 johnjelinek: tolitius: that's correct

18:13 amalloy: incidentally, johnjelinek, query-api could be better (imo) written as: (doto (chan) (put! @(http/get uri)))

18:13 johnjelinek: amalloy: ok, but then how would I pass the channel around?

18:13 amalloy: the let/munge/return pattern is easily replaced with doto, in general

18:13 johnjelinek: i'm saying my definition is exactly equivalent to yours

18:14 johnjelinek: ok

18:14 amalloy: (doto x (f y)) macroexpands to (let [foo x] (f foo y) foo)

18:15 johnjelinek: ok, and so now how would I read from this channel?

18:16 (go (while true (<! (query-api "http...")))) ?

18:16 note: I'm in REPL

18:18 tolitius: @johnjelinek, was not completely following of what you are doing, but usually you _return_ a channel from a functions that produces there, and then using another function (component) you read from it

18:19 johnjelinek: tolitius: right -- so query-api returns the channel, and now I'm trying to build a processor for the channel

18:20 like this? (let [c (query-api (query-api "http://urlquery"))] (go (while true (println (<! c)))))

18:20 tolitius: johnjelinek: then yes, you can do (go (while true …)) if that is what is required, or you you can compose thise q-api with other channels and alt! on them

18:22 johnjelinek: probably more like (fun [c] (go (while true …))), and then pass (query-api ..) to it. all depends on the "whole grand design"

18:22 johnjelinek: tolitius: well, right I'm just trying to understand core.async

18:22 tolitius: johnjelinek: e.g. in case with just (fun [c] ..) you can potentially reuse this processing for other channels as well

18:23 here is an example I did with putting HTTP requests responses into a channel, and then "racing" who is faster using "alt!": https://github.com/tolitius/wracer/blob/master/src/wracer/cljs/wracer.cljs#L15

18:25 johnjelinek: I'm unfamiliar with alt!

18:26 tolitius: johnjelinek: I think you are correct in the way you understand it. in simple terms => [producer]: 1. Create a channel (or take is an argument) 2. Produce there within a go block 3. Return a channel. [consumer] => a function that takes a channel and (go takes) from it.

18:26 justin_smith: I still like how randomly excited people are when they talk about certain side-effecting functions

18:26 danielszmulewicz: dnolen_: ping

18:27 tolitius: johnjelinek: "alt!" is like socket selector (e.g. non blocking IO). in short: takes a vector of channels as its input, and returns the first value that was return form one of these channels

18:29 johnjelinek: tolitius: ahh, that's cool :)

18:29 tolitius: so, what I'm trying to do is execute ~36000 HTTP requests in async and then aggregate the responses together (or retry if it gets 401/403/Connection Error exception)

18:30 should I use multiple channels for this or just 1?

18:30 tolitius: johnjelinek: the usual example is modeling a timeout for something. you create a timeout channel (timeout t), and you have your own channel (let's say "c"), that you only want to wait for some time, and then you give these two channels "c" and "t" to "alt!", and "alt!" will return whatever is "first": e.g. if the "t" comes back first, then your "request" timed out.

18:33 johnjelinek: tolitius: well, in my scenario, I want to aggregate all of the responses, so in the end, I should have a seq of 36000 responses

18:33 tolitius: johnjelinek: 36000, what's the magic behind the number? :) One thing to remember (at least the way Go people look at it) is channels are "inproc", and IO is outside of your process. you can certainly use multiple channels to "partition" these 36000 requests, but I would think that you'd be mostly IO bound and not CPU, hence a single channel might do as well as several

18:34 johnjelinek: tolitius: because I have 36000 queries to make to a WebAPI

18:34 different querystring for the same URL

18:35 amalloy: i think there's an rfc saying if you make more than 10000 simultaneous requests on the same server, the sysadmin is allowed to murder you

18:36 johnjelinek: amalloy: lol

18:37 well, it's hitting a load balancer that then sends it off to a server that can take my request

18:37 so it's a distributed 36000 ;)

18:38 tolitius: johnjelinek: I would first try with a single channel, but of course in case you'd like to experiment, you can have multiple channels doing these requests, in which case, you could use something like fan-in (just an example: https://github.com/clojure/core.async/blob/master/examples/ex-alts.clj#L3) to collect all the responses into a single channel (e.g. simple map/reduce)

18:40 johnjelinek: or you can use a built in merge: https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async.clj#L931

18:41 johnjelinek: noted :)

18:43 danielszmulewicz: Anyone knows how to use ReactCSSTransitionGroup from om?

18:45 seangrove: danielszmulewicz: Could be a bit tough, I don't think there's an extern file for it

18:45 danielszmulewicz: I would like to use CSS transitions when rendering an Om component.

18:46 seangrove: I saw this coming up in a discussion about Reagent. They seem to have a solution: https://groups.google.com/forum/#!topic/clojure/qt4uhpFqAnc

18:47 seangrove: Maybe I should open an issue on Om's github?

18:47 sakekasi: hi guys, I'm currently working on a project that uses ring and liberator to serve from a database. For some reason, the compiler seems to be calling one of my functions and caching the result, causing the values outputted to http to never change until a server restart.

18:47 here is a gist with my code: https://gist.github.com/sakekasi/9337146

18:47 any ideas as to what could cause something like this?

18:47 johnjelinek: tolitius: so I'm kind of getting it to read. This prints: (let [responses (atom nil)] (go (dotimes [_ 10] (let [query (query-api "http://query")] (println (<! query))))) responses)

18:48 but what I want is to send it to my atom and return the atom in the end

18:48 so I tried (reset! responses (conj responses (<! query)))

18:48 but that did not work

18:48 seangrove: danielszmulewicz: I wouldn't mind having access to it, certainly

18:49 I haven't looked at how they work at all, so I don't know the challenges

18:49 danielszmulewicz: seangrove: Some discussion here: https://github.com/swannodette/om/issues/59

18:49 amalloy: johnjelinek: (reset! x (conj x ...)) can never work, because nothing sequential is also resettable. you must mean something like (swap! responses conj ...)

18:50 johnjelinek: amalloy: yes, sorry -- but swap! doesn't work either, returns an empty atom

18:50 tolitius: johnjelinek: why atom, why not just return a channel?

18:51 johnjelinek: you mean return a channel for my consumer?

18:52 I'm trying to aggregate all of the http responses -- so why would it be good to return a channel rather than the aggregate?

18:54 tolitius: johnjelinek: just something I would do :) you would decouple producing vs. consuming, otherwise why bother with channels at all, you can do it in (future ..)

18:54 johnjelinek: lol, I tried just with future previously, but I spun up too many threads

18:54 and ran out of memory

18:54 that's when core.async was recommended to me

18:55 hiredman: ugh

18:55 why any one would recommend core.aync for an io task I don't know

18:55 tolitius: johnjelinek: you can limit your threads: https://github.com/tolitius/lasync

18:55 hiredman: using an executor with a fixed size threadpool

18:56 johnjelinek: tolitius: but yes, I would like it be decouple producing and consuming

18:56 oy, another library :|

18:56 thanks though

18:57 hiredman: johnjelinek: I doubt you need it

18:57 http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool%28int%29

18:58 tolitius: johnjelinek: it's a micro library though.. just plugging in a different queue to the thread pool executor

18:58 hiredman: it is different

18:58 hiredman: tolitius: I understand, I doubt he needs the difference

18:58 tolitius: johnjelinek: but yea, in case you would like to decouple, I would return a channel

18:59 johnjelinek: tolitius: https://www.refheap.com/51352 so you're saying the consumer should also return a channel?

18:59 at what point am I building my aggregate?

18:59 tolitius: hiredman: with "lasync", johnjelinek could create number of tasks, and just through all 36000 requests to them without pool returning "false"..

18:59 seangrove: hiredman: Even for making http calls? Seems like core.async is an alright match for coordinating the order of things

19:01 dnolen_: johnjelinek: what's up?

19:02 hiredman: tolitius: I doubt he ran out of memory from just having all the tasks around, most likely it was due to having all the results in memory, so if you limit the threadpool, he should be fine

19:02 johnjelinek: dnolen_: I was following your CS101 blogpost and was wondering how you would do the equivalent of forever reading from a channel in the repl from pure functions like you showed with CLJS

19:03 dnolen_: johnjelinek: I don't see how it would be any different, go loops won't block the repl

19:03 sakekasi_: hi guys, I'm currently working on a project that uses ring and liberator to serve from a database. For some reason, the compiler seems to be calling one of my functions and caching the result, causing the values outputted to http to never change until a server restart. here is a gist with my code: https://gist.github.com/sakekasi/9337146 . any ideas as to what could cause something like this?

19:04 tolitius: johnjelinek: I would have the producer produce within a go block and return a channel. as to a consumer, I would probably have a consumer that would take a vector of channels and merge their values into another channel (that would have all your 36000 responses). then I would have a function that would take this one channel and "do with these responses" as you wish.

19:04 johnjelinek: dnolen_: I see .. I'll keep playing with it ... what I was trying kept freezing LT

19:04 dsrx: hmmmm

19:04 trying to imagine a use-case for putting core.async channels onto a core.async channel

19:04 danielszmulewicz: dnolen_: https://github.com/swannodette/om/issues/129#

19:05 dsrx: 'higher order channels' if you will

19:05 johnjelinek: tolitius: well, in the example I linked to, it's just 1 channel

19:05 dnolen_: danielszmulewicz: I closed that it's just #59

19:05 danielszmulewicz: dnolen_: I would love to help.

19:05 dnolen_: danielszmulewicz: it's not an Om thing

19:05 hiredman: unless you are very careful, you are going to break things when mixing core.aync and io

19:05 dnolen_: danielszmulewicz: even #59 is not an Om thing

19:05 danielszmulewicz: dnolen_: Fine. But what can I do to use CSS transitions?

19:06 tolitius: johnjelinek: but it does not have to be. my "grand design" :) still holds, a consumer takes a vector, in this case a vector of one

19:06 johnjelinek: hrmm ... ok, I'll keep playing with it then :)

19:06 thanks!

19:06 g2g

19:07 hiredman: you effectively need another threadpool any way for io, because either you are using blocking io and it doesn't belong on core.asyncs pool, or you are doing non-blocking, which everthing except the bottom most layer of comes with a threadpool

19:07 dnolen_: danielszmulewicz: https://github.com/swannodette/react-cljs

19:07 danielszmulewicz: use React Add Ons, add externs

19:09 danielszmulewicz: https://github.com/swannodette/react-cljs/issues/1

19:09 danielszmulewicz: dnolen_: Ah, OK. I haven't worked with externs yet. I will investigate. Thank you.

19:09 dnolen_: danielszmulewicz: pull requests definitely welcome for this

19:10 hiredman: very likely derefing the http response whatever "async" http library you have is, in fact, blocking on io to some degree, so you cannot do that on a core.async "thread"

19:10 dnolen_: danielszmulewicz: the reason I've been dragging my feet with the add ons is that someone has take the time to do the externs

19:10 danielszmulewicz: packaging them up is not sufficient for ClojureScript use

19:10 danielszmulewicz: dnolen_: I understand. I'll gladly do it if I can wrap my head around it.

19:11 seangrove: danielszmulewicz: It's quite some work.

19:11 danielszmulewicz: seangrove: Is this documented somewhere?

19:11 seangrove: https://code.google.com/p/closure-compiler/wiki/FAQ#How_do_I_write_an_externs_file?

19:12 danielszmulewicz: seangrove: Thanks.

19:12 seangrove: danielszmulewicz: Depending on what level of detail you want, it's easier. It can be automated if you drop the type info

19:13 danielszmulewicz: Would this help? https://gist.github.com/Chouser/5796967

19:16 sakekasi: hi guys, I'm currently working on a project that uses ring and liberator to serve from a database. For some reason, the compiler seems to be calling one of my functions and caching the result, causing the values outputted to http to never change until a server restart. here is a gist with my code: https://gist.github.com/sakekasi/9337146 . any ideas as to what could cause something like this?

19:17 danielszmulewicz: seangrove: What does it take to automate this (without the type info)?

19:17 tolitius: danielszmulewicz: http://www.dotkam.com/2013/07/15/clojurescript-use-any-javascript-library/ (if that helps)

19:17 danielszmulewicz: tolitius: thanks.

19:18 estebanrules: Of course this depends on the indvidual, but how easy of a "jump" would it be from Scheme to Clojure?

19:20 sakekasi: estebanrules: scheme and clojure share a lot of general semantics. The jump should be pretty easy given a reasonable knowledge of the underlying java

19:20 estebanrules: clojure likes to give errors that are rather cryptic unless the underlying java is understood.

19:22 estebanrules: the underlying java is going to be my largest barrier I fear. I haven't coded anything in Java in over 10 years.

19:23 bbloom: estebanrules: it's not that big a deal. it only really shows itself in stack traces, but it's usually pretty easy to bisect your way to your bug. if you are used to a repl, you'll encounter you bugs faster, so you'll know it was likely something you just touched

19:23 gfredericks: TimMc: that's a bit surprising

19:23 bbloom: beyond that, you shouldn't have any problem coming from scheme. i recommend reading the stuff on the clojure.org site: rationale, the overview docs, cheatsheet, etc

19:24 estebanrules: Oh

19:25 bbloom: estebanrules: follow some folks on 4clojure.com & do the puzzles. that's the good way to learn the stdlib and idioms in a hurry

19:25 estebanrules: Thanks. Oh yes I intend to read all of the documentation.

19:27 bbloom: Yes I was looking at 4clojure. I was also checking out Clojure for The Brave and True. Concerning books, is there one title in particular you would recommend? There are a bunch of titles out there.

19:27 bbloom: ~books

19:27 clojurebot: books is book

19:27 bbloom: ~book

19:27 clojurebot: book is http://www.pragprog.com/titles/shcloj/programming-clojure

19:27 justin_smith: clojure programming / emerick carper & grand is good

19:29 estebanrules: Thank you.

19:31 sakekasi: any idea as to why clojure would cache the result of a function rather than call it?

19:32 tolitius: sakekasi: memoize ?

19:32 isaacbw: memoization

19:32 dnolen_: sakekasi: doesn't sound likely, gist?

19:32 sakekasi: https://gist.github.com/sakekasi/9337146

19:32 its a ring project that uses liberator

19:32 get-latest-links and get-latest link are called while the server is starting up

19:33 for some reason, these are the returned values, even when I post to the db.

19:33 it takes a server restart to get the functions called again and for the values to change

19:33 dnolen_: sakekasi: sounds like a bug in the libraries your are using - not Clojure per se.

19:33 sakekasi: huh, so liberator?

19:34 dnolen_: sakekasi: not necessarily

19:34 sakekasi: I could see that

19:34 does clojure.java.jdbc cache for some reason?

19:35 justin_smith: should the :exists? things have lambdas rather than forms? with lambdas they would get called later, with the current version they would just return a truthy object or nil at definition time I think

19:35 which would explain the npe

19:35 I think you are missing # or (fn [] ...) wrapping

19:36 *rather than random predicate forms

19:36 sakekasi: that makes sense

19:36 just found this article

19:36 http://stackoverflow.com/questions/3161986/compojure-clojure-contrib-sql-select-query-is-being-cached-why

19:36 that suggests that I didn't do fn[] wrapping in my defroutes

19:37 justin_smith: sakekasi: ok, reader deeper: you need to redefine your non-nil function

19:38 it should expect a function as a second argument

19:38 (and call it)

19:38 and then you should wrap the call to non-nil in a lambda

19:38 sakekasi: The way I defined non-nil, I wanted my function to be evaluated on call.

19:38 justin_smith: either #() or (fn []) whichever you prefer

19:39 the args are evaluated before being passed in...

19:39 OK non-nil may be OK, but the thing calling it should be a function called at run time

19:39 so again about wrapping as a lambda

19:40 seangrove: danielszmulewicz: I'll take a stab at it all later this week/this weekend. Seems like they're open to having an "advanced mode test run" in their build suite.

19:40 danielszmulewicz: seangrove: Awesome. Let me know if I can help.

19:41 * seangrove has flashbacks to contributing to the clojurescript compiler

19:41 seangrove: I image a lot of head-banging and gnashing-of-teeth for awhile

19:41 danielszmulewicz: seangrove: :-)

19:41 dsrx: speaking of which...

19:42 the clojure contributors page suggests sending an email to the mailing list before working on an open ticket, if I'd like to contribute to clojurescript should I direct an email like that to the clojure ML or the clojurescript one?

19:42 dnolen_: dsrx: or ask here or in #clojurescript

19:42 dsrx: ah okay

19:45 sakekasi: justin_smith: can you give me a line#/resource name?

19:46 justin_smith: basically do a search for :exists?

19:46 each one has an expression that is evaluated at compile time

19:47 and should probably be a function evaluated each time existence is checked

19:47 sakekasi: ok

19:48 ahh i get it. these are all being evaluated at compile time

19:48 justin_smith: http://yogthos.net/blog/30-Making+services+with+Liberator notice in this example, exists takes a funciton as argument

19:48 not an arbitrary expression

19:48 yeah - and if it returns nil, then liberator tries to call nil at runtime as a function

19:48 so boom, npe

19:48 which you see in your stacktrace

19:50 seangrove: dnolen_: I think the one issue we have using `:optimizations none` on a ring/clojurescript project is that it creates so many files, ring chokes trying to server them all. I've seen the same thing serving a clojurescript project from `python -M SimpleHTTPSever` Do you not run into that in your dev workflow at all?

19:50 dnolen_: seangrove: I find it strange that Ring or SimpleHTTPServer could not handle serving some files

19:51 seangrove: dnolen_: As do I.

19:51 dnolen_: But perhaps it's PEBKAC, so checking if you run into it at all

19:51 justin_smith: how many files are we talking about here? tens? hundreds? millions?

19:51 seangrove: justin_smith: few hundred all at once

19:52 For python, it just drops the files every now and then. For ring it serves them, but takes an awful amount of time

19:52 dnolen_: seangrove: huh your CLJS project results in hundreds of files? I take it you're not allowing the serve to let the browser serve from cache?

19:53 s/serve/server

19:53 seangrove: dnolen_: The hundreds of files are for cljs files, source maps, js files, and then all of the actual html content like images/markup

19:54 dnolen_: Anyway, not willing to state this as a categorical problem yet, just asking if others are running into ti

19:54 After developing with mies-om for Omchaya and seeing what it's like, I definitely want that where possible

19:55 dnolen_: seangrove: just doesn't sound like a real issue if you configure your server a bit. This is what etags are for no? https://github.com/mikejs/ring-etag-middleware

19:55 isaacbw: is there an out-of-box way to pretty print json?

19:56 dnolen_: isaacbw: data.json supports pretty printing

19:56 noprompt_: isaacbw: there's a plugin for chrome called JsonView which is nice.

19:56 sakekasi: awesome! I ended up getting my project to work. thanks for all the help!

19:56 bja: python -m json.tool file.json

19:56 justin_smith: sakekasi: glad to hear it

19:56 isaacbw: dnolen_: I found pprint, but it doesn't do newlines afaict

19:57 dnolen_: isaacbw: what do you mean doesn't do newlines?

19:57 noprompt_: brew install jsonpp

19:57 there's about dozen ways to do it.

19:57 isaacbw: dnolen_: as in, it doesn't go so far as to split the json up on multiple lines, which is what qualifies as "pretty" imo

19:57 gfredericks: I like jq

19:57 bja: cheshire can do it if you're okay with a library

19:57 dnolen_: isaacbw: pretty sure that it does

19:57 isaacbw: hmm

19:57 gfredericks: isaacbw: did you give it small input that fits comfortably on a line?

19:58 bja: (generate-string {:foo "bar" :baz {:eggplant [1 2 3]}} {:pretty true})

19:58 stkim1: I have a question. Say I have a lib such as hiccup. How do I navigate list of functions like javadoc?

19:58 gfredericks: clojure.repl/dir

19:59 combined with clojure.repl/{doc,find-doc}

19:59 justin_smith: bja: but that's edn, not json

19:59 gfredericks: justin_smith: what?

19:59 he's talking about cheshire

19:59 justin_smith: ahh, never mind, I missed that it was generate-string

19:59 stkim1: gfredericks, thank you!

19:59 isaacbw: gfredericks: oh, there we go!

19:59 cool, thanks

20:00 gfredericks: ,(= 1 (apply str "0." (repeat \9)))

20:00 clojurebot: #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>

20:04 amalloy: gfredericks: that's pretty cute

20:04 maybe it would have returned true eventually, given enough digits

20:05 we'll just never know

20:06 isaacbw: ,(println "Hello")

20:06 clojurebot: Hello\n

20:06 isaacbw: :O

20:09 gfredericks: ,(println "Hello\\n")

20:09 clojurebot: Hello\n\n

20:10 zachmassia: Is doall needed when the seq is being passed to an update-in call? https://gist.github.com/ZachMassia/470a57e5e7a0169667c9

20:11 gfredericks: ,((fn f [x] (->> (repeatedly rand) (take-while #(< % x)) (map f))) 1.0)

20:11 clojurebot: (() (() ((())) () ()) (() () () ()) () () ...)

20:11 gfredericks: zachmassia: without it the new value in the map will be an unrealized lazy seq

20:12 seangrove: :wq

20:12 * seangrove coughs

20:12 amalloy: zachmassia: doall is quite rarely needed

20:12 gfredericks: zachmassia: but that's probably fine here, as amalloy says

20:12 amalloy: a doall would only be needed here if the update functions in your entities perform time-sensitive side effects

20:14 gfredericks: ,((fn f [x] (->> (repeatedly rand) (take-while #(< % x)) (map f))) 0.8)

20:14 clojurebot: ()

20:14 gfredericks: ,((fn f [x] (->> (repeatedly rand) (take-while #(< % x)) (map f))) 0.8)

20:14 clojurebot: (() (((() ())) () () ()))

20:14 zachmassia: Hmm, the update functions only act on the inputs for now. It worked without the doall, but I only have about 5 entities so didn't know if it would be needed with more entities

20:14 amalloy: adding more entities will have no effect

20:15 the only thing to worry about is if you call this update-state function much more often than you read the resulting state, you could theoretically run into some issues

20:15 zachmassia: Actually now that I think of it, I iterate over them to draw them, so the doall is probably redundant then, right?

20:15 amalloy: right

20:15 Cr8: possibly. The doall can ensure that you don't *do compute in your draw routine* though.

20:15 amalloy: that's a good point, actually

20:15 Cr8: though in that sort of situation perhaps you should swap (doall (map ...)) for (mapv ...)

20:16 zachmassia: Good call, Cr8. I'll have a look into mapv

20:16 amalloy: if you want to make sure you only start drawing once you know exactly what you will draw, eg because it's bad to tie up the drawing thread, you might want to use doall or something like it to force the computation

20:17 zachmassia: I'm using https://github.com/rm-hull/big-bang to coordinate update and draw calls. afaik it only calls draw when there is a change in the world state

20:17 Cr8: mapv is map, but returns a vector and isn't lazy. Handy if you want the output to already-be-computed and especially so if you're going to be doing random access to it (or if you want to throw reducers at it later)

20:18 if you're throwing reducers at it in the same place though use reducers/map

20:19 zachmassia: Cr8: No reduce or anything right now. mapv sounds exactly like what I need

20:19 Thanks for the help guys :)

20:30 goldfeld: oohh i like that big-bang library link

20:31 xeqi: seangrove: do you have a good way to do server side rendering?

20:31 seangrove: xeqi: For React code?

20:31 xeqi: yep

20:32 seangrove: Nope. Thinking about it. Thought it would be fun to have a library fire up node and communicate with it to get the output over a socket

20:32 xeqi: The React guys keep telling me not to re-implement the React rendering code in Clojure, sadly.

20:33 xeqi: seangrove: heh, I'd skip rewriting the rendering too

20:33 I've seen https://github.com/brendanyounger/omkara/blob/master/src/omkara/react.clj#L29, which basically uses rhinko

20:33 *rhino

20:34 could embed something similar for dyn.js if wanted

20:34 zachmassia: goldfeld: I'm using it for my first cljs (and functional) program with his fork of monet as well. Might not be the best code but it works so far https://gist.github.com/ZachMassia/9dceffdd42b569845c48

20:35 xeqi: but leaves that leaves open how to handle ajax calls for initial data vs rendering them already from server side

20:35 seangrove: xeqi: I think that'd be fine for static pages that can be rendered once at startup, but dnolen_ mentioned that nodyn is something like 300x slower than node, so I might be nervous to use it dynamically

20:35 xeqi: and how to load the initial app state w/ that data if server side rendered

20:36 seangrove: xeqi: Yeah. It's messy enough that I wouldn't really recommend any one-way for newcomers yet, certainly.

20:36 xeqi: oh well, I'll be interested to see if you come up with something

20:38 seangrove: xeqi: Since we develop everything without a server first anyway, then setup Schema, then introduce the server, giving the frontend code enough data to render is trivial. It always bootstraps itself with some calls to the server post-load

20:38 And the initial state is enough for good SEO

20:38 But it's a pretty specific approach, still thinking about a more general solution

20:48 goldfeld: zachmassia: cool! i was considering using the monet fork too, will check out your code, thanks

21:00 dnolen_: seangrove: Om 0.5.1 out

21:00 seangrove: dnolen_: Awesome. I meant to send a PR with IDsplayName implemented for Om inputs

21:01 dnolen_: I can send that in a few minutes if you haven't done it already

21:01 dnolen_: seangrove: just open a issue for that, I can do it easily enough.

21:02 seangrove: will have to wait for next release

21:04 mlb-: I'm having trouble unarchiving a password protected zip file from clojure. Does anyone have experience with this?

21:11 benmoss: mlb-: are you using a library?

21:13 mlb-: benmoss: I've not found a library that supports extracting from password protected zipfiles. Don't want to have to resort to shelling out if I don't have to

21:13 benmoss: ZipInputStream doesn't support password protected files

21:13 http://www.lingala.net/zip4j/ is probably your best bet, i dunno if anyone has written a wrapper

21:14 mlb-: Doh. I should've remembered to check maven and friends

21:14 thanks, benmoss

21:14 benmoss: sure

21:14 here's some example code using it i just found https://github.com/oakes/Nightweb/blob/master/common/clojure/nightweb/zip.clj

21:29 dsrx: zip is such an overloaded term

21:30 for example, I remember being surprised to hear that PHP's stdlib included 'zip' functions, only to learn they had to do with zip files

21:32 mlb-: or Haskell's zip?

21:33 dsrx: well, that's what I was expecting

21:33 mlb-: ah, I was thinking of zippers

21:33 dsrx: yeah, and then there's that :P

21:41 muhoo: it's fun reading all the backscroll between sean and david. reminds me of a few years ago in here where there were guys like chris, chas, zach, phil, and others, continually evolving all kinds of cool stuff

21:42 chouser_log: who's chris? ;-)

21:42 muhoo: and chouser_log too :-)

21:43 grainger, and anthony, there was so much going on

21:43 * muhoo is deliberately avoiding using nicks so as not to annoy them with pings

21:43 logic_prog: is there a way to tell lein "lein, update yourself"

21:44 muhoo: logic_prog: lein updgrade

21:44 upgrade

21:44 logic_prog: $ lein upgrade Upgrades should be done using apt rather than Leiningen itself.

21:44 muhoo: wat?

21:45 chare: what is the difference between lein trampoline and lein run

21:45 qbg: logic_prog: You installed lein using apt?

21:46 logic_prog: yeah

21:46 muhoo: didn't know you could do that.

21:46 logic_prog: is that a bad thing?

21:46 as in "sudo apt-get install leiningen"

21:46 ubuntu 13.10

21:46 right1: try apt-get install --only-upgrade <packagename>

21:46 qbg: Is that version out of date for you?

21:47 logic_prog: I just manually installed lein

21:47 everything works now :-)

21:47 muhoo: you might want to uninstall the apt package if you're installing it manually

21:47 right1: what do you guys like for websockets in clojure? http-kit or adelph?

21:47 logic_prog: http-kit

21:48 the author of http-kit is awesome

21:48 i've filed bug reports on github issues, and he's responsded

21:48 muhoo: haven't tried http-kit, but done websockets stuff with aleph and it worked.

21:48 n0n3such: i've been looking for someone who's used http-kit :)

21:48 logic_prog: I use http-kit.

21:48 It's awesome.

21:48 n0n3such: logic_prog: experiences ?

21:49 logic_prog: Damn it, I'm not sure what else I can do; it sounds like I'm selling http-kit stock.

21:49 n0n3such: i tried hooking it up with compojure following the http-kit example and it didn't compile

21:49 but i'm a clojure noob

21:49 logic_prog: buy http-kit !

21:50 sell bitcoin, buy http-kit

21:50 muhoo: logic_prog: everyone has their programmign fanboi thing

21:50 ddellacosta: woah, I've never heard that about upgrading lein, in fact only the opposite.

21:50 muhoo: i annoy people by telling them how awesome clojure, om, and datomic are

21:50 n0n3such: some kind of namespace problem

21:50 benmoss: anyone familiar with vim-fireplace, is there much that can be done for a file like this? https://github.com/Datomic/simulant/blob/master/examples/repl/hello_world.clj

21:50 logic_prog: muhaoo: I like clojure, om, and datomic

21:50 muhaoo: admittedtly, http-kit is not as awesome as clojure/datomic, but possibly comparable to om

21:52 mlb-: benmoss: I use fireplace quite a bit. What do you mean "done"?

21:52 muhoo: i expect that once i get further into core.async i'll be just as fanboi about that. so far i'm impressed.

21:52 benmoss: mlb-: i can't evaluate any forms in that file

21:52 mlb-: when i 'cpp' the first line: https://gist.github.com/benmoss/9339442

21:53 mlb-: I've not worked with dataomic and friends, but as long as fireplace has an nREPL connection, things "just work" for me

21:53 benmoss: hmm

21:54 mlb-: huh. that stacktrace is something I've not seen before

21:54 benmoss: i have found i have problems whenever there's a file like this that has no ns and is just meant to be evaled

21:54 seems like just some vimscript error

21:55 even just 'cqp'-ing (+ 1 1) yields the same stacktrace

21:55 something about it trying to create a new ns

21:56 technomancy: logic_prog: lein from apt-get is hopelessly out of date ATM; I'd recommend removing and installing by hand

21:56 logic_prog: technomancy: already did that

21:57 technomancy: if only the maintainer of len would add a mode, where a system wide lein would (1) check to see if slef is out of date and (2) if so, install a up to date lein in ~/.local-lein, and (3) call ~/.local-lein

21:57 :-)

21:58 technomancy: logic_prog: if you want something that's up-to-date, you shouldn't be using apt-get to begin with

21:59 the whole point of apt-get is that it will always work the same as it did when it was first packaged and never break

22:00 tolitius: technomancy: is that something "lein possible": https://www.refheap.com/51402 ?

22:00 chare: do you guys use pulsar lightweight threads with clojure?

22:01 technomancy: tolitius: yeah, lein templates can take arguments

22:01 tolitius: right now the composability story around templates isn't great, but simple flags and such are easy

22:02 benmoss: mlb-: can you try this repo out? https://github.com/benmoss/fireplace-bug

22:02 just eval the form in the file in examples

22:02 tolitius: technomancy: great! I could not find the how to on template arguments, is there a place I can dive in for more info?

22:04 technomancy: tolitius: it should be fairly clear if you do `lein new template mytemplate`

22:04 it spits out a template with a defn in it; just add more args to the defn

22:05 tolitius: benmoss: fyi: it works for my fireplace setup, e.g. gets evaluated to 2

22:05 benmoss: hmm

22:06 tolitius: examples/wtf/bug.clj ?

22:06 lemme try updating and see if that fixes anything

22:07 tolitius: technomancy: you mean the "entry point fn": e.g. https://github.com/tolitius/cccp/blob/master/src/leiningen/new/cccp.clj#L6 ? it makes sense. it's just clojure.. I get it :)

22:08 technomancy: it's clojure's motto

22:08 "It's just a function"

22:08 tolitius: benmoss: no, "examples/wtf/bug.clj " will not work

22:08 since your source-paths are not looking there

22:09 benmoss: source-paths includes examples, shouldn't it?

22:09 maybe i don't understand source-paths, i admit

22:09 tolitius: benmoss: why would you keep sources in "src" and in another dir that's not in "src"?

22:10 benmoss: it's a common example i've seen to have some "example" code in another directory

22:10 ala https://github.com/Datomic/simulant/blob/master/examples/repl/hello_world.clj

22:10 tolitius: benmoss: oh.. and you have no namespace there

22:11 benmoss: yeah, it's meant to be just evaluable code, not a ns

22:11 tolitius: benmoss: that's your problem. add "(ns wtf.bug)" to the beginning of your "examples/wtf/bug.clj", and it will work

22:11 noprompt_: gawd. emacs indentation for ruby is awful...

22:12 tolitius: benmoss: I prefer to have "example" code under "test" if you must, but yes, I've seen this pattern around

22:13 technomancy: yep, makes a lot of sense, it was my first clojure template, and as it goes with "firsts", the fear of uncertainty blinds the fact just how simple it is..

22:13 technomancy: s/clojure template/lein template

22:14 benmoss: noprompt_: isn't ruby-mode.el maintained by Matz?

22:14 muhoo: can you nest {:keys []} inside {:keys ? i.e. {:keys {:keys [foo] :as params}} in a ring req?

22:14 noprompt_: benmoss: i dunno, but it's fucking horrible.

22:15 benmoss: i'm trying to return a hashmap in a case in a when clause and the map indentation is all hosed.

22:15 muhoo: i've been doing {{:keys [foo]} :params} but if i want other things i have to stutter them, i.e. {{:keys [foo]} :params bar :bar}

22:15 tolitius: benmoss: in order for it to be "evaluable code" it needs a namespace

22:15 noprompt_: i'll get in a bar fight over it: syntax is a *bad* idea.

22:15 benmoss: tolitius: i thought fireplace tried to create a user ns if one was not declared or something like that

22:16 technomancy: benmoss: I don't think ruby-mode is maintained at all

22:17 benmoss: ok, *created* by? not as though that guarantees any kind of quality, just would have assumed

22:17 * noprompt_ is gonna throw himself into a mountain.

22:19 * muhoo sings http://www.youtube.com/watch?v=1kAIMlISHhU

22:19 tolitius: benmoss: https://github.com/tpope/vim-fireplace/blob/master/doc/fireplace.txt#L118 yes, then you should remove "examples" from under "source-paths"

22:19 benmoss: and it will work

22:20 benmoss: ah lemme try that

22:20 tolitius: benmoss: otherwise you _are_ putting it on the classpath, but don't specify the namespace, which is why it does not like it

22:21 benmoss: indeed, it does work

22:24 thanks tolitius

22:25 Nyyx: so no libraries in clojure for bimaps?

22:26 tolitius: benmoss: sure, glad it helped

22:26 sea-gull: Nyyx: there's a bimap in guava

22:26 which is available from clojure too

22:27 tolitius: Nyyx: will http://clojuredocs.org/clojure_core/clojure.set/map-invert work?

22:27 Nyyx: I guess, but I'll have two maps

22:28 and I was hoping to serialize them so idk about guava

22:29 tolitius: Nyyx: but it is two indices one way or another

22:29 Nyyx: *these are

22:31 Nyyx: e.g. in guava these are also two maps: https://code.google.com/r/baggiogamp-guava/source/browse/guava/src/com/google/common/collect/HashBiMap.java#76

22:32 Nyyx: so I don't see why a simple map-invert won't work

22:41 Nyyx: tolitius: okay I was wrong

22:41 I'll use map-invert

22:59 if I have a function which uses map-invert in its body on the same map over and over will it always calculate the invert?

23:00 bbloom: Nyyx: clojure doesn't do any common subexpression elimination optimizations beyond what the java vm will do at jit time (read; very simple ones)

23:01 Nyyx: so yes

23:02 MattAbbott: what optimizations does clojure do before hitting the jvm?

23:02 bbloom: MattAbbott: practically none at the source transformation level

23:03 MattAbbott: I see. Are optimizations just kinda low on the priority list right now?

23:03 bbloom: MattAbbott: they're simply not necessary in most cases

23:03 Nyyx: bbloom: what about if I use a let binding?

23:03 and put the map-invert in there

23:03 bbloom: Nyyx: every time the let runs, the right side of the bindings will be re-evaluated

23:03 Nyyx: so I have to put it in a def?

23:04 bbloom: Nyyx: if you've only got one map & one map invert, then yeah, put it in a def.

23:04 Nyyx: depending on your use case, you could manually memoize in some way

23:05 Nyyx: the map stores user settings that could change

23:05 so eventually I was thinking of putting it into an atom?

23:05 bbloom: Nyyx: may vary at startup? or can change at runtime?

23:05 Nyyx: runtime

23:06 bbloom: if you haven't measured and determined that it's too slow, i'd say ignore it

23:06 Nyyx: so I guess I would stick both maps in a vector of the atom or two atoms for each one but then I'd need a watcher to change an atom when one changes right?

23:07 bbloom: Nyyx: you can do either a watcher or simply store the input AND the output, then check if the inputs differ, if so, recompute the output

23:08 your choice if you want/need eager or lazy recomputation

23:09 Nyyx: i'd just skip the watcher completely and not bother with the lazy recomputation. instead, just make a function to set the new settings and update two mutable values there

23:09 Nyyx: bbloom: okay thanks

23:09 cleared up my confusion

23:17 wei__: is there a blocking sleep in javascript? would be nice for using inside a go block

23:18 tolitius: wei__: take from a timeout channel?

23:18 will block until the timeout is done

23:19 wei__: oh yeah, that'll work

23:22 didn't realize there's actually a timeout channel in the api- that's cool

23:25 bbloom: wei__: if you don't already know, be sure to check out various golang resources for how to utilize multiplexing and timeout channels

23:26 wei__: will do thanks bbloom

23:27 munderwo: Hi all. has anybody played around with HTTP-kit?

23:28 I was wondering. A lot of their examples use the form (with-channel req channel …) but I'm not sure where the channel value comes from?

23:39 devn: Does anyone use earmuffs still on their dynamic vars?

23:39 dsrx: munderwo: it's a macro that makes handlers where the symbol channel (in that case) is bound to a channel opened up with a client/server

23:39 devn: Or is that old school at this point?

23:40 dsrx: munderwo: the docstring for with-channel might be helpful

23:48 munderwo: dsrx: so it grabs the web socket channel from the request headers? or from the middleware or something?

23:48 minikomi: I'm wanting to use a github branch which isn't yet available on clojars .. is git cloning the project & then symlinking it in checkouts the way to go?

23:55 dsrx: munderwo: yeah, the actual socket is grabbed from the request in the expanded macro

23:55 munderwo: dsrx: ahh ok. that makes sense. it looked like it was just appearing from no-where which was confusing. but makes sense now

Logging service provided by n01se.net