#clojure logs

2014-03-03

00:01devnheh
00:05firefauxhow could I apply a function to every value in a map, and return the key that corresponds to the greatest value?
00:05firefauxI was thinking first I'd need to apply the function
00:05bob2the answers sounds pretty similar to your question
00:05firefauxthen use map-invert
00:06firefauxand take value of the first item
00:07hiredman,(key (apply max-key (comp inc val) (seq {:a 1 :b 2})))
00:07clojurebot:b
00:07gfredericks,(key (apply max-key (comp inc val) {:a 1 :b 2}))
00:07clojurebot:b
00:08firefauxnice
00:20muhoowhat's the equivalent of "this" in om? how would i get the actual underlying dom node of a component?
00:21muhoooh, doh, get-node :-/
00:21muhoothough, get-node doesn't get THIS node, i have to give it a hardcoded id
00:23firefauxif you have the component, can you get the id from that?
00:23pyrtsahiredman, firefaux: Watch out for empty inputs, though. max-key doesn't allow zero arguments. :(
00:24pyrtsa,(apply max-key [])
00:24clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/max-key>
00:24firefauxgood catch, pyrtsa
00:24gfredericks,(max)
00:24clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/max>
00:25gfredericks,(<)
00:25clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/<>
00:25gfredericks,(-)
00:25clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/->
00:26brandonI'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?
00:33muhoobrandon: read the oreilly clojure programming book, it has good background on web stuff
00:34devnhttp://clojure-doc.org/, http://www.clojure-toolbox.com/, http://getclojure.org/, http://joyofclojure.com/, http://planet.clojure.in/, http://www.clojuresphere.com/
00:34brandonThanks!
00:35brandonI always feel a little awkward coming into these rooms to ask a single question. What's the 'normal' thing that people do in here?
00:35devnhttps://www.4clojure.com/ another one
00:45firefauxalight, thanks for the help everyone, I'm off to sleep
01:04devnaurorcoin connects you to an irc network
01:04devntheir qt app does
01:06seangrovebbloom 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.
01:06seangrovebbloom: It's small enough that you should be able to apply some of your wizardry simply enough :)
01:12voldymanwhats the recommended way of creating a simple socket server in clojure?
01:20technomancyvoldyman: just use java serversockets
01:20technomancycheck out the mire project for an example
01:21voldymantechnomancy: ok, i was looking at your fork of server-socket, whats it current state?
01:22technomancyit exists and works and is unlikely ever to see another commit
01:22voldyman:)
01:36seangrovebbloom: 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...
01:39effydoes 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"
01:58muhoois 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
02:03johann_muhoo: isn't that the default behavior if you dont specify a ref? could be mistaken
02:04muhoooh, that'd be awesome, but the docs say it requires a ref as an arg
02:04johann_(om/get-node owner)
02:05muhoohttps://github.com/swannodette/om/wiki/Documentation
02:06johann_https://github.com/swannodette/om/blob/master/src/om/core.cljs#L697
02:29chareguys have you heard of quasar pulsar?
02:29charehttp://blog.paralleluniverse.co/2013/05/02/quasar-pulsar/
02:30chareI got a question about it.
02:31chareanyone alive?
02:32nopromptdeadghost: thanks for the bug reports. :)
02:32nopromptdeadghost: sorry for tripping you up. :(
02:32deadghostnoprompt, that's for fixing them
02:32deadghost*thanks
02:33nopromptdeadghost: that should do it. lemme know.
02:34nopromptdeadghost: 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. :)
02:34seangroveHrm, 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
02:34deadghostwill do
02:34nopromptdeadghost: 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.
02:35nopromptbeen hacking a sass->garden script which monkey patches Sass::Script::* and Sass::Tree::* to emit EDN
02:35deadghostnoprompt, are there any compass clones on garden?
02:36deadghostI saw one but it doesn't seem to have much activity
02:36nopromptdeadghost: danneu started one, not sure where he's at w/ it though. :/
02:36deadghosthopefully because it was written perfectly the first time
02:36nopromptkind of a big undertaking though.
02:36deadghostyes that's the one
02:36muhooon 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?
02:37nopromptdeadghost: basically what i'm trying to do is emit mostly working garden code from a sass codebase.
02:37muhooand not of the window either
02:37nopromptdeadghost: that takes care a bulk of the hand-porting.
02:37deadghostseems more ideal than hand porting
02:38nopromptdeadghost: there's some difficulty around emitting calls to mixins and functions but it's not too bad.
02:39deadghostone of the things I wanted to do before I even touched clojure
02:39deadghostwas write something lispy that compiled to sass
02:39deadghostbut skipping a step is good too
02:40nopromptstuff like interpolation isn't bad "foo #{$bar} baz" => (str "foo " $bar " baz")
02:40noprompt@mixin foo (1, 2, 3) => (foo 1 2 3)
02:40noprompt$foo: weeble => (def $foo "weeble")
02:41noprompt1px + 2px => (+ (px 1) (px 2))
02:41nopromptit's just effing tedious.
02:56charewhat exactly is the purpose of lein trampoline, whats the purpsoe of NOT using it
03:04muhoois there a way for set-state! to set the state of itself, not its owner?
03:04muhooi.e. setting the state of the compoent not the owner of the component
03:05muhooand is set-state! valid within a did-mount, or must it only be used within a render or render-state?
03:12muhoooh, that's it. Uncaught Error: No protocol method ICursor.-path defined for type boolean: false
03:12muhooowner is a boolean false
03:12muhoobecause that's my data, and om hates it.
03:22Nyyxhow do I 'or' a list of bools
03:22Nyyxwithout reduce
03:22paulswilliamsesqHi all, here goes.... Is stubbing functions considered okay in clojure, and if so, is with-redef an idiomatic way to do it?
03:23Nyyxsomething like splicing
03:23Nyyxoh wait nvm apply
03:24Nyyxnvm again "CompilerException java.lang.RuntimeException: Can't take value of a macro:"
03:24NyyxI can't (apply or ...)
03:26Nyyx,(apply #(or %&) '(false true false))
03:26clojurebot(false true false)
03:26Nyyxno...
03:27Nyyx,(apply #(or % %2 %3) '(false true false))
03:27clojurebottrue
03:27Nyyx:( thats what I want but not vararg
03:28Kneiva_,(every? true? (list true false true))
03:28clojurebotfalse
03:28Kneiva_,(every? some? (list true false true))
03:28clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: some? in this context, compiling:(NO_SOURCE_PATH:0:0)>
03:28Kneiva_,(some? true? (list true false true))
03:28clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: some? in this context, compiling:(NO_SOURCE_PATH:0:0)>
03:28Kneiva_,(some true? (list true false true))
03:28clojurebottrue
03:28rhg135,(eval (apply #'or [true nil true nil]))
03:28clojurebottrue
03:29rhg135,(eval (apply #'or [true nil false nil]))
03:29clojurebotnil
03:30clgvNyyx: why not reduce?
03:30NyyxKneiva_: thanks
03:30rhg135If you do that in real code I will find you :-P
03:30Nyyxclgv: because I was looking for a function like every? and some? that do that already
03:31clgv"or" is a macro and certainly shouldnt be used like the above example
03:31rhg135clgv: of course not
03:32clgvNyyx: ##(some identity [false false true false])
03:32lazybot⇒ true
03:32clgveven with short circuiting ^^
03:33Nyyx,(println "test")
03:33clojurebottest\n
03:34Nyyx,(some identity [true (do (println "hi") false)])
03:34clojurebothi\ntrue
03:34Nyyxno short circuit though
03:35charewhat do you guys think about pulsar for clojure?
03:36clgvNyyx: it short circuits. your println is evaluated outside of some befor that vector is passed to some ;)
03:37clgv$source some
03:37lazybotsome is http://is.gd/IAmtiP
03:38Nyyxdoesnt do that in the or macro
03:38Nyyx,(or true (do (print "hi:")))
03:38clojurebottrue
03:44michaelr525howdy
03:47Kneivahello
04:12chareI've decided to use clojure with pulsar
04:12chareand you guys can't stop me
04:20rurumateHello everyone!
04:20rurumateWhich profiles are active by default, when doing a "lein install"?
04:21rurumateI've noticed that the dev profile is NOT active then
04:29noidirurumate, leiningen's docs state that "By default the :dev, :provided, :user, :system, and :base profiles are activated for each task"
04:29noidihttps://github.com/technomancy/leiningen/blob/stable/doc/PROFILES.md
05:10lvhHi
05:11lvhIf 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
05:11TEttingeryes
05:11lvhTEttinger: There's a nice clojure way of doing it, or yes use the java interop
05:11TEttingerthere's at least one set of seeded random number things in pure clojure
05:11TEttingerI have it somewhere...
05:12TEttingerhttps://github.com/kephale/clj-random
05:13lvhTEttinger: Thanks!
05:14lvhoh my me, a :cellularautomaton generator!
08:28mishok13hey, i have a small question about passing JDBC PreparedStatement parameters in HoneySQL + clojure.java.jdbc combination
08:28mishok13https://gist.github.com/mishok13/9324779 <-- here you can see the current smallest example
08:28mishok13in a nutshell: i want to change default fetchSize for one query
08:29mishok13reading clojure.java.jdbc code didn't bring any enlightment
08:32CookedGryphonHey, does anybody have any clues about testing core.async with midje when your go loop throws an exception?
08:32CookedGryphonat the moment it's just crashing a backgrounded thing and then passing because the desired outcome is no output
08:33CookedGryphonbut I want to output with no exceptions!
08:51BartAdvI 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
08:51BartAdvbut I don't know how to easily grab that project map
08:52BartAdvanyone 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)
08:58clgvNyyx: ,[true (do (println "hi") false)]
08:59clgv,[true (do (println "hi") false)]
08:59clojurebothi\n[true false]
08:59clgvBartAdv: https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md
09:00clgvclojurebot: leiningen plugin |is| https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md
09:00clojurebotRoger.
09:00clgvleiningen plugin?
09:00clgv~leiningen plugin
09:00clojurebotleiningen plugin is https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md
09:00clgvclojurebot: botsnack
09:00clojurebotthanks; that was delicious. (nom nom nom)
09:01BartAdvoh haha
09:04BartAdvbut 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
09:04clgv,(apropos "forv")
09:04clojurebot()
09:05clgvdamn. guess I have to write that thing some time...
09:06clgv$findfn [a [1 2 3], b [4 5 6] :when (even? (+ a b))] [a b] [[1 5] [2 4] [2 6] [3 5]]
09:06lazybotjava.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0)
09:13CookedGryphondoes anyone have any ideas how I fail a midje test on exception in a background thread
09:14CookedGryphongiven 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
09:24clgvCookedGryphon: cant you test the function alone that is used in the background thread?
09:34joegallois the exception uncaught in the background thread?
09:34joegalloif 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
09:35joegallojust be sure to get the current value first and put it back when you're done ;)
09:37CookedGryphonclgv: 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
09:38clgvCookedGryphon: ah right. go-loops can only consume and write stuff within the fo-block, right?
09:38clgv*go
09:38CookedGryphonyeah, I don't have a choice but to run it in the background
09:39CookedGryphonjoegallo: could do... doesn't feel like something I should be doing in a unit test though!
09:39joegalloshrug
09:39joegallo:)
09:39CookedGryphonwait, that's not the issue
09:39CookedGryphonI've looked at this before
09:40CookedGryphonI think the issue is that core.async makes its own executor, I have no way to access the threads its actually using
10:34n0n3suchAUR seems to be taking on a life of its own
10:34n0n3suchhttps://www.cryptocoincharts.info/v2/coins/show/aur
10:40mikerodIt 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:40mikerodHowever, I only get this error during AOT-compilation
10:40mikerodhow is that possible?
10:41mikerodI thought in AOT and not compilation, the same byte code would still be getting generated and verfied?
10:41mikerodverified*
10:42stuartsierraAOT is weird in many ways.
10:43mikerodstuartsierra: I wouldn't argue with that statement :P
10:43mikerodThis error that is only happening in AOT concerns me though, since I think it is pointing out a potential issue I have.
10:43mikerodI have a macro that is generating very large constants.
10:44mikerodSomehow, without AOT this is not revealed to me. However, it still seems like that may be a cause for concern?
10:44stuartsierraIt's not a great idea if you can avoid it.
10:44stuartsierraAlternatives: Generate them once and save in an EDN file, generate at runtime, etc.
10:45mikerodstuartsierra: Yes, that's the general guidelines I've heard. I think that will be the approach I try to take.
10:46mikerodI appreciate the feedback too.
10:46stuartsierraYou're welcome.
10:51sdegutisWhat OpenID libraries are you all using?
10:52jarjar_prime@sdegutis: I just use facebook connect
10:52jarjar_primehaven't had much success product wise when it came to openid
10:53sdegutisOh.
10:53jarjar_primeand on iOS you can just hand a token back without having to do anything special on the server
10:54jarjar_primeprobably going to add google+ at some point once we get android up and running
10:56sdegutisOk.
11:29wei__anyone use kioo successfully with om? the example code uses an outdated version of om
11:44goldfeldi have that kioo-riosity too, plan to use it soon
11:51johnjelinekhihi all :)
11:51johnjelinekhow's it goin'?
11:51johnjelinekdakrone: you around?
11:52wei__hi johnjelinek, fine thanks
11:52johnjelinekwei__: great :)
11:52rasmustoits a beautiful morning
11:52johnjelinekI'm wondering -- how should I handle "Connection Reset" exceptions with clj-http? I have {:throw_exceptions false} but this one still gets through
11:52wei__looking for some example code using kioo + Om 0.5.0, if anyone happens to know
11:53wei__you could try/catch it, at worst
11:54johnjelinekwei__: 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:54johnjelinekbasically the future calls 26 HTTP requests
11:54seangrovednolen_: I was a little disappointed that the binary in "All the code that's fit to printf()" doesn't seem meaningful :(
11:55dnolen_seangrove: heh
11:55seangrovednolen_: Still, nice touch
11:56abakerAlex Miller around?
11:59johnjelinek(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:00johnjelinekhmm .. maybe all of my requests threw this exception
12:05dnolen_seangrove: btw I played around a bit with nodyn, seems really slow - like 300X slower than V8.
12:06seangrovednolen_: Probably a better idea (if it's important) to run a separate node process, communicate over some connection
12:06bbloomseangrove: just saw your msges about perf... bummer... how many items are you in your views currently?
12:07seangrovebbloom: 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:08bbloomseangrove: hm yeah, can you test it w/ just a fixed height w/o measuring?
12:08seangrovebbloom: Yeah, suppose that would just take a minute or two
12:14dnolen_seangrove: btw the profile is pretty informative, appears currently all the time is lost in CLJS
12:14seangrovednolen_: Yeah, recalc-heights mostly
12:15dnolen_seangrove: mostly mean all
12:15dnolen_meaning all
12:15seangroveA lot of thrashing there. Need to be more clever about it
12:15dnolen_no time is actually spent rendering
12:16seangrovednolen_: 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:16dnolen_seangrove: how big is the generated list of things?
12:16seangrovednolen_: 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:17dnolen_seangrove: it should be easy to hack in a special version of om.core/set-state! that doesn't invalidate the path btw
12:17dnolen_seangrove: no need to wait for me :)
12:17dnolen_at least for perf testing
12:17seangrovednolen_: I did, I ended up using atoms, it helped a bit
12:17seangrovednolen_: Then that mutated to channels which did the calculations and used set-state! to signal a rerender necessary
12:18seangroveThat 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:21dnolen_seangrove: there's definitely some weird logic going on
12:22dnolen_seangrove: it scrolls smoothly then completely locks up
12:22seangrovednolen_: Yeah, I'd emphasize experimental. That lockup is because it triggers a round of rendering
12:22dnolen_for a couple of scrolls
12:22dnolen_623000+ calls to ChunkedSeq
12:22dnolen_that just doesn't make any sense
12:22seangroveHah
12:23bbloomlol whoa
12:23dnolen_I suspect something minor here
12:23dnolen_which will speed things up considerably
12:25johnjelinekcan I make a future of futures
12:25johnjelinek?
12:25johnjelinekI'd like to do (future-done? my-future) which would deref a collection of futures
12:26seangrovebbloom: Even being stupid with the fixed-height virtual stack panel, it's 60fps easy
12:26bbloomseangrove: so you're saying the slow part is your measuring code path?
12:26seangrovebbloom: Yeah, all the data that's being mangled keeping track of heights and offsets
12:27johnjelinek(future (my-running-futures)) immediately returns true
12:27johnjelinekany idea why?
12:27johnjelinekprolly because something is lazy?
12:29abakerare 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:30abakerinterested 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:30johnjelinekI am trying (doall @my-futures-collection)
12:30johnjelinekand returning a future
12:32seangrovebbloom 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:33pyrtsajohnjelinek: How about... (future (doall (map deref my-futures))) ?
12:34pyrtsaIt 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:35johnjelinekpyrtsa: I'll give that a shot
12:41johnjelinekpyrtsa: lol, wrapping my (future (doalls in (future (doalls reminds me of callback hell
12:41johnjelinekmaybe I'm not thinking about this the right way?
12:41pyrtsaIt's worse than callback hell. It's a spawn-thread-and-wait hell.
12:42johnjelineklol -- maybe I should just be using core.async?
12:43pyrtsaThe problem is: java.util.concurrent.Future (which clojure.core/future models) doesn't provide a callback mechanism.
12:43pyrtsaYeah, core.async. Or RxJava if you're into that thing.
12:43johnjelinekI see
12:43johnjelineklol, I've been trying to avoid core.async -- but now it feels like I may have no choice
12:45pyrtsajohnjelinek: 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:46johnjelinekI think I'll go core.async
12:47pyrtsaThat's a good choice.
13:16danneudeadghost: 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:16dbaschI'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:43sdegutisIs there a built-in tagged literal to create strings from symbols?
13:43sdegutisWhere #w[foo bar baz] would return ["foo" "bar" "baz"]
13:44hyPiRionIt's called (mapv str '[foo bar baz]), I guess.
13:44hyPiRionbut no, not built in.
13:44sdegutisAh. I think it would be more terse as #w, so it may be worth writing a third party lib for it.
13:44sdegutisEspecially if Clojure wants to compete with Ruby, which has this built-in.
13:47llasramRuby also has Perl-inspired magical global variables tied to the regular expression engine
13:47llasramDo not want
13:47sdegutisAgreed, that feature is bogus.
13:47johnjelinekstrange ... I did async/close! my-chan and it crashed LT
13:47sdegutisOh.
13:54TimMcgfredericks: OK, it looks like gen-class definitely requires writing out to disk -- and then reading back from disk again. :-(
13:55bbloomsdegutis: 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:55jcromartiebbloom: I thought you said "that feature is in great peril"
13:56bbloomit's clear to me ruby started out as "i want a better perl" and later became "oh, smalltalk is cool" :-)
13:56sdegutisjcromartie: :D
13:56llasramIf only Matz had added system images
13:57sdegutisbbloom: Matz himself said: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/179642
13:57technomancysomehow 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:58amalloysdegutis: #w[x y z] is not very much terser than (w x y z). exact same number of characters, i think?
13:58bbloomsdegutis: there you go :-P
13:58sdegutisamalloy: ah but is it as clear?
13:59amalloyuh...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:59technomancywell, it feels like a reader concern to me
13:59sdegutisamalloy: True. Although isn't data_readers.clj only looked up in the current project?
13:59sdegutisamalloy: If so, it wouldn't be much digging, you just open the root-level file named data_readers.clj
13:59technomancyI don't think it's useful enough to justify the #w shortness, but I agree the former is clearer
14:00amalloysdegutis: 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:00sdegutistechnomancy: 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:00llasramsdegutis: the implementation finds and loads all top-level data_readers.clj files on the classpath
14:00technomancyamalloy: M-. not working on reader literals is dumb too =)
14:00sdegutisamalloy: touché good sir
14:00sdegutisllasram: Ahh.
14:01technomancyalso: aliases for reader literals should be able to be specified in the ns macro =P
14:01technomancyso you could use #w in one namespace without stomping others
14:01amalloytechnomancy: that'd be just one more thing making it hard to read clojure code without running it, for eg analyzers
14:01technomancynamespaces are cool, mkay?
14:02llasramAnd non-namespaced literals are implicitly in the namespace rhickey.decided.this.was.cool
14:02technomancyllasram: it's very un-egalitarian
14:02technomancymuch like the fact that you can't use namespaced :my.stuff/clauses in ns; that's super annoying
14:03sdegutisI'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:03llasramtechnomancy: On these points I cannot disagree
14:03ToBeReplacedsdegutis: pallet?
14:04lockssdegutis: it is?
14:04sdegutisToBeReplaced: whoa
14:04sdegutislocks: yessir
14:05locksbut they're almost opposites :P
14:05sdegutislocks: It's dynamic, terse, written for extensibility and expressiveness, and ideal for sane and maintainable DSLs.
14:05sdegutislocks: yessir
14:05sdegutisToBeReplaced: totally investigating.
14:06ToBeReplacedsdegutis: 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:06sdegutisToBeReplaced: thanks
14:12dbaschI'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:14sdegutisdbasch: I have been using openid4java but am looking into JOpenID.
14:14sdegutisI could not get Friend to work, but I think I'm not the target audience, which explains that.
14:14dbaschsdegutis: the openID part works, what doesn't work is restricting routes to logged in users
14:15dbaschI cloned this example, but it doesn't have any protected urls: friend-demo.herokuapp.com/openid/
14:15jcromartieman, when it comes to application configuration, when did we forget about environment variables?
14:17dbaschwhat 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:17sdegutisdbasch: you'd have to wrap your route handler code in some kind of function that checks the current user's permissions
14:17sdegutisWe do this with a macro that I've been trying to turn into a function for a year now with no luck.
14:18dbaschsdegutis: friend/authenticate supposedly does this, but it doesn't work properly
14:18dbaschor at least I can't get it to work
14:19jcromartiedbasch: what's the challenge here? we do it
14:19jcromartieso long as all your restricted routes are in one place
14:19sdegutisAh it should have been named "Mellon".
14:19jcromartieotherwise it's a bit piecemeal
14:19dbaschjcromartie: when I try to access a restricted resource, I get redirected to a blank login page instead of my login form
14:20dbaschjcromartie: I
14:20dbaschjcromartie: I'm using essentially this code: https://github.com/cemerick/friend-demo/blob/master/src/clj/cemerick/friend_demo/openid.clj
14:21dbaschthe only difference is that I set allow-anon? to false for the group of restricted routes
14:23dbaschif 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:34jcromartiedon't you need to specify mysite/login ?
14:34sdegutisLooks like Pallet does all that we need.
14:34sdegutisOnly lacking in docs, but the source is open.
14:35jcromartiedbasch: I mean do you have anything to render /login ?
14:37dbaschjcromartie: 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:38dbaschjcromartie: and debugging login shows that authentication doesn't happen
14:39jcromartiesorry, I don't really know much about the friend/openid stuff
14:39dbaschjcromartie: this is what login looks like:
14:39dbasch (GET "/login" req
14:39dbasch (if-let [auth (friend/current-authentication req)]
14:39dbasch (a/home req auth)
14:39dbasch (do (println "not authenticated" req) (c/home req)))))
14:40dbaschjcromartie: thanks, I
14:40amalloydbasch: www.refheap.com
14:41dbaschamalloy: sorry about that https://www.refheap.com/51256
14:42dbaschI'm at the end of my rope, pulling my hair out in frustration
14:42dbaschcannot believe it's so hard to do something that in Sinatra would take me 5 minutes
14:43seangrovedbasch: 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:43seangroveI think it's more akin to Devise
14:44sdegutisYeah we have something similar: (GET "/some/page" req ,,, (with-authorized-user req (do-some-stuff)))
14:44dbaschseangrove: 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:44sdegutisI could de-macroize it by just putting (fn [] (do-some-stuff)) instead, but I go back and forth on that.
14:45seangrovedbasch: 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:45sdegutisseangrove: Ahhh, I like that solution better I think.
14:45dbaschyeah, I like the with-authorized-user approach
14:46AeroNotixany tools that given a regex pattern would generate a string which satisfies that regex?
14:46sdegutisseangrove: 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:46seangrovesdegutis: I suppose that could be true. I'd have to think about
14:47dbaschsdegutis: right, I was hoping that you could just wrap all the routes you care about with something like friend/authenticate
14:47sdegutisAlthough they could still live in the same file, just two different (defroutes ...)
14:47dbaschin my case, I just don't want to accidentally leave a route unprotected
14:48sdegutisseangrove: 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:48sdegutisNot sure how to avoid that in the future, that was a gross bug.
14:48dbaschconceptually wrapping routes in friend/authenticate is the right thing, except I can't get it to work
14:48seangrovesdegutis: Yeah, it's possible. But we explicitely separate our authenticated routes and unauthenticated routes to addresss dbasch's concern.
14:49sdegutisRight.
14:49seangrovedbasch: So just write your own authenticate method, it's simple
14:49sdegutisThanks for the ideas yahl.
14:49dbaschseangrove: how?
14:49seangrovesdegutis: Then we namespace the url so that we only authenticate /api/*, or whatever it might be
14:49clojurebotHuh?
14:49sdegutisseangrove: Ah.
14:50dbaschseangrove: I spent too much time trying to write my own method and couldn't get it to work
14:51seangrovedbasch: 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:52dbaschseangrove: I'll give it a try, thanks
14:53seangrovedbasch: Then wrap the authenticated routes you care about and specify a prefix https://www.refheap.com/7a62e3170452398ee2502d656
14:53seangroveThat 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:54dbaschseangrove: for an api, sure. This is a simple webapp
14:54sdegutisSame here.
14:55seangrovedbasch: What's the difference?
14:55seangroveThey both follow the same principles
14:56dbaschseangrove: 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:57seangrovedbasch: With that code, if you omit the prefixes, everything needs to be authed
14:57seangroveIf not, it's just a one line change
14:58seangroveAnd if that's the case, then just wrap the routes you've defed and want authed
15:03jchaunceyso ive asked in the leiningen chan and didnt get an answer but has anyone written a active middleware for a core leiningen task?
15:05llasramjchauncey: I'm not really sure what that question means...
15:05jchaunceyim trying to write a middleware for the uberjar task
15:05gtrakjchauncey: 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:05llasramLeiningen middleware doesn't apply to a task. It's just code which gets a chance to modify the map
15:06llasramwhat gtrak said
15:06jchaunceyand doing uberjar.plugin/middleware dosnt seem to get picked up
15:06jchaunceythats fine
15:06jchaunceyi just need to override a value in the project map when a task is called
15:06jchaunceyit works if i explicitly set :middleware in the project.clj
15:06gtrakcan you override it for all tasks?
15:06jchaunceybut you can have it actively find all middleware if it conforms to a standard
15:07jchaunceythats what it does if you use :middleware in project.clj
15:07jchaunceyi would rather not do that
15:07jchaunceyinstead only override for a specific task/plugin (uberjar
15:07jchauncey)*
15:07gtrakmaybe there's a dynamic var somewhere that holds the current task
15:07llasramThat sounds like maybe you want a hook
15:07jchaunceyllasram: yeah maybe
15:07llasramBut if not -- are you just trying to get automatic middleware?
15:07jchaunceycould use preprend to run what i need before the uberjar function is called
15:07llasramSure
15:08jchaunceyllasram: yup
15:08gtrakyea, you want a hook
15:08llasramI've definitely done it before. Do you have a link to your project?
15:08jchaunceyllasram: nope =\
15:08jchaunceyLike hooks, middleware will be applied automatically for plugins if you put it in plugin-name.plugin/middleware. <(------------------- from the plugins.md
15:08llasramYes
15:09jchaunceyhrm
15:09llasramSo 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:09jchaunceyi basically want my teams to include my plugin and get this for free
15:10jchaunceyno need to explicitly set :middleware or :hooks
15:10jchaunceyyes
15:10gtrakyour plugin can provide a middleware that alters the hooks
15:10jchaunceybut how does that work if i want middleware for a core task
15:10llasramDude, you are thinking about it all wrong
15:10llasramHuman, rather
15:10llasramLet's not be sexist
15:10jchaunceyhehe
15:10jchaunceyisA man
15:10llasramMiddleware is task-irrelevant.
15:11jchaunceycorrect
15:11llasramThe namespace for your plugin needs to match the name of your *plugin*
15:12llasramNaming `uberjar.plugin` is completely broken
15:12llasramYou need to have a `my-plugin.plugin/middleware` var-function
15:12llasramWhere "my-plugin" is whatever you've named your plugin
15:12gtrakyour plugin can provide a 'project' middleware that alters the hooks, which then hook into uberjar.
15:13llasramgtrak: Um, or just use Leiningen's default hook auto-activation method :-)
15:13gtrakoh :-)
15:13jchaunceyyeah
15:13gtrakmiddlewares can do anything :-)
15:14gtrakah, I was thinking of this: 'Hooks can also be loaded manually by setting the :hooks key'
15:16llasramjchauncey: 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:16jchaunceythanks
15:16jchaunceyi think a hook is what i want
15:18llasramOOC, what's the end-goal you're trying to achieve?
15:21jchaunceyive build a series of plugins for bumping versions based on SEMVER that will be used by our CI system
15:21jchaunceyer built rahter
15:22TimMcAnyone 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:22gtrakwhat's wrong with those two?
15:23jchaunceythat 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:24llasramTimMc: Write a tiny stub class in Java :-D
15:25llasramTimMc: Or use ASM to generate a class in-memory which you then load via Clojure's DynamicClassLoader
15:26TimMcD-:
15:27llasramThe former is obvious more sane
15:27TimMcgtrak: proxy doesn't give you a real Class; gen-class involves barfing stuff out to disk.
15:28llasramTimMc: What are you trying to do at a higher level?
15:30TimMcllasram: Write a Zuul filter loader.
15:31llasramIs the class found via reflection?
15:31sdegutisWhat will Clojure be in 15 years?
15:31TimMcNetflix 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:31sdegutisWhat will be different about it?
15:31TimMcIt's great for Groovy, not as much for Clojure.
15:31xusersdegutis: it will be dead
15:31llasramOh, so then it needs to construct instances of the class itself?
15:32sdegutisI hope it'll start faster :)
15:32TimMcllasram: Yeah. :-/
15:32sdegutisxuser: oh?
15:32xusersdegutis: maybe with Java 9?
15:32llasramTimMc: 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:33llasramTimMc: Then I think you really actually might have a use for ASM :-D
15:33TimMcMultiple, different behavior, not known in advance. :-/
15:33xuserllasram: is ASM the lib that generates java bytecode in the clojure compiler?
15:34llasramIt 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:34llasramTimMc: Not necessarily a great example, but https://github.com/llasram/esfj/blob/master/src/clojure/esfj/provider.clj#L46
15:35TimMcllasram: Do you know if Clojure's lack of an "extend this class" utility is ideological or technical?
15:36llasramTimMc: I'd guess a combination of both, but more ideology
15:36llasramBut really have no special insight
15:37llasramTimMc: FYI, ASM includes the "ASMifier" http://asm.ow2.org/asm40/javadoc/user/org/objectweb/asm/util/ASMifier.html
15:38llasramYou run it on a Java class file, and it spits out the ASM (Java) API calls necessary to generate that class file
15:38TimMcNeat.
15:40fro_,(-> {:a 0 "b" 4} (:a))
15:40clojurebot0
15:40llasramI think this approach will get a lot more sane once clojure.tools.jvm is "finished"
15:40fro_,(-> {:a 0 "b" 4} ("b"))
15:40clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>
15:40fro_,(-> {:a 0 "b" 4} (:b))
15:40clojurebotnil
15:40fro_lol
15:40llasramI 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:40fro_check it, guys )
15:40fro_funny
15:41fro_but
15:41fro_,({:a 0 "b" 4} "b")
15:41clojurebot4
15:41llasram(inc Bronsa)
15:41lazybot⇒ 18
15:42fro_there is a problem with macros ->?
15:42llasramfro_: What there is unexpected?
15:43fro_,({:a 0 "b" 4} "b")
15:43clojurebot4
15:43llasramYes?
15:43fro_,(-> {:a 0 "b" 4} ("b"))
15:43clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>
15:43rasmusto,(-> {:a 0 "b" 4} (get "b"))
15:43clojurebot4
15:43fro_ok
15:43llasram,(macroexpand `(-> {:a 0 "b" 4} ("b"))
15:43clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
15:43llasram,(macroexpand `(-> {:a 0 "b" 4} ("b")))
15:43clojurebot("b" {"b" 4, :a 0})
15:44rasmusto,(macroexpand `(-> {:a 0 "b" 4} (get "b")))
15:44clojurebot(clojure.core/get {"b" 4, :a 0} "b")
15:44llasramfro_: ^^ all clear?
15:44fro_,(macroexpand `(--> {:a 0 "b" 4} ("b")))
15:44clojurebot(sandbox/--> {"b" 4, :a 0} ("b"))
15:44fro_,(macroexpand `(->> {:a 0 "b" 4} ("b")))
15:44clojurebot("b" {"b" 4, :a 0})
15:45fro_yea
15:45fro_clear
15:45fro_thx
15:49sdegutis,("b" {"b" 4})
15:49clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>
15:50sdegutis,('b {'b 4})
15:50clojurebot4
15:50sdegutis,(:b {:b 4})
15:50clojurebot4
15:50sdegutisOh.
15:50ordnungswidrigsdegutis: symbol and keyword implement ifn
15:50sdegutis,(4 {4 :b})
15:50clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
15:50sdegutis,({} {})
15:50clojurebotnil
15:50sdegutis:D
15:51rasmusto,({} {{} 'foo})
15:51clojurebotnil
15:51rasmusto,({{} 'foo} {})
15:51clojurebotfoo
15:51sdegutis:D
15:51sdegutisI'd never have guessed that one.
15:51ordnungswidrig,({} {}) ;; <= clojure emoticons
15:51clojurebotnil
15:51sdegutis,(() ())
15:51clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentList$EmptyList cannot be cast to clojure.lang.IFn>
15:51ordnungswidrig,({:o :o})
15:51clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentArrayMap>
15:51rasmusto,:D
15:51clojurebot:D
15:51ordnungswidrig,'({:o :o})
15:51clojurebot({:o :o})
15:52sdegutisHold on now, let me remember..
15:52sdegutis,(= () '())
15:52clojurebottrue
15:52sdegutisYes, that's a hipster.
15:53sdegutisHe's wearing steampunk pilot goggles.
16:08jowag,(:•_:•)
16:08clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :?_:?>
16:11TimMc,'😰
16:11clojurebot??
16:13sdegutis:D
16:45asthasrGood afternoon!
16:45asthasrAnd/or evening, as the case may be.
16:45rasmustogoodaften
16:46asthasrI'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:48sdegutisThe exception should have a stacktrace I think.
16:48rasmustoasthasr: you're talking about finding the line in the large file?
16:48asthasrSure, there's a stacktrace, but it doesn't include the data, just the location where it occurred (the :pre condition)
16:48asthasrYes, rasmusto. I want to see what input is causing the precondition to fail
16:49asthasrbut when I try to do printlns before the fact, they never seem to be output
16:49rasmustohrm, yeah I think those functions get messed with
16:50AeroNotixhttps://github.com/AeroNotix/lapse reiddraper
16:52rasmustoasthasr: erm, you can do a {:pre (do (prn "blah") (assert something))}
16:53justin_smithasthasr: or maybe even {:pre [(and datum (f datum))]}
16:53justin_smiththat should show datum when it fails
16:53rasmustowell, what if datum is nil?
16:54reiddraperAeroNotix: oh neat
16:54rasmustoI assume nil would be bad, but I don't know the context much
16:54justin_smith(and [x] (f x))
16:54rasmustoah, that'd do it :)
16:55justin_smithnope, that does not work because it prints the literal test that failed
16:55rasmusto,((fn [x] {:pre [(and [x] (odd? x))]} x) 2)
16:55clojurebot#<AssertionError java.lang.AssertionError: Assert failed: (and [x] (odd? x))>
16:55rasmustoah, darn
16:55justin_smithbut it does not show the value it failed on
16:55rasmusto,((fn [x] {:pre [(do (prn x) (odd? x))]} x) 2)
16:55clojurebot2\n#<AssertionError java.lang.AssertionError: Assert failed: (do (prn x) (odd? x))>
16:55justin_smithbetter, but gives us unneeded printouts
16:56justin_smith((fn [x] {:pre [(or (odd? x) (prn x))]} x) 2)
16:56justin_smithonly prints when it fails :)
16:56justin_smith,((fn [x] {:pre [(or (odd? x) (prn x))]} x) 1)
16:56clojurebot1
16:56justin_smith,((fn [x] {:pre [(or (odd? x) (prn x))]} x) 2)
16:56clojurebot2\n#<AssertionError java.lang.AssertionError: Assert failed: (or (odd? x) (prn x))>
16:56rasmusto,((fn [x] {:pre [(if (odd? x) (do (prn x)))]} x) 2)
16:56clojurebot#<AssertionError java.lang.AssertionError: Assert failed: (if (odd? x) (do (prn x)))>
16:57AeroNotixreiddraper: I sent a PR on github for check, not sure if it's the right place.
16:57justin_smithprn returns nil, so the do is not needed
16:57rasmustogotcha. or seems like it'd work well
16:58justin_smithhas the right semantics at least
16:58justin_smiththough could be opaque to other users of the code
16:58rasmustoyeah, name is a bit inconvenient
16:58justin_smithI 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:59asthasrit doesn't seem to work for me
16:59asthasrlet me show code
16:59asthasr{:pre [(or (every? (comp (partial = Name) type) original-names) (prn original-names))]}
16:59asthasrand in the repl
16:59asthasr(file->records (first data-files))
16:59asthasrAssertionError Assert failed: (or (every? (comp (partial = Name) type) original-names) (prn original-names))
17:00asthasrno actual output
17:00mikerodasthasr: sounds like you'd need to hav a bit more fine-grained error checking
17:01mikerodputting it all in the pre-condition isn't likely to get you a lot of useful context
17:01justin_smithif that failed, I think it should have printed
17:01justin_smithyeah, a series of assert statements is probably better here, agreed
17:02`cbpIf anyone finds this useful: https://www.refheap.com/51314
17:03`cbpThey'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`cbp..to cider
17:04RickInAtlanta`cbp thx
17:05`cbp:)
17:09asthasrThanks guys. I think I'm going to have to rework some of my processing logic to make asserts at more points...
17:09asthasr(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:09TimMcllasram: 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:10ordnungswidrigI 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:11justin_smithasthasr: another thing that helps is making more / smaller functions, making sure each one does exactly one thing, and testing their behavior individually
17:11ordnungswidrigrepl startup will fail if anything in user refers to a broken something in another ns
17:12justin_smithordnungswidrig: 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:12mikerodasthasr: stick with it, it gets better
17:13ordnungswidrigyes, but I want to have some convenience functions in user to start the system
17:13justin_smithdon't
17:13justin_smithput them in util, or something else
17:13justin_smithleave user empty
17:14justin_smithsorry, don't mean to sound bossy
17:14ordnungswidrigcome on! is best practive nowadays :)
17:15ordnungswidrigs/v/c
17:15technomancythe user namespace is really not a great place to dump convenience stuff
17:15technomancybecause it just goes away when you switch namespaces
17:15technomancyyou need commands exposed in your client IMO
17:15justin_smithyeah, for that very "repl failing to start" reason for starters
17:16sdegutisI didn't know the user ns was so transient.
17:16technomancyalso putting one in a library is super sketchy
17:16sdegutisDoesn't REPLy do that?
17:16ordnungswidrig"exposed in your client"?
17:16sdegutisIn that case I think it's helpful.
17:16technomancysdegutis: I think it intercepts some forms to give the illusion of having them exist in all namespaces
17:17sdegutisAh interesting.
17:17technomancywhich is neat, but I don't like how it makes them look like function calls
17:17technomancyslime does this better; it accepts commands like ,do-somethin
17:17sdegutisYeah, they should be custom tagged readers.
17:17technomancy=P
17:17sdegutis#doc interpose
17:17sdegutisNo srsly.
17:17sdegutis#examples cond->
17:17technomancyno
17:18technomancyit shouldn't look like a value
17:18sdegutisBut it's so terse!
17:18technomancyit should be something that's invalid clojure syntax
17:18technomancyit's so simple!
17:18technomancyand powerful!
17:18sdegutisxD
17:18sdegutisInvalid Clojure syntax? No such thing.
17:19sdegutisInvalid Clojure semantics, sure. But nearly everything is valid Clojure syntax.
17:19justin_smith::::sdegutis:
17:19justin_smith,::::sdegutis:
17:19clojurebot#<RuntimeException java.lang.RuntimeException: Invalid token: ::::sdegutis:>
17:19justin_smiththat's invalid clojure syntax
17:19sdegutis,new Exception()
17:19clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: new in this context, compiling:(NO_SOURCE_PATH:0:0)>
17:19technomancy,~ohai
17:19clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ohai in this context, compiling:(NO_SOURCE_PATH:0:0)>
17:19justin_smithfor example
17:19sdegutisjustin_smith: ah
17:19ordnungswidrig,(keyword "::::sdegutis:)
17:19clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading string>
17:20ordnungswidrig,(keyword "::::sdegutis:")
17:20clojurebot:::::sdegutis:
17:20sdegutisHey guys
17:20justin_smithright, the object can exist, but that read syntax is invalid
17:20sdegutisLook over there ------>
17:20asthasr,(:::::sdegutis)
17:20clojurebot#<RuntimeException java.lang.RuntimeException: Invalid token: :::::sdegutis>
17:20technomancywhoa, batman
17:22ordnungswidrigso, in which way is ns user special?
17:23sdegutis,(do (in-ns 'user) (def foo 3) ,,, (in-ns 'somethingelse) ,,, (in-ns 'user) foo)
17:23clojurebot3
17:23sdegutisDunno.
17:23ordnungswidrigso
17:24justin_smithit is special because repls start up in it
17:24ordnungswidrigok
17:24justin_smithso if it is broken the repl can't start
17:24ordnungswidrig"because it just goes away when you switch namespaces"
17:24technomancyit's also loaded at startup
17:24ordnungswidrigtechnomancy: says
17:25justin_smithI *think* what technomancy meant by that is that the advantage of putting things in user disappears when your switch namespaces
17:25justin_smithand it is easy to switch namespaces
17:25ordnungswidrigI see
17:25technomancyordnungswidrig: (use 'clojure.pprint) ; great, now you have it. for a while, then it's gone when you in-ns
17:25justin_smithso why not put the stuff you want in a different one
17:25technomancyvs M-x cider-pprint or whatever
17:25technomancywhich will always be with you
17:25technomancytill death do you part, &c
17:25ordnungswidrigso I better use core!
17:25ordnungswidrig*g*
17:25technomancysuper tempting!
17:25ordnungswidrigreader macro ftw?
17:26technomancyno, use elisp
17:26rasmustoeclipse?
17:26sdegutislol
17:26rasmustosorry
17:26asthasrI 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:27justin_smithas I mentioned :)
17:27ordnungswidrigM-x (cider-eval-sync "1") => no repl connection
17:27justin_smithsorry, that sounds smug. I mean yeah, breaking things into smaller parts will bring happiness.
17:27reiddraperAeroNotix: i'm afraid clojure contrib repos can't take pull-requests
17:27technomancyalso increase your sex appeal
17:28ordnungswidrigoh, my repl died
17:28johnjelinekordnungswidrig: don't feel bad, my repl just died too (LT)
17:28goldfeldhave you guys seen vinyasa from zcaudate?
17:29goldfeldit's pretty cool for injecting stuff you want right into core for dev purposes
17:31PinkPrincessSo 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:31PinkPrincessIt's here: http://pastebin.com/EmfuMGzP
17:31PinkPrincessEssentially I'm trying to distribute downloading a lot of web pages (~14000) using channels.
17:32PinkPrincessBut I'm struggling with everything either being lazy (and returning immediately, never realizing anything) or being very eager (and blocking the main thread).
17:32bob2have you read http://martintrojer.github.io/clojure/2013/07/07/coreasync-and-blocking-io/ ?
17:32PinkPrincessI'd like to have some progress displayed during the rather long download process.
17:33PinkPrincessNope. I'll go read that.
17:35PinkPrincessThat does seem a lot simpler than what I'm getting into.
17:37PinkPrincessIs there an easy way to control the go block thread pool size?
17:38bob2http://stackoverflow.com/questions/18779296/clojure-core-async-any-way-to-control-number-of-threads-in-that-go-thread
17:38bob2but the point of the above is to avoid just spamming one thread per io-bound thing
17:39johnjelinekdnolen_: you around?
17:40PinkPrincessThanks, bob2.
17:42creeseapi question: should you marshal first, or validate first? I'm undecided.
17:43AeroNotixcreese: validate what?
17:43creeseAeroNotix: the data coming in
17:43AeroNotixcreese: what is the data, presumably JSON?
17:44creeseAeroNotix: example: you have a date field, you want to be sure it's an actual date and not something else
17:44creeseAeroNotix: assume JSON
17:44AeroNotixcreese: use closchema
17:44AeroNotixcreese: https://github.com/bigmlcom/closchema
17:44AeroNotix!next
17:45amalloycloschema sounds like some kind of medical condition
17:45AeroNotixIt's just a JSON schema validator
17:46AeroNotixwrite your schema -> validate instances of it
17:46AeroNotix-> delete idiotic code you were writing yourself
17:46AeroNotixcreese: if it's JSON you seriously should not be rolling your own validators outside of special cased fields
17:46creeseAeroNotix: too late
17:46AeroNotixcreese: delete the code->use closchema
17:47dsrx'closchema' reminds me of 'cloact'
17:47creeseAeroNotix: does it marshal too?
17:48AeroNotixcreese: why would it? Use ring-json middleware for that
17:49AeroNotixcreese: were you manually decoding the json on each request?
17:49AeroNotixtechnomancy: I'm having great success with that project
17:49technomancyhad another team use it for a big API and said it was a great fit
17:50AeroNotixit really i
17:50AeroNotixis
17:50tolitiusis 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:50AeroNotixI just added a feature where you can override certain keys with your own validators
17:50sdegutistechnomancy: have you seen that new thing on HN?
17:50technomancyAeroNotix: are you using it with erlang?
17:50technomancysdegutis: hm?
17:50sdegutistechnomancy: the new Q lang, kinda related to json-schema
17:50AeroNotixtechnomancy: We use Jesse but Jesse doesn't do references, we're working on adding it.
17:50technomancyAeroNotix: sweet
17:50sdegutistechnomancy: https://news.ycombinator.com/item?id=7333354
17:50sdegutistechnomancy: also http://www.q-lang.io/
17:51AeroNotixtechnomancy: in fact I might tackle jesse references this week
17:53asthasrAre there any really good books that go into the practical aspects of designing a system using lisp?
17:53creeseAeroNotix: the project in Python, I just come here for inspiration
17:53technomancythe edn fans on this thread; my goodness
17:53asthasrI'm thinking of, by way of comparison, "Domain Driven Design" on the OO side (although I never liked DDD)
17:53AeroNotixcreese: https://pypi.python.org/pypi/jsonschema
17:53technomancyI can't help but get the "stop trying to make 'fetch' happen. it's not gonna happen" feeling
17:54AeroNotixcreese: always use a validator! There's no reason not to.
17:54AeroNotixtechnomancy: which thread?
17:54technomancyAeroNotix: the one sdegutis linked to
17:54AeroNotixah
17:54sdegutistechnomancy: that's cuz EDN is the best format ever
17:55sdegutisIt was almost HTML but ended up not being HTML.
17:55creeseAeroNotix: can you execute arbitrary functions?
17:55bjaI 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:56AeroNotixcreese: As validators? In the python one I have no idea
17:57technomancyEven 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:57AeroNotixWorse is better
17:58technomancyif you ever find yourself complaining about json, just be thankful there was a massive backlash against xml
17:58technomancybecause it could be a lot worse
17:58Wild_Catyeah, at least JSON isn't XML :p
17:58asthasrsadly, in some contexts, I think XML was better :(
17:59hiredmanThings: they could be worse.
17:59Wild_CatXML is better for marked-up text documents.
17:59technomancyhiredman: always the optimist
17:59Wild_Catwhich isn't surprising in and of itself. What is is that the enterprise people decided it should be used everywhere and for everything.
17:59technomancy"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:00sdegutistechnomancy: xaml is awesome
18:01technomancysdegutis: is it simple while at the same time being powerful?
18:01sdegutis*whilst
18:01technomancyoh snap
18:01sdegutisbut otherwise yes, exactly
18:03johnjelinekI'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:03johnjelinek(it's using http-kit)
18:04johnjelinekI thought I could test it with this: (go (while true (let [[_ results] (<! (query-api "http://en.wikipedia.org/w/api.php?action=opensearch&amp;format=json&amp;search=cat&quot;))] (println results))))
18:04johnjelinekbut this doesn't seem to be the case -- what's the best way to test this defn?
18:04sdegutisBut 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:04sdegutis(end-user in the programmer sense)
18:04sdegutis(wait, that doesn't disambiguate it at all...)
18:05sdegutisGonna so investigate Pallet soon.
18:05sdegutisClojure's version of Chef? Heck yeah!
18:06amalloyjohnjelinek: 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:07johnjelinekamalloy: should I use >! instead?
18:09johnjelinek(doc put!),
18:09clojurebotCool story bro.
18:09johnjelineklol
18:09johnjelinek(doc clojure.core.async/put!),
18:09clojurebotIt's greek to me.
18:09johnjelinekhrm
18:09johnjelinekamalloy: docs say put! is async
18:09johnjelinekso it shouldn't block right?
18:11amalloyoh, right. i guess put! is the...non-blocking primitive on which >! is built? i don't really understand put!
18:12tolitiusI think put! is used outside of the go block while >! is used only within
18:12johnjelinektolitius: that's correct
18:13amalloyincidentally, johnjelinek, query-api could be better (imo) written as: (doto (chan) (put! @(http/get uri)))
18:13johnjelinekamalloy: ok, but then how would I pass the channel around?
18:13amalloythe let/munge/return pattern is easily replaced with doto, in general
18:13amalloyjohnjelinek: i'm saying my definition is exactly equivalent to yours
18:14johnjelinekok
18:14amalloy(doto x (f y)) macroexpands to (let [foo x] (f foo y) foo)
18:15johnjelinekok, and so now how would I read from this channel?
18:16johnjelinek(go (while true (<! (query-api "http...")))) ?
18:16johnjelineknote: I'm in REPL
18:18tolitius@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:19johnjelinektolitius: right -- so query-api returns the channel, and now I'm trying to build a processor for the channel
18:20johnjelineklike this? (let [c (query-api (query-api "http://urlquery&quot;))] (go (while true (println (<! c)))))
18:20tolitiusjohnjelinek: 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:22tolitiusjohnjelinek: probably more like (fun [c] (go (while true …))), and then pass (query-api ..) to it. all depends on the "whole grand design"
18:22johnjelinektolitius: well, right I'm just trying to understand core.async
18:22tolitiusjohnjelinek: e.g. in case with just (fun [c] ..) you can potentially reuse this processing for other channels as well
18:23tolitiushere 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:25johnjelinekI'm unfamiliar with alt!
18:26tolitiusjohnjelinek: 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:26justin_smithI still like how randomly excited people are when they talk about certain side-effecting functions
18:26danielszmulewiczdnolen_: ping
18:27tolitiusjohnjelinek: "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:29johnjelinektolitius: ahh, that's cool :)
18:29johnjelinektolitius: 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:30johnjelinekshould I use multiple channels for this or just 1?
18:30tolitiusjohnjelinek: 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:33johnjelinektolitius: 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:33tolitiusjohnjelinek: 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:34johnjelinektolitius: because I have 36000 queries to make to a WebAPI
18:34johnjelinekdifferent querystring for the same URL
18:35amalloyi 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:36johnjelinekamalloy: lol
18:37johnjelinekwell, it's hitting a load balancer that then sends it off to a server that can take my request
18:37johnjelinekso it's a distributed 36000 ;)
18:38tolitiusjohnjelinek: 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:40tolitiusjohnjelinek: 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:41johnjelineknoted :)
18:43danielszmulewiczAnyone knows how to use ReactCSSTransitionGroup from om?
18:45seangrovedanielszmulewicz: Could be a bit tough, I don't think there's an extern file for it
18:45danielszmulewiczI would like to use CSS transitions when rendering an Om component.
18:46danielszmulewiczseangrove: 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:47danielszmulewiczseangrove: Maybe I should open an issue on Om's github?
18:47sakekasihi 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:47sakekasihere is a gist with my code: https://gist.github.com/sakekasi/9337146
18:47sakekasiany ideas as to what could cause something like this?
18:47johnjelinektolitius: so I'm kind of getting it to read. This prints: (let [responses (atom nil)] (go (dotimes [_ 10] (let [query (query-api "http://query&quot;)] (println (<! query))))) responses)
18:48johnjelinekbut what I want is to send it to my atom and return the atom in the end
18:48johnjelinekso I tried (reset! responses (conj responses (<! query)))
18:48johnjelinekbut that did not work
18:48seangrovedanielszmulewicz: I wouldn't mind having access to it, certainly
18:49seangroveI haven't looked at how they work at all, so I don't know the challenges
18:49danielszmulewiczseangrove: Some discussion here: https://github.com/swannodette/om/issues/59
18:49amalloyjohnjelinek: (reset! x (conj x ...)) can never work, because nothing sequential is also resettable. you must mean something like (swap! responses conj ...)
18:50johnjelinekamalloy: yes, sorry -- but swap! doesn't work either, returns an empty atom
18:50tolitiusjohnjelinek: why atom, why not just return a channel?
18:51johnjelinekyou mean return a channel for my consumer?
18:52johnjelinekI'm trying to aggregate all of the http responses -- so why would it be good to return a channel rather than the aggregate?
18:54tolitiusjohnjelinek: 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:54johnjelineklol, I tried just with future previously, but I spun up too many threads
18:54johnjelinekand ran out of memory
18:54johnjelinekthat's when core.async was recommended to me
18:55hiredmanugh
18:55hiredmanwhy any one would recommend core.aync for an io task I don't know
18:55tolitiusjohnjelinek: you can limit your threads: https://github.com/tolitius/lasync
18:55hiredmanusing an executor with a fixed size threadpool
18:56johnjelinektolitius: but yes, I would like it be decouple producing and consuming
18:56johnjelinekoy, another library :|
18:56johnjelinekthanks though
18:57hiredmanjohnjelinek: I doubt you need it
18:57hiredmanhttp://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool%28int%29
18:58tolitiusjohnjelinek: it's a micro library though.. just plugging in a different queue to the thread pool executor
18:58tolitiushiredman: it is different
18:58hiredmantolitius: I understand, I doubt he needs the difference
18:58tolitiusjohnjelinek: but yea, in case you would like to decouple, I would return a channel
18:59johnjelinektolitius: https://www.refheap.com/51352 so you're saying the consumer should also return a channel?
18:59johnjelinekat what point am I building my aggregate?
18:59tolitiushiredman: with "lasync", johnjelinek could create number of tasks, and just through all 36000 requests to them without pool returning "false"..
18:59seangrovehiredman: Even for making http calls? Seems like core.async is an alright match for coordinating the order of things
19:01dnolen_johnjelinek: what's up?
19:02hiredmantolitius: 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:02johnjelinekdnolen_: 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:03dnolen_johnjelinek: I don't see how it would be any different, go loops won't block the repl
19:03sakekasi_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:04tolitiusjohnjelinek: 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:04johnjelinekdnolen_: I see .. I'll keep playing with it ... what I was trying kept freezing LT
19:04dsrxhmmmm
19:04dsrxtrying to imagine a use-case for putting core.async channels onto a core.async channel
19:04danielszmulewiczdnolen_: https://github.com/swannodette/om/issues/129#
19:05dsrx'higher order channels' if you will
19:05johnjelinektolitius: well, in the example I linked to, it's just 1 channel
19:05dnolen_danielszmulewicz: I closed that it's just #59
19:05danielszmulewiczdnolen_: I would love to help.
19:05dnolen_danielszmulewicz: it's not an Om thing
19:05hiredmanunless you are very careful, you are going to break things when mixing core.aync and io
19:05dnolen_danielszmulewicz: even #59 is not an Om thing
19:05danielszmulewiczdnolen_: Fine. But what can I do to use CSS transitions?
19:06tolitiusjohnjelinek: 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:06johnjelinekhrmm ... ok, I'll keep playing with it then :)
19:06johnjelinekthanks!
19:06johnjelinekg2g
19:07hiredmanyou 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:07dnolen_danielszmulewicz: https://github.com/swannodette/react-cljs
19:07dnolen_danielszmulewicz: use React Add Ons, add externs
19:09dnolen_danielszmulewicz: https://github.com/swannodette/react-cljs/issues/1
19:09danielszmulewiczdnolen_: Ah, OK. I haven't worked with externs yet. I will investigate. Thank you.
19:09dnolen_danielszmulewicz: pull requests definitely welcome for this
19:10hiredmanvery 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:10dnolen_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:10dnolen_danielszmulewicz: packaging them up is not sufficient for ClojureScript use
19:10danielszmulewiczdnolen_: I understand. I'll gladly do it if I can wrap my head around it.
19:11seangrovedanielszmulewicz: It's quite some work.
19:11danielszmulewiczseangrove: Is this documented somewhere?
19:11seangrovehttps://code.google.com/p/closure-compiler/wiki/FAQ#How_do_I_write_an_externs_file?
19:12danielszmulewiczseangrove: Thanks.
19:12seangrovedanielszmulewicz: Depending on what level of detail you want, it's easier. It can be automated if you drop the type info
19:13danielszmulewiczWould this help? https://gist.github.com/Chouser/5796967
19:16sakekasihi 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:17danielszmulewiczseangrove: What does it take to automate this (without the type info)?
19:17tolitiusdanielszmulewicz: http://www.dotkam.com/2013/07/15/clojurescript-use-any-javascript-library/ (if that helps)
19:17danielszmulewicztolitius: thanks.
19:18estebanrulesOf course this depends on the indvidual, but how easy of a "jump" would it be from Scheme to Clojure?
19:20sakekasiestebanrules: scheme and clojure share a lot of general semantics. The jump should be pretty easy given a reasonable knowledge of the underlying java
19:20sakekasiestebanrules: clojure likes to give errors that are rather cryptic unless the underlying java is understood.
19:22estebanrulesthe underlying java is going to be my largest barrier I fear. I haven't coded anything in Java in over 10 years.
19:23bbloomestebanrules: 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:23gfredericksTimMc: that's a bit surprising
19:23bbloombeyond 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:24estebanrulesOh
19:25bbloomestebanrules: follow some folks on 4clojure.com & do the puzzles. that's the good way to learn the stdlib and idioms in a hurry
19:25estebanrulesThanks. Oh yes I intend to read all of the documentation.
19:27estebanrulesbbloom: 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:27bbloom~books
19:27clojurebotbooks is book
19:27bbloom~book
19:27clojurebotbook is http://www.pragprog.com/titles/shcloj/programming-clojure
19:27justin_smithclojure programming / emerick carper & grand is good
19:29estebanrulesThank you.
19:31sakekasiany idea as to why clojure would cache the result of a function rather than call it?
19:32tolitiussakekasi: memoize ?
19:32isaacbwmemoization
19:32dnolen_sakekasi: doesn't sound likely, gist?
19:32sakekasihttps://gist.github.com/sakekasi/9337146
19:32sakekasiits a ring project that uses liberator
19:32sakekasiget-latest-links and get-latest link are called while the server is starting up
19:33sakekasifor some reason, these are the returned values, even when I post to the db.
19:33sakekasiit takes a server restart to get the functions called again and for the values to change
19:33dnolen_sakekasi: sounds like a bug in the libraries your are using - not Clojure per se.
19:33sakekasihuh, so liberator?
19:34dnolen_sakekasi: not necessarily
19:34sakekasiI could see that
19:34sakekasidoes clojure.java.jdbc cache for some reason?
19:35justin_smithshould 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:35justin_smithwhich would explain the npe
19:35justin_smithI think you are missing # or (fn [] ...) wrapping
19:36justin_smith*rather than random predicate forms
19:36sakekasithat makes sense
19:36sakekasijust found this article
19:36sakekasihttp://stackoverflow.com/questions/3161986/compojure-clojure-contrib-sql-select-query-is-being-cached-why
19:36sakekasithat suggests that I didn't do fn[] wrapping in my defroutes
19:37justin_smithsakekasi: ok, reader deeper: you need to redefine your non-nil function
19:38justin_smithit should expect a function as a second argument
19:38justin_smith(and call it)
19:38justin_smithand then you should wrap the call to non-nil in a lambda
19:38sakekasiThe way I defined non-nil, I wanted my function to be evaluated on call.
19:38justin_smitheither #() or (fn []) whichever you prefer
19:39justin_smiththe args are evaluated before being passed in...
19:39justin_smithOK non-nil may be OK, but the thing calling it should be a function called at run time
19:39justin_smithso again about wrapping as a lambda
19:40seangrovedanielszmulewicz: 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:40danielszmulewiczseangrove: Awesome. Let me know if I can help.
19:41seangroveI image a lot of head-banging and gnashing-of-teeth for awhile
19:41danielszmulewiczseangrove: :-)
19:41dsrxspeaking of which...
19:42dsrxthe 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:42dnolen_dsrx: or ask here or in #clojurescript
19:42dsrxah okay
19:45sakekasijustin_smith: can you give me a line#/resource name?
19:46justin_smithbasically do a search for :exists?
19:46justin_smitheach one has an expression that is evaluated at compile time
19:47justin_smithand should probably be a function evaluated each time existence is checked
19:47sakekasiok
19:48sakekasiahh i get it. these are all being evaluated at compile time
19:48justin_smithhttp://yogthos.net/blog/30-Making+services+with+Liberator notice in this example, exists takes a funciton as argument
19:48justin_smithnot an arbitrary expression
19:48justin_smithyeah - and if it returns nil, then liberator tries to call nil at runtime as a function
19:48justin_smithso boom, npe
19:48justin_smithwhich you see in your stacktrace
19:50seangrovednolen_: 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:50dnolen_seangrove: I find it strange that Ring or SimpleHTTPServer could not handle serving some files
19:51seangrovednolen_: As do I.
19:51seangrovednolen_: But perhaps it's PEBKAC, so checking if you run into it at all
19:51justin_smithhow many files are we talking about here? tens? hundreds? millions?
19:51seangrovejustin_smith: few hundred all at once
19:52seangroveFor python, it just drops the files every now and then. For ring it serves them, but takes an awful amount of time
19:52dnolen_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:53dnolen_s/serve/server
19:53seangrovednolen_: The hundreds of files are for cljs files, source maps, js files, and then all of the actual html content like images/markup
19:54seangrovednolen_: Anyway, not willing to state this as a categorical problem yet, just asking if others are running into ti
19:54seangroveAfter developing with mies-om for Omchaya and seeing what it's like, I definitely want that where possible
19:55dnolen_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:55isaacbwis there an out-of-box way to pretty print json?
19:56dnolen_isaacbw: data.json supports pretty printing
19:56noprompt_isaacbw: there's a plugin for chrome called JsonView which is nice.
19:56sakekasiawesome! I ended up getting my project to work. thanks for all the help!
19:56bjapython -m json.tool file.json
19:56justin_smithsakekasi: glad to hear it
19:56isaacbwdnolen_: I found pprint, but it doesn't do newlines afaict
19:57dnolen_isaacbw: what do you mean doesn't do newlines?
19:57noprompt_brew install jsonpp
19:57noprompt_there's about dozen ways to do it.
19:57isaacbwdnolen_: 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:57gfredericksI like jq
19:57bjacheshire can do it if you're okay with a library
19:57dnolen_isaacbw: pretty sure that it does
19:57isaacbwhmm
19:57gfredericksisaacbw: did you give it small input that fits comfortably on a line?
19:58bja(generate-string {:foo "bar" :baz {:eggplant [1 2 3]}} {:pretty true})
19:58stkim1I have a question. Say I have a lib such as hiccup. How do I navigate list of functions like javadoc?
19:58gfredericksclojure.repl/dir
19:59gfrederickscombined with clojure.repl/{doc,find-doc}
19:59justin_smithbja: but that's edn, not json
19:59gfredericksjustin_smith: what?
19:59gfrederickshe's talking about cheshire
19:59justin_smithahh, never mind, I missed that it was generate-string
19:59stkim1gfredericks, thank you!
19:59isaacbwgfredericks: oh, there we go!
19:59isaacbwcool, thanks
20:00gfredericks,(= 1 (apply str "0." (repeat \9)))
20:00clojurebot#<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>
20:04amalloygfredericks: that's pretty cute
20:04amalloymaybe it would have returned true eventually, given enough digits
20:05amalloywe'll just never know
20:06isaacbw,(println "Hello")
20:06clojurebotHello\n
20:06isaacbw:O
20:09gfredericks,(println "Hello\\n")
20:09clojurebotHello\n\n
20:10zachmassiaIs doall needed when the seq is being passed to an update-in call? https://gist.github.com/ZachMassia/470a57e5e7a0169667c9
20:11gfredericks,((fn f [x] (->> (repeatedly rand) (take-while #(< % x)) (map f))) 1.0)
20:11clojurebot(() (() ((())) () ()) (() () () ()) () () ...)
20:11gfrederickszachmassia: without it the new value in the map will be an unrealized lazy seq
20:12seangrove:wq
20:12amalloyzachmassia: doall is quite rarely needed
20:12gfrederickszachmassia: but that's probably fine here, as amalloy says
20:12amalloya doall would only be needed here if the update functions in your entities perform time-sensitive side effects
20:14gfredericks,((fn f [x] (->> (repeatedly rand) (take-while #(< % x)) (map f))) 0.8)
20:14clojurebot()
20:14gfredericks,((fn f [x] (->> (repeatedly rand) (take-while #(< % x)) (map f))) 0.8)
20:14clojurebot(() (((() ())) () () ()))
20:14zachmassiaHmm, 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:14amalloyadding more entities will have no effect
20:15amalloythe 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:15zachmassiaActually now that I think of it, I iterate over them to draw them, so the doall is probably redundant then, right?
20:15amalloyright
20:15Cr8possibly. The doall can ensure that you don't *do compute in your draw routine* though.
20:15amalloythat's a good point, actually
20:15Cr8though in that sort of situation perhaps you should swap (doall (map ...)) for (mapv ...)
20:16zachmassiaGood call, Cr8. I'll have a look into mapv
20:16amalloyif 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:17zachmassiaI'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:17Cr8mapv 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:18Cr8if you're throwing reducers at it in the same place though use reducers/map
20:19zachmassiaCr8: No reduce or anything right now. mapv sounds exactly like what I need
20:19zachmassiaThanks for the help guys :)
20:30goldfeldoohh i like that big-bang library link
20:31xeqiseangrove: do you have a good way to do server side rendering?
20:31seangrovexeqi: For React code?
20:31xeqiyep
20:32seangroveNope. 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:32seangrovexeqi: The React guys keep telling me not to re-implement the React rendering code in Clojure, sadly.
20:33xeqiseangrove: heh, I'd skip rewriting the rendering too
20:33xeqiI've seen https://github.com/brendanyounger/omkara/blob/master/src/omkara/react.clj#L29, which basically uses rhinko
20:33xeqi*rhino
20:34xeqicould embed something similar for dyn.js if wanted
20:34zachmassiagoldfeld: 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:35xeqibut leaves that leaves open how to handle ajax calls for initial data vs rendering them already from server side
20:35seangrovexeqi: 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:35xeqiand how to load the initial app state w/ that data if server side rendered
20:36seangrovexeqi: Yeah. It's messy enough that I wouldn't really recommend any one-way for newcomers yet, certainly.
20:36xeqioh well, I'll be interested to see if you come up with something
20:38seangrovexeqi: 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:38seangroveAnd the initial state is enough for good SEO
20:38seangroveBut it's a pretty specific approach, still thinking about a more general solution
20:48goldfeldzachmassia: cool! i was considering using the monet fork too, will check out your code, thanks
21:00dnolen_seangrove: Om 0.5.1 out
21:00seangrovednolen_: Awesome. I meant to send a PR with IDsplayName implemented for Om inputs
21:01seangrovednolen_: I can send that in a few minutes if you haven't done it already
21:01dnolen_seangrove: just open a issue for that, I can do it easily enough.
21:02dnolen_seangrove: will have to wait for next release
21:04mlb-I'm having trouble unarchiving a password protected zip file from clojure. Does anyone have experience with this?
21:11benmossmlb-: are you using a library?
21:13mlb-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:13benmossZipInputStream doesn't support password protected files
21:13benmosshttp://www.lingala.net/zip4j/ is probably your best bet, i dunno if anyone has written a wrapper
21:14mlb-Doh. I should've remembered to check maven and friends
21:14mlb-thanks, benmoss
21:14benmosssure
21:14benmosshere's some example code using it i just found https://github.com/oakes/Nightweb/blob/master/common/clojure/nightweb/zip.clj
21:29dsrxzip is such an overloaded term
21:30dsrxfor 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:32mlb-or Haskell's zip?
21:33dsrxwell, that's what I was expecting
21:33mlb-ah, I was thinking of zippers
21:33dsrxyeah, and then there's that :P
21:41muhooit'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:42chouser_logwho's chris? ;-)
21:42muhooand chouser_log too :-)
21:43muhoograinger, and anthony, there was so much going on
21:43logic_progis there a way to tell lein "lein, update yourself"
21:44muhoologic_prog: lein updgrade
21:44muhooupgrade
21:44logic_prog$ lein upgrade Upgrades should be done using apt rather than Leiningen itself.
21:44muhoowat?
21:45charewhat is the difference between lein trampoline and lein run
21:45qbglogic_prog: You installed lein using apt?
21:46logic_progyeah
21:46muhoodidn't know you could do that.
21:46logic_progis that a bad thing?
21:46logic_progas in "sudo apt-get install leiningen"
21:46logic_progubuntu 13.10
21:46right1try apt-get install --only-upgrade <packagename>
21:46qbgIs that version out of date for you?
21:47logic_progI just manually installed lein
21:47logic_progeverything works now :-)
21:47muhooyou might want to uninstall the apt package if you're installing it manually
21:47right1what do you guys like for websockets in clojure? http-kit or adelph?
21:47logic_proghttp-kit
21:48logic_progthe author of http-kit is awesome
21:48logic_progi've filed bug reports on github issues, and he's responsded
21:48muhoohaven't tried http-kit, but done websockets stuff with aleph and it worked.
21:48n0n3suchi've been looking for someone who's used http-kit :)
21:48logic_progI use http-kit.
21:48logic_progIt's awesome.
21:48n0n3suchlogic_prog: experiences ?
21:49logic_progDamn it, I'm not sure what else I can do; it sounds like I'm selling http-kit stock.
21:49n0n3suchi tried hooking it up with compojure following the http-kit example and it didn't compile
21:49n0n3suchbut i'm a clojure noob
21:49logic_progbuy http-kit !
21:50logic_progsell bitcoin, buy http-kit
21:50muhoologic_prog: everyone has their programmign fanboi thing
21:50ddellacostawoah, I've never heard that about upgrading lein, in fact only the opposite.
21:50muhooi annoy people by telling them how awesome clojure, om, and datomic are
21:50n0n3suchsome kind of namespace problem
21:50benmossanyone 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:50logic_progmuhaoo: I like clojure, om, and datomic
21:50logic_progmuhaoo: admittedtly, http-kit is not as awesome as clojure/datomic, but possibly comparable to om
21:52mlb-benmoss: I use fireplace quite a bit. What do you mean "done"?
21:52muhooi expect that once i get further into core.async i'll be just as fanboi about that. so far i'm impressed.
21:52benmossmlb-: i can't evaluate any forms in that file
21:52benmossmlb-: when i 'cpp' the first line: https://gist.github.com/benmoss/9339442
21:53mlb-I've not worked with dataomic and friends, but as long as fireplace has an nREPL connection, things "just work" for me
21:53benmosshmm
21:54mlb-huh. that stacktrace is something I've not seen before
21:54benmossi have found i have problems whenever there's a file like this that has no ns and is just meant to be evaled
21:54benmossseems like just some vimscript error
21:55benmosseven just 'cqp'-ing (+ 1 1) yields the same stacktrace
21:55benmosssomething about it trying to create a new ns
21:56technomancylogic_prog: lein from apt-get is hopelessly out of date ATM; I'd recommend removing and installing by hand
21:56logic_progtechnomancy: already did that
21:57logic_progtechnomancy: 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:57logic_prog:-)
21:58technomancylogic_prog: if you want something that's up-to-date, you shouldn't be using apt-get to begin with
21:59technomancythe 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:00tolitiustechnomancy: is that something "lein possible": https://www.refheap.com/51402 ?
22:00charedo you guys use pulsar lightweight threads with clojure?
22:01technomancytolitius: yeah, lein templates can take arguments
22:01technomancytolitius: right now the composability story around templates isn't great, but simple flags and such are easy
22:02benmossmlb-: can you try this repo out? https://github.com/benmoss/fireplace-bug
22:02benmossjust eval the form in the file in examples
22:02tolitiustechnomancy: great! I could not find the how to on template arguments, is there a place I can dive in for more info?
22:04technomancytolitius: it should be fairly clear if you do `lein new template mytemplate`
22:04technomancyit spits out a template with a defn in it; just add more args to the defn
22:05tolitiusbenmoss: fyi: it works for my fireplace setup, e.g. gets evaluated to 2
22:05benmosshmm
22:06benmosstolitius: examples/wtf/bug.clj ?
22:06benmosslemme try updating and see if that fixes anything
22:07tolitiustechnomancy: 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:08technomancyit's clojure's motto
22:08technomancy"It's just a function"
22:08tolitiusbenmoss: no, "examples/wtf/bug.clj " will not work
22:08tolitiussince your source-paths are not looking there
22:09benmosssource-paths includes examples, shouldn't it?
22:09benmossmaybe i don't understand source-paths, i admit
22:09tolitiusbenmoss: why would you keep sources in "src" and in another dir that's not in "src"?
22:10benmossit's a common example i've seen to have some "example" code in another directory
22:10benmossala https://github.com/Datomic/simulant/blob/master/examples/repl/hello_world.clj
22:10tolitiusbenmoss: oh.. and you have no namespace there
22:11benmossyeah, it's meant to be just evaluable code, not a ns
22:11tolitiusbenmoss: that's your problem. add "(ns wtf.bug)" to the beginning of your "examples/wtf/bug.clj", and it will work
22:11noprompt_gawd. emacs indentation for ruby is awful...
22:12tolitiusbenmoss: I prefer to have "example" code under "test" if you must, but yes, I've seen this pattern around
22:13tolitiustechnomancy: 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:13tolitiustechnomancy: s/clojure template/lein template
22:14benmossnoprompt_: isn't ruby-mode.el maintained by Matz?
22:14muhoocan you nest {:keys []} inside {:keys ? i.e. {:keys {:keys [foo] :as params}} in a ring req?
22:14noprompt_benmoss: i dunno, but it's fucking horrible.
22:15noprompt_benmoss: i'm trying to return a hashmap in a case in a when clause and the map indentation is all hosed.
22:15muhooi'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:15tolitiusbenmoss: in order for it to be "evaluable code" it needs a namespace
22:15noprompt_i'll get in a bar fight over it: syntax is a *bad* idea.
22:15benmosstolitius: i thought fireplace tried to create a user ns if one was not declared or something like that
22:16technomancybenmoss: I don't think ruby-mode is maintained at all
22:17benmossok, *created* by? not as though that guarantees any kind of quality, just would have assumed
22:19tolitiusbenmoss: https://github.com/tpope/vim-fireplace/blob/master/doc/fireplace.txt#L118 yes, then you should remove "examples" from under "source-paths"
22:19tolitiusbenmoss: and it will work
22:20benmossah lemme try that
22:20tolitiusbenmoss: otherwise you _are_ putting it on the classpath, but don't specify the namespace, which is why it does not like it
22:21benmossindeed, it does work
22:24benmossthanks tolitius
22:25Nyyxso no libraries in clojure for bimaps?
22:26tolitiusbenmoss: sure, glad it helped
22:26sea-gullNyyx: there's a bimap in guava
22:26sea-gullwhich is available from clojure too
22:27tolitiusNyyx: will http://clojuredocs.org/clojure_core/clojure.set/map-invert work?
22:27NyyxI guess, but I'll have two maps
22:28Nyyxand I was hoping to serialize them so idk about guava
22:29tolitiusNyyx: but it is two indices one way or another
22:29tolitiusNyyx: *these are
22:31tolitiusNyyx: 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:32tolitiusNyyx: so I don't see why a simple map-invert won't work
22:41Nyyxtolitius: okay I was wrong
22:41NyyxI'll use map-invert
22:59Nyyxif 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:00bbloomNyyx: clojure doesn't do any common subexpression elimination optimizations beyond what the java vm will do at jit time (read; very simple ones)
23:01bbloomNyyx: so yes
23:02MattAbbottwhat optimizations does clojure do before hitting the jvm?
23:02bbloomMattAbbott: practically none at the source transformation level
23:03MattAbbottI see. Are optimizations just kinda low on the priority list right now?
23:03bbloomMattAbbott: they're simply not necessary in most cases
23:03Nyyxbbloom: what about if I use a let binding?
23:03Nyyxand put the map-invert in there
23:03bbloomNyyx: every time the let runs, the right side of the bindings will be re-evaluated
23:03Nyyxso I have to put it in a def?
23:04bbloomNyyx: if you've only got one map & one map invert, then yeah, put it in a def.
23:04bbloomNyyx: depending on your use case, you could manually memoize in some way
23:05Nyyxthe map stores user settings that could change
23:05Nyyxso eventually I was thinking of putting it into an atom?
23:05bbloomNyyx: may vary at startup? or can change at runtime?
23:05Nyyxruntime
23:06bbloomif you haven't measured and determined that it's too slow, i'd say ignore it
23:06Nyyxso 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:07bbloomNyyx: 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:08bbloomyour choice if you want/need eager or lazy recomputation
23:09bbloomNyyx: 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:09Nyyxbbloom: okay thanks
23:09Nyyxcleared up my confusion
23:17wei__is there a blocking sleep in javascript? would be nice for using inside a go block
23:18tolitiuswei__: take from a timeout channel?
23:18tolitiuswill block until the timeout is done
23:19wei__oh yeah, that'll work
23:22wei__didn't realize there's actually a timeout channel in the api- that's cool
23:25bbloomwei__: if you don't already know, be sure to check out various golang resources for how to utilize multiplexing and timeout channels
23:26wei__will do thanks bbloom
23:27munderwoHi all. has anybody played around with HTTP-kit?
23:28munderwoI 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:39devnDoes anyone use earmuffs still on their dynamic vars?
23:39dsrxmunderwo: 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:39devnOr is that old school at this point?
23:40dsrxmunderwo: the docstring for with-channel might be helpful
23:48munderwodsrx: so it grabs the web socket channel from the request headers? or from the middleware or something?
23:48minikomiI'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:55dsrxmunderwo: yeah, the actual socket is grabbed from the request in the expanded macro
23:55munderwodsrx: ahh ok. that makes sense. it looked like it was just appearing from no-where which was confusing. but makes sense now