#clojure log - Apr 11 2014

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

0:43 amalloy: reloading the protocol

0:43 (i mean, not really, but it would have symptoms that would make you think that's what happened, akhudek)

0:44 akhudek: amalloy: it turned out to be a slightly more subtle error with some custom nippy serialization routines :-/

0:44 thanks though

1:37 quizdr: 'sup fellas long time no SEE

2:04 jdeisenberg: clojure newbie here: is loop/recur more "morally pure" than (for [x (range 1 n)] ...)

2:04 in terms of functional programming, that is.

2:04 maxthoursie: jdeisenberg: no

2:05 jdeisenberg: aim for readability

2:05 jdeisenberg: if it's enough with for, go with it

2:05 jdeisenberg: if it would do with map, use that instead

2:06 jdeisenberg: and wrap it in a function with a good name if it gets hairy

2:08 jdeisenberg: Thank you. I'm also aiming for a lot of small functions rather than large complex ones.

2:12 OK; thanks again!

2:12 maxthoursie: you're welcome

5:46 myguidingstar: hi all, is there a naming convention for prototype functions that create an other function?

6:06 noidi: no

6:07 e.g. partial, fnil, comp, and some-fn all return new functions

6:54 dublindan: Hey everyone, I want to repeat each element in a vector twice ([1 2] -> [1 1 2 2] etc). I can do this with something like (apply concat (map (juxt identity identity) input-seq)). Is there a better way?

6:55 ok, just remembered mapcat :) (mapcat (juxt identity identity) input-seq)

6:57 clgv: dublindan: that's good. alternative: (mapcat (partial repeat 2) input-seq)

6:58 noidi: another way: (mapcat vector input-seq input-seq)

6:59 dublindan: Ah, perfect, thanks :)

6:59 clgv: (defn multiply [n input-seq] (mapcat (partial repeat n) input-seq)) :D

6:59 dublindan: That gives me a few alternatives to ponder :P

7:00 clgv: nice generalised solution, thanks

7:01 clgv: np

7:02 ,(count (mapcat repeat (range))) ; still countably infinite :D

7:02 clojurebot: #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>

7:02 clgv: not refering to the count function of course ;)

7:40 mercwithamouth: o_O

7:50 horizonal tabs/views aren't possible yet in light table are they?

8:57 scape_: i have added my uberjar to a java project and when I go to import intellij autocompletes the path I'm looking for, but when compiling it says my package does not exist

8:58 mikerod: I'm curious, why does a type created via `defrecord` (i.e. `emit-defrecord`) implement a non-caching variety of #hashCode and #hasheq?

8:58 I was hoping/expected that they would follow the hashing mechanism of APersistentMap impl of #hashCode and #hasheq

9:00 I know #hasheq for a defrecord-type takes into account the `type-hash` so that the type has a part of the resulting value, however, in the #hashCode impl for the defrecord-type, it seems to just impl the #mapHash, effectively skipping the caching mechanism of the internal _hasheq field.

9:01 So I'm just trying to wrap my head around the motivation for this. I think cached hashCode on defrecord-types would be a desirable feature.

9:06 Anderkent: so this is a long shot, but I read an article discussing OOP design based on a game with archers, cavalry, horse archers that nicely demonstrated increasing complexity... can't find it now :/

9:06 mdrogalis: Can't say I've seen it, Anderkent. :|

9:07 tbaldridge: Anderkent: I remember an article stating how StarCraft 1 almost didn't ship due to crappy OOP design.

9:07 mikerod: Anderkent: sounds interesting, give me a link and I'll read through it :P

9:24 scape_: i have added my uberjar to a java project and when I go to import intellij autocompletes the path I'm looking for, but when compiling it says my package does not exist

9:31 sm0ke: hello, i want to have a route in compojure which can set a urlpatten into a variable, how do i do that?

9:31 so i we used to have urlparam in jax-rs, something like that

9:31 ugh

9:34 jcidaho: hi, playing with clojure.jvm.tools.analyzer. I've noticed that when I call analyze-form-in-ns, it actually evaluates/executes the form I give it

9:34 is this by design or is there a way to prohibit evaluation?

9:36 tbaldridge: jcidaho: are you quoting the input form?

9:41 jcidaho: no

9:43 tbaldridge: I basically have some code as a string, and I'm doing edn/read-string on it, then passing it into analyze-form-in-ns

9:44 tbaldridge: okay, that's odd then

9:52 jcidaho: tbaldridge: I.e. calling (foo "(reset! a {:b :c})") against http://pastebin.com/RQLQMiTJ actually resets the atom a

9:54 Am I doing something wrong there?

9:59 bodie_: is it possible to run a cider REPL such that it's aware of identifiers defined in the project source?

9:59 i.e. I have two windows open, one in the main file, the other is a Cider nREPL

9:59 connected to Lein repl

9:59 ... that's probably obvious..

10:00 let's say I want to test my new function "foo"

10:00 why can't I just save my file, and say (foo) in the repl?

10:00 or... what would be necessary in order to do that?

10:01 clgv: bodie_: you can just send the "foo" definition to the repl via a shortcut

10:01 bodie_: I figured that out, but let's say it depends on other stuff from the project

10:02 can I simply (use <project main namespace>) in the repl?

10:02 clgv: usually there is a shortcut that sends the whole file to the repl

10:02 bodie_: hmm

10:02 ok

10:03 why can't I just (use foo.bar)

10:03 assuming the ns declaration in the main is (ns foo.bar <...>)

10:03 clgv: bodie_: you'd nee to specify :reload or :reload-all and that will work

10:04 bodie_: so like (use foo.bar :reload-all) ?

10:04 clgv: almost. (use 'foo.bar :reload-all)

10:05 bodie_: I see. works for me :D thanks much clgv!

10:06 clgv: bodie_: afair there might be inconsistencies when in more complicated setups. therefore the library tools.namespace was written to do a proper reload. just in case you experience problems

10:08 bodie_: I see. thanks :) all my "Choose this answer" are belong to you!

10:32 gfredericks: semvar clojure-style: ZERO.MAJOR.MINOR

10:33 semver*?

10:33 jcidaho: Anyone have an idea of how to safely use jvm.tools.analyzer? I've found calling (foo "(reset! a {:b :c})") against http://pastebin.com/RQLQMiTJ actually resets the atom a

10:34 gfredericks: jcidaho: avoiding top-level side effects is pretty useful in general

10:37 jcidaho: So you can run the analyzer against code strings that when evaled may have side effects?

10:37 I just want to analyze code without actually executing it

10:37 *so you can't*

10:39 gfredericks: I don't know for sure; can you wrap your code in a function before analyzing?

10:54 oskarth: I've defined and sourced environment variables in .bashrc, but when I do (System/getenv) in my (restarted) repl I don't see it. What's wrong?

10:56 mpenet: oskarth: did you do "source ~/.bashrc" ?

10:56 oskarth: mpenet: yes

10:56 fresh terminal and echo $foo works. Running a fresh repl in emacs using nrepl-jack-in

10:57 jconnolly: i'm guessing because lein is a non-interactive shell script?

10:58 oskarth: jconnolly: what does that mean and what do I have to do to get it to read envs correctly?

10:58 mpenet: you need to use something like https://github.com/purcell/exec-path-from-shell I think

10:59 oskarth: using emacs from the terminal if that makes a difference

10:59 mpenet: I do, and I don't have your issue, hopefully this fixes this

10:59 ah

11:00 try to echo the var from eshell, just to see the result, but I guess this is related

11:00 oskarth: I restarted emacs and now it works :)

11:00 Anderken1: >restarted emacs

11:00 blasphemy!

11:00 oskarth: haha

11:00 Anderken1: :P

11:01 oskarth: so just restarting nrepl doesn't do it. But I'm sure there's a way update it in emacs?

11:02 could use setenv and do it twice as a hack I guess

11:03 mpenet: or source from eshell maybe

11:03 jcidaho: gfredericks: good idea I'll do that

11:03 just would've thought you could analyze without running

11:03 oskarth: mpenet: that's where I did it the first time :/

11:04 `szx: ,(clojure.set/union #{1 2} (take 1 #{1 2 3}))

11:04 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set>

11:04 `szx: hmm

11:04 ##(clojure.set/union #{1 2} (take 1 #{1 2 3}))

11:04 lazybot: ⇒ #{1 2}

11:04 oskarth: maybe nrepl inherits directly from emacs session? so it's not affected by shell session

11:04 `szx: ##(clojure.set/union #{} (take 1 #{1 2 3}))

11:04 lazybot: ⇒ (1)

11:04 `szx: am i the only one who find this strange?

11:05 gfredericks: jcidaho: there are two analyzer libs -- jvm.tools.analyzer uses the builtin compiler's analyzer, and tools.analyzer.jvm uses the separate tools.analyzer lib. the latter might be easier to work with; it's worth checking out at least

11:06 `szx: you're calling a set function with a seq, so anything strange is hard to complain about

11:06 but this seems to make sense to me in any case; you end up conj'ing 1 onto the first set in both cases

11:06 jcidaho: gfredericks: will do cheers

11:06 `szx: gfredericks: yeah, i was pleasantly surprised when i found out it worked - if it's not consistent then it just shouldn't, no?

11:07 gfredericks: `szx: well what you're doing is presumably dependent on the seq ordering of #{1 2 3} which is a shady thing; but in an awful lot of cases clojure does not check for bad input

11:07 so what you're observing is pretty consistent with the rest of clojure.core

11:08 `szx: gfredericks: so you would consider that a undocumented/unsupported scenario

11:08 gfredericks: definitely

11:08 ,(doc clojure.set/union)

11:08 clojurebot: excusez-moi

11:08 gfredericks: &(doc clojure.set/union)

11:08 lazybot: ⇒ "([] [s1] [s1 s2] [s1 s2 & sets]); Return a set that is the union of the input sets"

11:09 gfredericks: ^ it expects args to be sets

11:09 (into some-set some-collection) might be what you actually want?

11:10 `szx: well, i just needed to take a number of items (don't care which) from one set and add them to another

11:11 gfredericks: (into some-set (take n other-set)) is good then

11:12 `szx: hmm, cool

11:12 is there any advantage to s/union over into then?

11:13 gfredericks: knowing the current codebase I'd say s/union is probably slower

11:13 Anderkent: `szx: union will decide which set is larger and put the smaller into larger

11:14 which is faster than larger into smaller

11:14 `szx: got it

11:14 gfredericks: though into uses transients

11:14 `szx: probably not that important for the set sizes i'm working with

11:14 Anderkent: right, i guess for sets of similar size into will be faster

11:15 gfredericks: someday clojure.core/set will use transients too

11:15 hyPiRion: gfredericks: you are quite the optimistic one :p

11:16 gfredericks: I already patched it

11:16 hyPiRion: oh hurray

11:16 gfredericks: so in about a year

11:17 hyPiRion: gfredericks: how long ago did you send in the patch?

11:17 gfredericks: a month or so ago

11:17 too late for 1.6

11:17 if it's not in 1.7 I'll be mildly grumpy

11:18 * hyPiRion still waits for the bugfix for cl-format I submitted Dec. 2012 to be patched in

11:19 gfredericks: hyPiRion: are you competing for oldest patch?

11:19 hyPiRion: gfredericks: In fact no =(

11:20 gfredericks: but if you want to win you should vote up CLJ-1134

11:20 gfredericks: I've never once used cl-format

11:22 hyPiRion: but how can you not? It makes stuff so readable. https://github.com/hyPiRion/snigilbot/blob/675c04e1fec0af762565e719a2bb08bf4c7c4e81/src/snigil/io_utils.clj#L62-L66 for example

11:22 llasram: *snork*

11:22 ambrosebs: gfredericks: where is set transient patch?

11:22 seancorfield: hyPiRion: I think that page has been corrupted - there's a bunch of line noise near the bottom :)

11:23 gfredericks: hyPiRion: I'm not even going to follow that link

11:23 hyPiRion: (inc seancorfield)

11:23 lazybot: ⇒ 12

11:24 gfredericks: ambrosebs: http://dev.clojure.org/jira/browse/CLJ-1384

11:29 ambrosebs: gfredericks: can you post your benchmark code?

11:29 bbloom: hyPiRion: eery time i see a cl format string, i think it must be a joke

11:29 like, there's no way that does anything

11:29 that's just somebody holding shift and banging on the top row of their keyboard

11:29 gfredericks: ambrosebs: hrm

11:30 seangrove: bbloom: It's an impressive DSL

11:30 gfredericks: ambrosebs: I'm sure it was a one-liner

11:30 bbloom: seangrove: i'm sure it is, but i rather code to it's AST :-P

11:30 seangrove: The fact that I can recursively destructure maps to roman numerals interposed with the pluralized version of .....

11:31 gfredericks: ambrosebs: oh I found it!

11:31 seangrove: bbloom: It's impressively write-only, from my experience

11:31 But then again, long time CLispers say it's fine, so what do I know

11:31 gfredericks: http://upload.gfredericks.com/ambrose.clj

11:31 bbloom: seangrove: one of these days i need to really take a crack at the extensibility part of fipp

11:31 hyPiRion: bbloom: haha, it's really powerful, but it's important to not go overboard

11:31 bbloom: seangrove: i'll add roman numerials support to a numbered list element

11:32 just for you guys

11:32 gfredericks: bbloom: I've been meaning to write an email to clojure-dev about global extension points; I think fipp is more flexible in that regard?

11:32 seangrove: bbloom: Get it working well in cljs first ;)

11:32 gfredericks: compared to print-method or cheshire

11:33 bbloom: seangrove: i'm taking the long route to CLJS support...

11:33 gfredericks: global extension points is something that clojure is merely better than average at

11:33 needs an "obviously how this should work" idea

11:33 gfredericks: bbloom: it falls down when composing libraries though

11:33 bbloom: yes

11:34 gfredericks: and I don't know a workaround at the moment besides forking the extendable libraries or something

11:34 seangrove: bbloom: Outsourcing it, or rebuilding the entire computing infrastructure from the ground up until cljs support just 'falls out'

11:34 ?

11:34 bbloom: seangrove: you clearly know the answer to that one, lol

11:35 * seangrove mutters 'there but for the grace of god....'

11:35 bbloom: but yeah, my plan is to provide a JS backend for eclj sooner rather than later, which will be much more pleasant than cljsx or any feature-expressions like idea

11:37 i have this crazy idea that i'll be able to "compile" a fipp function to generate an efficient non-pretty print function

11:37 among my many other crazy ideas :-)

11:37 clojurebot: Cool story bro.

11:37 seangrove: I was wondering about that

11:38 bbloom: i'm tired of doing things 10 times for various performance/functinality targets

11:56 ambrosebs: bbloom: I like that David still remembers you recommending React to him (latest Cognicast)

11:57 bbloom: ambrosebs: i appreciate the recognition, but at this point, Om is all his baby, he's done a ton of work on it :-)

11:58 hyPiRion: ambrosebs: He did it at the thoughtbot podcast as well

11:59 http://podcasts.thoughtbot.com/giantrobots/93 ← there

11:59 ambrosebs: bbloom: I just find it funny that he didn't really look at React until later, but still remembers your mention (or so I understand)

11:59 another one of bbloom's crazy ideas

11:59 :)

12:00 bbloom: ambrosebs: i bugged him about it for months, no way he could have forgotten ;-)

12:00 ambrosebs: ahaha

12:00 yep sounds right

12:02 bbloom: how do i get on these fancy pants podcasts? :-P

12:03 hiredman: I imagine you need some fancy pants

12:03 wink: which react I might ask?

12:03 hyPiRion: wink: FB's react

12:03 * bbloom heads to amazon.com to acquire some fancy pants

12:03 hiredman: clojurebot: pants |are| overrated

12:03 clojurebot: Ack. Ack.

12:03 wink: hyPiRion: ah thx.

12:04 technomancy: hiredman: it *is* friday

12:04 hyPiRion: bbloom: Hmm, you never been on the Cognicast? I thought you had

12:04 bbloom: nope

12:04 wink: hyPiRion: https://www.youtube.com/watch?v=kfVsfOSbJY0 ? :)

12:04 hiredman: technomancy: right, it isn't even dress for success monday

12:05 wink: I thought it was "pizza and beer" monday :(

12:05 hyPiRion: wink: I think that one was for technomancy, amirite?

12:06 wink: hyPiRion: you stressed friday

12:06 oops sorry

12:06 hyPiRion: you are right!

12:06 technomancy: no-pants friday, everyone[1]!

12:06 wink: > I do find it strange that an SSL vulnerability that has existed for 2 yrs is brought to the world the same week that WindowsXP support stops, along with microsoft Essentials support… I think this elaborate marketing genius might be brought to you by our good friends at Microsoft

12:06 technomancy: [1] - everyone who works from home

12:06 wink: I like that guy

12:07 Anderkent: technomancy: isn't every day no-pants friday if you work from home?

12:07 wink: technomancy: I have to disappoint you, home office days do include pants over her

12:07 technomancy: Anderkent: sure; Friday is just the ancient tradition

12:07 Anderkent: >pants over her

12:09 tim__: Anderkent: I assume that's a typo for "here", otherwise that's a quite creepy comment...

12:10 wink: don't judge me by my misspellings :(

12:10 and I don't get why it would be creepy instead of totally nonsensical

12:10 hyPiRion: over her what?

12:10 wink: is "pants over someone" a thing?

12:11 hyPiRion: Oh right

12:11 wink: pants also means "to pant", with may be a bit creepy

12:11 like breathing

12:12 justin_smith: pants can also mean "crazy" or "messed up"

12:12 so you could be pants over someone

12:12 wink: hyPiRion: true, but that sounds grammatically weird :P

12:12 justin_smith: ah thanks

12:12 jcidaho: gfredericks: thanks about early - I switched analyzer lib and got the behavour I expected

12:12 hyPiRion: wink: sure thing, it sounds really strange :p

12:15 solidus_: going over how clojures stm works - can't i get a transaction stuck in a livelock if it is constantly interrupted?

12:15 hyPiRion: solidus_: it will throw an exception after some limit

12:16 solidus_: interesting, this really limits the scope of what you can do in dosync

12:17 hyPiRion: solidus_: happens very infrequently though. I think it manages to avoid starvation and "livelocks", so I'm not sure when it will actually throw

12:18 justin_smith: solidus_: if the system has the kind of throughput where that happens, you should probably be using a contiguous ringbuffer instead of persistent objects anyway

12:18 or at least some kind of queue

12:19 hyPiRion: justin_smith: or an agent?

12:19 justin_smith: well, maybe there is a space in between performance wise, I was describing the kind of stuff they use for hft

12:19 which is where you would get massive throughput and livelocks

12:20 *massive attempted throughput

12:22 hyPiRion: Q: Imagine I've found a way to speed up some part of clojure.core significantly. How would I go forward showing that it actually is faster, and how likely would it be that it will be accepted?

12:22 justin_smith: have you signed the whatchamacallit?

12:22 Anderkent: hyPiRion: make up benchmarks, that's what everyone does to show their approach is faster! /s

12:23 technomancy: stu seems to really like the debian benchmarks

12:23 alioth or whatever

12:26 jonasen: dnolen_: I've been looking at cljs multimethod performance. Seems like getting rid of apply in both (apply dispatch-fn args) and (apply target-fn args) might result in a big perf boost. Is this something worth pursuing or do you have better suggestions at making multimethods faster?

12:27 gfredericks: ambrosebs: I'm curious what the purpose of adding the second benchmark was -- just getting a second data point? or is there a difference I missed?

12:29 ambrosebs: gfredericks: second data point. Shall edit.

12:29 gfredericks: k cool

12:30 hyPiRion: technomancy: so the benchmarks game?

12:31 technomancy: I guess; maybe

12:31 gfredericks: ambrosebs: ha you got alex's attention

12:31 technomancy: I'm not someone who has had a lot of luck getting patches applied, so don't listen to me

12:32 hyPiRion: technomancy: Guess that makes two of us

12:33 gfredericks: are we still talking about pants? patching pants with holes in them?

12:33 do I need to get stu's approval to fix my pants?

12:33 Anderkent: only on no pants friday

12:33 otherwise you interacting with pants might trigger alerts

12:34 * gfredericks tries to see how far the codebase-as-pants metaphor goes

12:34 * bbloom comes back to see that his random mention of fancy pants sparked an epic tangent

12:34 Anderkent: do you even have write access to the pant repository?

12:34 hyPiRion: gfredericks: problem with pants is that good ones generally only have two branches

12:34 actually one branch

12:35 Anderkent: eh? it's clearly development and staging branching off master

12:35 hyPiRion: or two? Now I'm confused.

12:35 gfredericks: clojurebot: bbloom is a pantsologist

12:35 clojurebot: Ok.

12:35 dnolen_: jonasen: that sounds like an awesome first step!

12:35 bbloom: dammit.

12:35 gfredericks: now i need to write a talk about pants

12:35 hyPiRion: bbloom: looking forward to that

12:35 gfredericks: that was my goal

12:35 hyPiRion: (inc gfredericks)

12:35 lazybot: ⇒ 48

12:36 dnolen_: jonasen: patch welcome, would be nice to see some numbers. But yeah getting rid of apply should be a decent boost.

12:36 ambrosebs: gfredericks: ha :)

12:36 tbaldridge: dnolen_: have you seen a problem with CLJS where the compiler tries to treat a macro like a function?

12:36 gfredericks: bbloom: pants look like a tree under the normal orientation

12:36 bbloom: gfredericks: they've even got a zipper!

12:37 tbaldridge: dnolen_: as in it emits a macro.call instead of running macroexpand?

12:37 dnolen_: tbaldridge: no, that only happens if it can't find the macro, or you didn't namespace your macro properly.

12:37 tbaldridge: writing macros in CLJS generally means fully qualifying everything, since macro symbol resolution is in Clojure *not* ClojureScript

12:37 hyPiRion: bbloom: Those zippers are hard to use though. Only up and down are implemented

12:38 dnolen_: huge source of lameness - hopefully to be addressed w/ tools.analyzer switch

12:38 gfredericks: I bet whoever wrote that backtick lib could adapt it to make cljs macros easier

12:38 tbaldridge: dnolen_: this might be related, but is it possible to have this work in cljs? (ns foo (:require-macros [foo]))

12:38 bbloom: gfredericks: i've already told dnolen to feel free to copy/paste it in to the cljs source

12:39 dnolen_: tbaldridge: hmm, never tried something like that before.

12:39 tbaldridge: Seems like that might trip up the compiler, (two files with the same name, one .clj, the other .cljs)

12:39 yeah, I was afraid of that.

12:39 dnolen_: bbloom: rather have it solved in the analyzer since that's where we're going.

12:39 bbloom: dnolen_: it's a reader feature

12:39 gfredericks: should it be?

12:39 dnolen_: tbaldridge: no that shouldn't matter

12:40 tbaldridge: that's how :include-macros and :require-macros works

12:40 gfredericks: having the reader dependent on *ns* is pretty weird

12:40 bbloom: gfredericks: agreed, but it's also true of ::

12:40 jonasen: dnolen_: I'll see what I can do. Is there any point in implementing IFn's (-invoke ..) methods. I seem to recall that you once said that IFn is basically a lie in CLJS

12:40 gfredericks: bbloom: oh that's a lot tricksier to fix

12:40 bbloom: gfredericks: sadly, there is no runtime representation of :: keywords

12:40 dnolen_: jonasen: IFn works now

12:41 jonasen: I think you just need to tag ^not-native

12:41 and it will do a direct dispatch to the right arity

12:41 jonasen: dnolen_: cool. MM doesnt use them so that could be a first step

12:41 dnolen_: bbloom: ah right

12:41 jonasen: definitely, that would be a giant boost

13:03 coventry: Heh, "UnsupportedLookAndFeelException"

13:06 justin_smith: coventry: as opposed to the "YouCanLookButNotTouchException"

13:10 hyPiRion: you will find punk generalizes the pants zipper http://bit.ly/1kdHPkW

13:15 hyPiRion: heh

13:20 jonasen: dnolen_: it's looking good. The multimethods benchmark dropped from 248msecs to 23msecs :)

13:20 bbloom: jonasen: nice.

13:20 dnolen_: jonasen: excellent

13:32 justin_smith: I'm looking for resources / info comparing pig and clojure-hadoop (or even using them together)

13:33 http://techblog.netflix.com/2014/01/introducing-pigpen-map-reduce-for.html extra info about pigpen would be especially interesting

13:35 hiredman: justin_smith: to muddy the waters further parkour (clojure hadoop library) is pretty nice

13:35 justin_smith: cool! thanks

13:36 tbaldridge: justin_smith: did you see the ClojureWest talk?

13:36 justin_smith: no, I will look for that too

13:37 tbaldridge: justin_smith: https://www.youtube.com/watch?v=drzMkklC05U&list=PLZdCLR02grLp__wRg5OTavVj4wefg69hM

13:37 hiredman: I had never done use hadoop before, but after 1.5 to 2 days futzing with parkour and elastic map reduce I had it cranky and getting the data I needed

13:37 justin_smith: tbaldridge: the cascalog one?

13:37 tbaldridge: justin_smith: No, that's pigpen from NetFlix.

13:38 llasram: hiredman: Oh, hey! Glad you had a good experience.

13:38 tbaldridge: justin_smith: Rich was ranting about how nice pigpen's "just pure clojure" approach was. No datalog, etc. Just seq like functions that happen to work as Hadoop jobs

13:38 hiredman: llasram: me too :)

13:38 llasram: hiredman: LMK if you ran into any rough edges. I'm looking to improve the documentation and interfaces a bit

13:38 justin_smith: tbaldridge: yeah, that does sound very good

13:40 hiredman: llasram: a lot of the rough edges were emr, not parkour, I had sort of test runs going locally using parkour real quick, but getting on emr, and figuring out how to feed inputs and where to read outputs, etc was a pain

13:40 llasram: justin_smith, tbaldridge: Honestly, my mind kind of rebels at such enthusiasm for a system which compiles a Clojure-like language to Pig. Unless I've misunderstood it

13:41 justin_smith: is there a demo project that uses the aws open datasets? that seems like a nice way to introduce stuff and show it working with a low barrier to entry

13:42 maybe that's something I could do as an exercise

13:42 llasram: hiredman: Ah, yeah. There's a lot of tribal knowledge of The Hadoop Way which is not always made sufficiently explicit

13:43 justin_smith: Oh, noticed your original question. Parkour is somewhat philosophically similar to clojure-hadoop, but is up-to-date, more complete, and more Clojure-ish

13:44 justin_smith: cool

13:44 llasram: justin_smith: And I've got a blog post on working interactively w/ it on an Amazon public dataset: http://blog.platypope.org/2014/2/8/interactive-hadoop-with-parkour/

13:44 justin_smith: this is definitely a great start, maybe I can try to sum it up in a blog post or something as I get started, thanks abain all

13:44 *again

13:51 TravisD: Would you guys mind dumping your twitter usernames so that I can make a list and follow you all?

13:53 technomancy: TravisD: it would be cool to just assume IRC nicks map to twitter usernames, build up a graph, and do some kind of follower analysis on it to weed out false positives.

13:53 llasram: oooh

13:54 bbloom: it's times like these that i wish for a nebulous tuple store of "shit the world wants the rest of the world to know"

13:54 i just wanna datalog query the internet

13:54 technomancy: bbloom: you don't use wikipedia for that?

13:54 TravisD: technomancy: Hehe, sounds like a fun project. Could probably even detect some usernames that were slightly different, by looking at the follower graph and comparing based on hamming distance or something

13:54 pjstadig: probably better to just seed with a couple of good clojure twitterers and then find a clique through follower analysis

13:54 technomancy: https://en.wikipedia.org/wiki/List_of_Clojure_Users_on_Twitter

13:54 hiredman: bbloom: so, like, freebase?

13:54 bbloom: technomancy: i tried, but the association between my IRC & twitter handles was deemed "not noteworthy"

13:54 pjstadig: bbloom: rdf

13:55 semantic web!

13:55 hyPiRion: TravisD: and possibly by interactions on IRC channels

13:55 TravisD: hehe yeah

13:55 bbloom: hiredman: pjstadig: eh, freebase & rdf are cool, but not quite there yet

13:55 TravisD: there's also the IRC interactions graph, which is weighted by frequency or something!

13:55 hyPiRion: ^

13:55 hyPiRion: mhm

13:56 perhaps also mine github, facebook, G+ and so on while you're at it

13:56 justin_smith: technomancy: [this may not meet the notability guidelines] [citation needed]

13:57 TravisD: This is starting to sound like one of those new fangled social networking data mining research projects

13:57 hiredman: foaf it up in here

13:59 bbloom: licensing question for you guys: what's the right protocol if i want to copy paste individual or groups of functions in to my code?

14:00 i don't want assign copyright to all the code to rich hickey... at least not yet....but i want to properly preserve copyrights/notices/etc

14:00 justin_smith: bbloom: what licenses?

14:00 bbloom: sorry, i'm copy/pasting out of clojure.core :-)

14:00 taking a handful of functions, making small edits to some, replacing others, using some wholesale

14:02 amalloy: bbloom: https://www.eclipse.org/legal/eplfaq.php#SRCREDIST might be relevant?

14:02 bbloom: amalloy: yeah, saw that, but i'm not sure what that means practically

14:03 amalloy: copyright doesn't matter much for your case, i think, because rich has "given you" a license

14:04 justin_smith: I think: you have the right to copy it and redistribute as part of epl code, but if someone steals it from your version, Hickey is the one with copyright who has the right to take legal action?

14:04 bbloom: i know i *can* use it, but i'm not sure *how*. specifically, do i just put a EPL notice in my code and say "some portions of this code copyright Rich Hickey, the rest copyright Brandon Bloom" ?

14:06 arav93: Hi, does anyone know why ArityException occurs?

14:06 technomancy: bbloom: © 200x-2014 Rich Hickey, Brandon Bloom should be fine

14:06 ToxicFrog: arav93: read the rest of the error message?

14:06 Usually it means you called a function with the wrong number of arguments.

14:07 bbloom: technomancy: isn't that ambiguous though? that implies to me joint copyright, rather than different parts having individual rights holders

14:07 ToxicFrog: ,(let [f (fn [] 0)] (f 1))

14:07 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/eval25/f--26>

14:07 arav93: Yes, that's what happened.

14:08 I'm trying to work on parse-timestamp in clojure,instant namespace.

14:08 I'm not able to get it to work.

14:08 gfredericks: clojure.org/lisps is slightly outdated

14:09 I forget where you're supposed to whine about those pages

14:09 hiredman: the internet

14:09 sqldier: arav93: you've got to figure out how many args to pass - no getting around it

14:09 ToxicFrog: arav93: 'not able to get it to work' as in....?

14:10 arav93: I read the code and it requires 10 args.

14:10 I passed it , still it refuses to work.

14:10 justin_smith: arav93: have you tried using clojure.repl/doc to see the argument signature? or looked at the source?

14:10 stuartsierra: gfredericks: email to clojure-dev

14:10 amalloy: gfredericks: i think you're supposed to be able to ask someone to give you edit permissions, and then you fix it

14:10 technomancy: bbloom: the new file is a single derivative work of the old afaik

14:10 gfredericks: stuartsierra: cool thanks

14:10 bbloom: technomancy: meaning that i become the rights holder of that file?

14:10 technomancy: or it stays rich?

14:11 technomancy: bbloom: there isn't one rights holder

14:12 bbloom: technomancy: *shrug* ok i don't understand this super well, but i'll assume that a friendly notice will do & it's unlikely rich et al will sue me

14:12 :-)

14:12 justin_smith: arav93: it has two args

14:12 zanes: technomancy: Do you still use lein difftest?

14:12 arav93: Two args?

14:12 justin_smith: arav93: it is defined oddly in that it is an fn inside a let, rather than a defn

14:12 zanes: Or is there some new hotness I should switch to?

14:12 hiredman: gross

14:13 justin_smith: arav93: from the source (fn [new-instant ^CharSequence cs] <- that is the fn that gets bound to parse-timestamp

14:13 two args

14:14 arav93: Ok, but how would I call it?

14:14 justin_smith: the second arg should be a string that the re can parse

14:14 (that one called timestamp in the let)

14:15 the first arg is a function you provide that will be passed in the parsed result

14:15 try "vec" first to see what comes back, I'd say

14:15 err, I mean vector

14:15 arav93: vec?

14:16 justin_smith: or list

14:16 if you pass in list as the first arg, it will give you a list of all the things it would pass to your function

14:16 then you can define the function you would really want to pass in

14:16 technomancy: bbloom: it's really only relevant if you want to change the license or go after infringers

14:17 zanes: I use it a bit, yeah

14:17 aciniglio: Using core.async, is there an idiomatic way to apply a function to a channel, but not care about the order? (if for example the operation can sometimes take a long time)

14:18 bbloom: technomancy: my only concern is that i'm likely to develop some library code that will live in the same repository, but be entirely independent of the clojure bits, so i want to retain all rights/etc on those parts.

14:18 justin_smith: ,(do (require '[clojure.instant :as i]) (i/parse-timestamp list "1977")) ; arav93

14:18 aciniglio: something like (defn mymap [f in] (let [out (chan)] (go (while true (let [m (<! in)] (go (>! out (f m)))))) out))

14:18 clojurebot: (1977 1 1 0 0 ...)

14:19 aciniglio: Using core.async/map< yields a channel that preserves order, so it will block the channel

14:19 justin_smith: arav93: look at the list that comes out, and based on that write the timestamp generator function you would want to pass in

14:19 bbloom: technomancy: https://github.com/brandonbloom/eclj#license seems like that should cover it

14:19 justin_smith: arav93: or just use list or vector as your new-instant function, and then pull out the fields you want as you need them

14:20 hiredman: aciniglio: if your function is potential blocking (read takes a long time) maybe use thread instead of go

14:21 arav93: thanks justin_smith

14:21 justin_smith: np

14:23 jonasen: dnolen_: does -invoke support varargs?

14:23 aciniglio: hiredman: yeah, thats a good point (defn mymap [f in] (let [out (chan)] (go (while true (let [m (<! in)] (thread (>!! out (f m)))))) out))

14:25 Is there a better name for what that operation is doing? Maybe apply?

14:27 hiredman: aciniglio: I've fiddling with https://gist.github.com/hiredman/10489794 which basically composes a bunch of mapcat style functions and channels for you

14:30 aciniglio: hiredman: nice! that makes a lot of sense

14:39 ambrosebs: Bronsa: can you start a change log for tools.analyzer?

14:41 hiredman: aciniglio: it is not ideal yet, it needs some kind of limiting of the number of tasks then are spun up, not just a limit on the number of tasks in channels between stages

14:42 er, items in the channels

14:43 gfredericks: could you pipeline a bunch of operations by just interleaving calls to seque and map?

14:43 hiredman: seque is super gross and sequence based, but I don't really care about ordering

14:45 gfredericks: grossness level: super

14:46 ,(->> (range 100000) (map inc) (reduce +))

14:46 clojurebot: 5000050000

14:46 gfredericks: ,(->> (range 100000) (map inc) (seque) (reduce +))

14:46 clojurebot: Execution Timed Out

14:46 gfredericks: hiredman: I'll take that as a "yes" ;-)

14:47 oh wait

14:47 my question was interpreted in context wasn't it

14:47 sorry I didn't realize you guys were talking about something related :P

14:47 hiredman: huh?

14:47 gfredericks: you were talking about channels and such

14:47 amalloy: gfredericks: seque is a funny one. try (dorun (seque (range))) in your repl

14:48 gfredericks: amalloy: I tried it! where are the jokes!

14:48 amalloy: gfredericks: give it a couple minutes. you'll run out of memory

14:48 gfredericks: oh that's a good joke

14:49 amalloy: and what's taking up all your memory won't be the integers from 0 to infinity!

14:49 gfredericks: that *does* sound super gross

14:49 amalloy: it'll be lambdas that the agent inside seque is planning to run eventually

14:49 hiredman: blech

14:49 gfredericks: wtf

14:50 I can't even imagine why that might be the case

14:50 hiredman: < hiredman> seque is super gross

14:50 gfredericks: why does it even use an agent?

14:50 hiredman: I think it predates futures?

14:50 gfredericks: is there a cleaner way to write this function?

14:50 amalloy: gfredericks: each time you take an item from a seque, it sends the agent an action to refill-if-necessary

14:51 gfredericks: oh and the agent is still busy filling it the first time?

14:51 amalloy: each refill-if-necessary task refills as much as it can, so if you're consuming faster than you're producing, that first task goes forever

14:51 right

14:52 flatland/useful has two alternate implementations of seque: https://github.com/flatland/useful/blob/develop/src/flatland/useful/seq.clj#L289-L363 - neither is perfect, but they make different tradeoffs

14:52 actually i think the second one, seque*, is what's in core now; my patch for that got accepted

14:53 anyway i gotta go to lunch, now that i've confirmed hiredman's allegation that seque is gross

14:53 gfredericks: hey thamks

14:54 hiredman: and even if it wasn't gross, it is based on seqs, which are linear, which may as well be unstructured data for parallel processing

14:55 O(n) will eat your parallelism

14:55 gfredericks: the case I'm in is sort of inherently linear

14:55 intested in*

14:56 reading paged data from a remote server

14:56 hiredman: ah

14:56 gfredericks: and I was just interested in ensuring that the reading didn't stop while I'm writing stuff elsewhere

14:58 hiredman: I suppose that would match seque's api well

15:04 gfredericks: if the api let you ask for a list of page ids (which would be smaller and require less parsing then a singe page in theory) and then you can ask for each page via id, it is now random access instead of linear, so you can parallelize it all (but of course it is most likely sorted data, and an api you don't ahve control of, so foo)

15:12 gfredericks: when I type 1000 in emacs, autocomplete mode suggests 1000, 10000, 100000, and 1000000

15:13 hiredman: it's a gray area actually; the page ids are apparently easy to infer, but I think formally they're supposed to be opaque and you can only get the next one

15:14 would be interesting if the next-page-id comes early in the response...

15:14 hiredman: gfredericks: or on a head request

15:15 gfredericks: yeah; I could imagine it blowing up if we requested in parallel though

15:15 it blows up under virtually every other circumstance

15:15 hiredman: heh

15:26 jonasen: dnolen_: is this a bug in cljs: https://www.refheap.com/75049

15:27 dnolen_: jonasen: IFn doesn't support rest args

15:27 er protocol fns rather

15:28 jonasen: dnolen_: https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L1050

15:28 dnolen_: jonasen: that's a horrible hack which should not be used a reference for anything

15:28 like String.prototype modification before it

15:28 it's not supported

15:29 jonasen: dnolen_: heh. understood

15:41 bbloom: Bronsa: does tools.reader offer a convenient for-form-in-file helper function?

16:05 miseria: "disfruto como pasajero de la capsula terrestre, los ranchos viejos de paris o roma no son mas lindos que los que veo aqui" bienvenidos: http://castroruben.com *temo_a_un_ser_sin_rival*

16:06 jonasen: dnolen_: http://dev.clojure.org/jira/browse/CLJS-795

16:08 Bronsa: bbloom: not sure what you mean about for-from-in-file

16:08 bbloom: for-form-in-file rather

16:08 Bronsa: right, typo

16:08 bbloom: i want a lazy seq of forms until eof

16:09 i'm doing loop/recur right now

16:09 Bronsa: oh, no there's no helper for that

16:09 bbloom: Bronsa: unused parameter recursive? on this line: https://github.com/clojure/tools.reader/blob/0503239d5ca433756147689726f936e29eecbef7/src/main/clojure/clojure/tools/reader.clj#L731

16:09 Bronsa: bbloom: yeah I know it's for compatibility with c.c/read

16:10 bbloom: ok

16:10 Bronsa: recursive? is a no-op in c.c/read too

16:10 bbloom: blargh haha

16:15 Bronsa: what's the correct procedure to create a indexing/pushback/input-stream reader for a source file?

16:16 (-> stream input-stream-reader (indexing-push-back-reader 1 path))

16:16 amalloy: bbloom: the unused "recursive?" is for "compatibility" with common lisp's read, by the way

16:16 bbloom: ^^ that doesn't seem to work, gives me: No implementation of method: :unread

16:16 amalloy: weee software archeology

16:17 Bronsa: bbloom: indexing-push-backp-reader expects a pushback reader of sorts

16:17 I should probably update the docstring

16:17 bbloom: Bronsa: yeah, these doc strings don't tell me much

16:17 Bronsa: what's the point of the "1" if it's not going to create a buffer for me?

16:18 Bronsa: bbloom: replace input-stream-reader with input-stream-push-back-reader and it should work

16:18 bbloom: the ctor functions fallback to a string-reader, otherwise they just assume you did the right thing

16:19 bbloom: Bronsa: ok. *seems* to work

16:19 Bronsa: so if you give the function a string, it's going to create a string-push-back-reader with a 1-sized buffer

16:19 bbloom: i get an error from my code now, so that's a start ;-)

16:19 thanks for the help. i'll let you know how it goes

16:20 Bronsa: bbloom: yeah sorry again for the confusion. I've been meaning to "fix" that situation for some time but never found the time. I'm opening a ticket for that so I won't forget

16:20 bbloom: still easier to use than LispReader :-)

16:26 dnolen_: jonasen: looks good, all tests pass I presume?

16:28 jonasen: dnolen_: yes, but I have only V8 installed. I also tried it on some personal projects and it seems to work

16:29 dnolen_: jonasen: k will give it a spin later.

16:30 jonasen: thanks much!

16:33 ivan: how do I annotate something as a primitive byte array to fix a reflection warning?

16:34 Bronsa: ivan "B];" IIRC

16:34 ,(class (byte-array 0))

16:34 clojurebot: [B

16:34 Bronsa: oh well, that

16:34 "[B"

16:35 llasram: ivan: ^bytes

16:35 (in most places)

16:35 ivan: aha, thanks

16:35 llasram: Bronsa: Unless you want to deprecate that?

16:35 jonasen: dnolen_: dispatching is much faster according to my tests. Before the changes multimethods was ~10x slower than ordinary functions and now it's more like 3x. So hopefully everything works fine and we can start using multimethods in more places

16:36 Bronsa: llasram: are you talking about recursive?

16:37 llasram: Bronsa: I remember there was some discussion of valid values for `:tag` metadata

16:37 Bronsa: ah ok

16:37 llasram: Right now JVM Clojure handles the symbols bytes, ints, etc specially

16:37 Wasn't sure if you were supporting that in CinC

16:37 Bronsa: right

16:38 llasram: I am

16:38 llasram: cool

16:38 Bronsa: llasram: the only thing tools.analyzer.jvm doesn't support is things that cannot resolve to a class

16:38 dnolen_: jonasen: in my tests it was more like 120X slower :)

16:38 Bronsa: it allows for class/symbol/string

16:38 llasram: Ohhhhh, got it. So bytes resolves to [B etc

16:38 Bronsa: yeah

16:39 jonasen: dnolen_: ok. that's weird

16:40 dnolen_: or did you mean multimethods in general (and not with my patch applied)?

16:40 Bronsa: llasram: Rich still has to give his opinion on that so if he says that it's ok to allow arbitrary values in :tag I will make t.a.j support that

16:40 llasram: but tbh I'm hoping that's not his position.

16:41 dnolen_: jonasen: oops actually I think you're right, running w/ your patch applied, yeah they were 10X slower, and now they are comparable to Clojure

16:41 jonasen: excellent work

16:41 jonasen: dnolen_: thanks

16:42 Bronsa: llasram: clojure's handling of :tag is really inconsistent right now btw

16:42 llasram: Bronsa: Oh, totes. Inconsistent and confusing

16:43 Bronsa: sometimes thing get resolved, sometimes not. sometimes wrong tag throws, sometimes it doesn't and there's no clear way to tell what will happen other than trying to do it

17:00 blake__: (/ x y) where x and y are integers...I'm using (/ x (* y 1.0)) to get a real--idiomatic? acceptable?

17:01 akhudek: blake__: use (double y) instead

17:01 gfredericks: ,(double 7/6)

17:01 clojurebot: 1.166666666666667

17:02 gfredericks: ^ can just do it to the answer too

17:02 blake__: akhudek, gfredericks: thanks

17:02 akhudek: gfredericks: yes, but then you are doing math with rationals which is probably slower

17:06 gfredericks: akhudek: that is true

17:10 blake__: Given fn[x], the difference between calling "(fn new-x)" vs. "(recur new-x)"...does the recur use tail-recursion?

17:11 pbostrom: dnolen_: quick Om style question, you mentioned on the ml that components should probably take callbacks over channels, would the callback just be passed in as part of the :state map (like a channel would)?

17:15 dnolen_: pbostrom: depends, if the callbacks are not stateful in some way you can do it via :opts

17:15 pbostrom: if they are state yes, :state works

17:15 s/state/stateful

17:21 pbostrom: dnolen_: thx

17:21 gfredericks: blake__: yep

17:26 coventry: Are differences between cljs and clj on core functions and clojure data structures bugs? (get-in {:a [0]} [:a nil]) returns nil in clj, 0 in cljs.

17:27 gfredericks: ,(get [0] nil)

17:27 clojurebot: nil

17:27 gfredericks: (get [42] nil) returns 42 in cljs

17:28 (get [1 2 3] nil) returns 1

17:28 coventry: I'll file an issue, anyway, in case it's unknown behavior.

17:28 gfredericks: I'd say that's a bug unless there's some crazy perf reason it's wired up that way

17:29 amalloy: s/unless/even if/, right?

17:29 * gfredericks imagines dnolen sitting at his laptop baffled: "I don't know why but if we switch it to do this the code runs faster than equivalent C"

17:30 gfredericks: amalloy: I meant if it was intentional

17:30 amalloy: right, right. i'm arguing it can be a bug even if it was intentional

17:30 coventry: gfredericks: what version did you check with? I'm on r2156.

17:30 amalloy: just by dint of sheer wrongness

17:30 gfredericks: coventry: himera.herokuapp.com

17:31 amalloy: you and your values of right and wrong

17:31 coventry: oh, nice.

17:31 blake__: gfredericks: thanks

17:31 dbasch_: if I have a multimethod that needs to do something for :a, something else for :b, and the same thing for :c, :d, or :e, how do write the method for :c, :d and :e?

17:31 gfredericks: amalloy: fine if you get this then I get integers and ratios

17:32 blake__: If I'm getting a stack overflow from java.util.Random.nextdouble, that's just a coincidence, right? =P It's my own app causing the problem, and Random.java is just by chance where it is when it runs out of stack.

17:32 gfredericks: dbasch_: if you use namespaced keywords you can use inheritance

17:32 amalloy: blake__: yes

17:33 gfredericks: dbasch_: otherwise I think you'd extract it into a helper, or somehow encode that information in your dispatch function

17:33 dbasch_: gfredericks: thanks

17:35 blake__: amalloy: thanks

17:52 bbloom: i seriously just wrote @@#'

17:52 *sigh*

17:52 Bronsa: ew

17:52 bbloom: dereferencing an atom in a private var

17:53 coventry: three-star programmer.

17:53 bmabey: perljure!

17:54 gfredericks: ,(->> (nth (iterate atom 42) 10000) (iterate deref) (drop 10000) (first))

17:55 clojurebot: 42

17:57 bbloom: coventry: when all else fails, add more indirections

17:57 ... or remove them

17:57 i don't know any more

18:00 justin_smith: gtrak: about that stack overflow thread, check this out:

18:00 ,(reduce #(if (> %2 10) (reduced %) (+ % %2)) (range))

18:00 clojurebot: 55

18:01 gtrak: wait wat?

18:01 early exit?

18:01 justin_smith: yup

18:02 nickmbailey: re

18:02 oops, ignore me

18:02 gtrak: ahh, reduced is new in 1.5, no wonder I missed it :-)

18:02 that's good to know

18:03 justin_smith: ,(reduced 42) ; for some reason this amuses me

18:03 clojurebot: #<Reduced@c9a375: 42>

18:04 gtrak: hitchhiker's?

18:04 justin_smith: well the amusing part is that reduced works on its own, but yeah

18:04 42 is like numerical foo

18:05 gfredericks: ,(reduced 1 2)

18:06 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core/reduced>

18:06 blake__: reduced...for testing?

18:06 gfredericks: some reduces like to quit early

18:06 blake__: on Fridays? don't we all?

18:07 justin_smith: blake__: it makes reduce more powerful when it can short circuit, of course

18:07 gfredericks: you could use it to implement find-first

18:07 with less object allocation in a lot of cases

18:08 justin_smith: indeed

18:08 gtrak: yea, I mean that's how I'd explain reduce to folks. reification of a loop into data... gain things like reductions, fork/join, lose some control, that's the tradeoffs.

18:08 blake__: oh...so...if you can get the answer without going over the whole collection?

18:08 gfredericks: ,(defn find-first [pred coll] (reduce #(if (pred %2) (reduced %2)) nil coll))

18:08 clojurebot: #'sandbox/find-first

18:08 justin_smith: blake__: exactly

18:08 blake__: sweet

18:08 gfredericks: ,(find-first even? [1 3 5 6 7])

18:08 clojurebot: 6

18:08 gtrak: there's no technical reason why it couldn't exit early :-), so I'm glad.

18:09 gfredericks: ,(defn find-first-with-index [pred coll] (reduce #(if (pred %2) (reduced [%1 %2]) (inc %1)) 0 coll))

18:09 clojurebot: #'sandbox/find-first-with-index

18:09 gfredericks: ,(find-first-with-index even? [1 3 5 6 7])

18:09 clojurebot: [3 6]

18:09 gfredericks: ,(find-first-with-index even? #{1 3 5 6 7})

18:09 clojurebot: [2 6]

18:09 gfredericks: haha

18:10 llasram: ,(find-first-with-index even? [1 3 5 7])

18:10 bbloom: ,(macroexpand '(fn f []))

18:10 clojurebot: 4

18:10 (fn* f ([]))

18:10 bbloom: ,(macroexpand '(defn f []))

18:10 clojurebot: (def f (clojure.core/fn ([])))

18:10 bbloom: grumble grumble.

18:10 stupid defn

18:10 not passing the name along

18:10 tuft: anyone know why clojure doesn't overload the inequality operators?

18:10 (functions)

18:10 gfredericks: overload?

18:10 oh for non-numeric comparisons?

18:11 tuft: yeah

18:11 blake__: gfredericks: Not sure I get that second one, with the set?

18:11 gfredericks: blake__: it's just treating it as a sequential thing anyways

18:11 tuft: Comparables would be nice -- same for min/max, etc.

18:11 justin_smith: ,(map identity (into #{} (range 10))) ; blake__:

18:11 clojurebot: (0 7 1 4 6 ...)

18:11 gfredericks: tuft: I've wanted this lately too

18:12 justin_smith: iow sets are not ordered

18:12 gfredericks: I literally wrote my own max just yesterday

18:12 tuft: should I go make a library?

18:13 blake__: justin_smith: Oh! OK. So it converts and...well, you shouldn't be using index and sets anyway....

18:13 tuft: could be handy -- generic versions of certain core functions like this

18:13 Bronsa: bbloom: there's a very good reason why defn doesn't pass the name

18:13 justin_smith: blake__: right

18:13 bbloom: Bronsa: which is?

18:14 weavejester: gfredericks: medley has "least" and "greatest" which are like min and max for comparables.

18:15 Bronsa: bbloom: if it expanded to e.g. (def a (fn* a ([..] ..))) and you use `a` inside the fn definition, you'll use the local a rather than going through the Var

18:15 cbp: how do i tell lein repl to use clojure 1.6

18:15 blake__: The right collection for the job.

18:15 technomancy: cbp: outside a project you mean?

18:15 Bronsa: bbloom: that might break redefinition in some cases

18:15 cbp: technomancy: yeah

18:15 bbloom: Bronsa: yeah, i guess that makes sense...

18:15 technomancy: cbp: need to run from git for that

18:16 cbp: technomancy: ah

18:16 thanks

18:16 gfredericks: weavejester: this otherwise has a lot of overlap with prismatic/plumbing

18:16 hadn't seen it before

18:16 justin_smith: would a :dependencies vector in .lein/profiles.clj not do it?

18:16 Bronsa: bbloom: there was a good example where this behaviour is problematic but I can't remember it :/

18:16 bbloom: Bronsa: but that only really matters if you capture the fn

18:16 technomancy: justin_smith: no, because clojure is already loaded by the time that's processed

18:16 bbloom: Bronsa: and in that case, i think you *don't* want redefinition

18:16 weavejester: gfredericks: Ah, I hadn't seen plumbing before

18:16 Bronsa: now I remember the example

18:17 gfredericks: weavejester: it's got kind of a weird focus but I've been using it at work

18:17 Bronsa: bbloom: (defn x [] ..) where the body of x contains a recursion

18:17 and suppose you want to (def x (memoize x))

18:17 gfredericks: weavejester: I just pushed update and mapply into it :)

18:17 weavejester: for some reason I feel like using 2 util libs would be chaos but I don't know why exactly

18:18 S3thc0n: What do you guys prefer (practically and theoretically): The threading macros (a.k.a. pipelining) vs destructuring (by let)? Both alter the code organization to match the program flow in order of appearance.

18:18 bbloom: Bronsa: i think it's worse the way it is now: you do something like (def fog (comp f g)) and if f is recursive, now fog is a broken hybrid

18:19 justin_smith: S3thc0n: horses for courses - if it is linear thread, if values come up repeatedly and not just linear stepwise let bindings

18:19 gfredericks: they do different things well; threading macros support more general operations; destructuring can do lots of things at once

18:19 weavejester: gfredericks: The graph focus in plumbing is a bit curious

18:19 S3thc0n: It honestly depends on the situation

18:19 gfredericks: weavejester: yeah that's part of what I meant by weird focus

18:19 bbloom: Bronsa: i mean if you redefine f after defining fog

18:19 amalloy: S3thc0n: do you prefer company or food? they're not things you can have a preference between, because they're so different

18:20 bbloom: cemerick: does nrepl have some kind of logging mode i can turn on?

18:20 cemerick: i want to see all messages/responses

18:21 cemerick: bbloom: no; I've written the same logging middleware 5 times without putting it anywhere :-/

18:21 S3thc0n: Fair enough. Although it does seem to me like both are generally used to change the order to be (not necessarily my opinion) more intuitive (which is what I'm interested in). Thanks for your thoughts on that.

18:21 justin_smith: bbloom: what about a man in the middle type snooping / logging process in front of the nrepl port? or even wireshark

18:21 technomancy: bbloom: I think it's in `lein help sample`

18:22 oh, doesn't log responses though

18:22 bbloom: cemerick: with tpope's help, i've managed to get fireplace to interop smoothly between .clj and .eclj files, but sometimes fireplace chokes on the nrepl response

18:22 justin_smith: not a bad idea

18:22 cemerick: bbloom: (.eclj is?)

18:23 bbloom: cemerick: it's clojure + bonus features :-)

18:23 well, no bonus features

18:23 yet

18:23 but soon

18:25 Bronsa: bbloom: oh yeah, that doesn't really look right, I didn't think about that

18:28 bbloom: looks like it used to expand to (def x (fn x [])) http://dev.clojure.org/jira/browse/CLJ-809

18:29 bbloom: Bronsa: seems like it sucks both ways, but i understand why it was changed

18:36 gfredericks: bbloom: cemerick: I was wanting some logging middleware recently too; but when you're developing middleware, logging can be subtle

18:36 like you'd want to do before and after or something

18:37 I've started thinking I want a session-multiplexer middleware

18:37 to support things like backgrounding long-running-evals after they've started

18:38 gtrak: oh damn, company-mode

18:38 gfredericks: my emacs does not have company-mode

18:38 gtrak: i just got it from melpa, playing with it.

18:39 supposed to support the cider backend already

18:40 gfredericks: presumably better than autocomplete-mode?

18:40 gtrak: so far, yea.

18:40 I disabled ac-nrepl for the cljs stuff, but this might work out of the box.

18:41 bbatsov seemed vehement about it, anyway :-)

18:41 as just a better project overall

18:59 Frozenlock: What does #clojure use for testing ring app nowadays? Kerodon?

19:01 justin_smith: Frozenlock: I write handlers that can be tested by passing in the appropriate map, and sometimes my groundhog middleware to record requests for later testing

19:02 Frozenlock: I had not seen kerodon, looks cool for more elaborate testing

19:03 Frozenlock: justin_smith: I see. I'm too lazy to make my requests by hands! :-p

19:04 justin_smith: https://github.com/noisesmith/groundhog groundhog records requests as you make them, and can output them to a file or whatever

19:04 so there is no making by hand needed

19:06 xeqi: Frozenlock: unfortuantly I haven't seen anyone build much else in the ring testing area

19:06 there is recording like groundhog, or full stack with clj-webdriver

19:10 bbloom: cemerick: you wanna copy/paste me that middleware you got? :-)

19:11 justin_smith: I am happy to just do recording and reusing those maps, since I like my handlers to be functions of input to output with any state being carried by / pointed to by the request

19:12 (also I haven't had to do many state heavy webapps thank god, or otherwise I would be looking for something like kerodon for sure)

19:12 Frozenlock: Yeah, I guess I was just looking for something of higher level (I already test all my underlying functions). Say, something that would let me know if I messed up my auth with friend, but without have a friend map hardcoded in it.

19:13 blake__: OK, I'm trying to optimize a routine. It's based on my understanding of Knuth's minmax routine for cracking mastermind codes.

19:14 I did a refheap: https://www.refheap.com/75126 The last five lines are the ones taking so long.

19:15 Basically, you check all guesses against all possible remaining codes to find the least number of codes eliminated by any guess (and also the most).

19:16 Your next guess is based on those that have the highest result for "least possible number of codes eliminated".

19:17 amalloy: blake__: well, rand-pattern should be (repeatedly number #(rand-nth colors)). doesn't address performance at all, of course, but you do have a question about that too

19:18 blake__: So, the first time around, with six colors and four codes, it's 1296x1296. This takes a minute. The next one brings it down to 1296x256 (typically). But it's that first 1,679,616 checks that really slow things down. =P

19:19 amalloy: Hah. I'm not even using that. I rewrote it later as "rand-code" and "(vec (repeatedly number #(rand-nth colors)))". So I guess I worked that out.

19:19 (It's the small signs of progress that keep me going. That, and it's my job. =P)

19:20 amalloy: Oh, lol, you even said "repeatedly number..." Missed that.

19:30 Frozenlock: xeqi: Is there something wrong with asking kerodon to follow a link of the type "/some-line"? I get an error (not found), but I can clearly see the link in the enlive parsed document.

19:30 (-> (session server/app) (visit "/") (follow "/login")) ;;;; IllegalArgumentException link could not be found with selector "/login" kerodon.impl/not-found

19:31 xeqi: Frozenlock: it searches by id or link text, not the pointed to url

19:31 well, css selector I think

19:31 Frozenlock: Oh!

19:31 No wonder then

19:31 xeqi: Frozenlock: think of kerodon as only doing what a user would do

19:32 and there are most likely missing features, I haven't touched it in quite awhile and would happily pass kerodon off to another person if they wanted to maintain it

19:33 Frozenlock: xeqi: last commit 3 months ago... ain't so bad ;-)

19:33 xeqi: I think someone else did that, and glenjammin merged it

19:34 so much to do, so little time

19:34 Frozenlock: I'll let you know if I'm interested. But it's quite literally the first time I try it.

19:35 xeqi: haha, didn't mean it quite that way :p

19:43 bbloom: ,(. foo bar)

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

19:43 bbloom: ,`(. foo bar)

19:43 clojurebot: (. sandbox/foo sandbox/bar)

19:43 bbloom: ,`(.bar foo)

19:43 clojurebot: (.bar sandbox/foo)

19:44 bbloom: :-/ parsing dot forms in syntax quote is busted apparently

19:44 llasram: hmmmm -- I'm not sure how it could work that would be better though

19:45 bbloom: ,(macroexpand '(defmethod foo :bar [args] code))

19:45 clojurebot: (. foo clojure.core/addMethod :bar (clojure.core/fn [args] code))

19:45 bbloom: llasram: clearly that's not right ^^ heh

19:45 llasram: Ha

19:45 bbloom: that's apparently just how it works...

19:45 llasram: Well, does `.` ignore the namespace on the method symbol?

19:45 bbloom: ,(eval `(. "abc" (endsWith "c")))

19:46 clojurebot: true

19:46 bbloom: ,`(. "abc" (endsWith "c"))

19:46 clojurebot: (. "abc" (sandbox/endsWith "c"))

19:46 bbloom: yeah seems like it

19:46 crazy

19:46 llasram: A bit odd, but make sense if you squint your eyes and tilt your head a few degrees

19:46 Oh, wait, that's just these polarized sunglasses

19:47 bbloom: heh

20:00 amalloy: bbloom: it turns out that if you don't ignore the namespace part, it's a huge hassle to write any interop macros

20:05 cemerick: bbloom: lost in time, AFAIK. Thus the :-/

20:30 jdeisenberg: Hello. In one terminal I have a core.clj file open in a text editor; in another terminal window I have leiningen repl running. I make a change to core.clj, and would like to re-compile without having to quit repl, compile, and re-enter repl.

20:31 I have tried (set! *compile-path* "./src/polygon") then (compile 'core) but it gives me "could not locate...core.clj on classpath: clojure.lang.RT.load

20:32 justin_smith: jdeisenberg: is core the full name of the ns? or is it polygon.core?

20:32 hiredman: jdeisenberg: compile is almost certainly not what you want at all

20:33 justin_smith: oh yeah, good point

20:33 hiredman: like, basically, there is a 2% chance that compile is what you want

20:33 jdeisenberg: just copy and paste the code in to the repl

20:33 justin_smith: (require 'your.ns :reload)

20:33 or that

20:33 jdeisenberg: Um, let me check the namespace, justin_smith

20:33 hiredman: jdeisenberg: the are editors/setups that give you short guts that basically do that

20:34 short cuts

20:34 jdeisenberg: ns is polygon.core

20:34 justin_smith: jdeisenberg: compile would only compile it, I don't know that it would load the new def

20:34 you want to evaluate the new def, or require with :reload

20:34 hiredman: I would recommend forgetting that compile exists

20:34 jdeisenberg: justin_smith: It was a natural thought (being a clueless newbie)

20:35 hiredman: you will never call it yourself

20:35 jdeisenberg: At the risk of starting a theological war, I'm using vi to edit.

20:35 danielszmulewicz: How do I return the value of a var only if it exists? (without throwing an exception)?

20:36 hiredman: jdeisenberg: I don't use vi myself, but my understand is there are some pretty good vi tools for clojreu these days, maybe bbloom or tpope would know more

20:36 justin_smith: jdeisenberg: fireplace is popular if you want to integrate the repl into your editor, but saving the file and doing a require with reload will do the job too - or even just copy pasting a def into the repl window

20:36 hiredman: danielszmulewicz: resolve + deref

20:36 danielszmulewicz: (inc hiredman)

20:36 lazybot: ⇒ 41

20:36 danielszmulewicz: hiredman: thanks

20:38 bbloom: jdeisenberg: use fireplace. it rocks

20:38 jdeisenberg: justin_smith: Thank you!

20:38 justin_smith: np

20:39 * amalloy has never achieved any goal by calling 'compile himself

20:40 blake__: hmmm "ClassCastException clojure.lang.Cons cannot be cast to java.lang.Number clojure.lang.Numbers.isZero (Numbers.java:90)

20:40 "

20:40 amalloy: &(zero? (range))

20:40 lazybot: java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to java.lang.Number

20:40 hyPiRion: ,(zero? (cons -1 (range)))

20:40 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Cons cannot be cast to java.lang.Number>

20:41 Platz: is cider still the go-to mode for clojure on emacs?

20:41 blake__: ,(zero? (cons -1 (range)))

20:41 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Cons cannot be cast to java.lang.Number>

20:41 llambda: i have an om question: what's the best way to condense this kind of pattern? --> https://gist.github.com/maxcountryman/0f9296ce9306824674ed

20:41 blake__: ,(zero? (cons '(-1) (range)))

20:41 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Cons cannot be cast to java.lang.Number>

20:42 amalloy: llambda: you want repeatedly, not repeat

20:42 llambda: that doesn't work either

20:42 amalloy: (repeatedly 4 (fn [] (apply dom/div ... (repeatedly 4 (fn [] (dom/div ...))))))

20:43 llambda: amalloy: it doesn't output anything when i do that

20:43 amalloy: i mean, i don't know anything about om, but that is how you reduce duplication in this code

20:43 llambda: yeah it doesn't seem to work with om

20:46 amalloy: llambda: i don't really believe that. it's just how functions work. so what is the code that you think is "when i do that"

20:47 `szx: llambda: is it possible you're forgetting apply?

20:47 llambda: `szx: nope

20:47 `szx: oh sorry, didn't see that

20:49 hyPiRion: llambda: not repeat, but repeatedly

20:49 llambda: yes, using repeatedly, it doesn't work

20:50 amalloy: the funny thing is, repeat might actually work fine - i don't know if om needs these things to be distinct objects

20:50 llambda: both repeat and repeatedly yield this: <span data-reactid=".0.0.$cljs$lang$protocol_mask$partition0$:0">32374988</span>

20:50 amalloy: llambda: again, i suggest you paste the code of yours that's producing that output

20:51 llambda: sure

20:51 hiredman: because dom has these functions/macros for generating the shadow dom stuff instead of data structures

20:52 amalloy: hiredman: i'm not sure what behavior your "because" is explaining

20:53 hiredman: amalloy: the serialized javascript constructor name in the string instead of the sane behaviour

20:54 llambda: amalloy: https://gist.github.com/maxcountryman/0f9296ce9306824674ed#file-grid-again-clj

20:55 amalloy: right, you're missing an apply on the first dom/div

20:55 you want to call div with four arguments, not with one argument which is a four-element sequence

20:55 llambda: amalloy: that doesn't work

20:56 (apply dom/div <rest> doesn't work at all

20:56 hyPiRion: so it's a macro then

20:56 `szx: llambda: https://www.refheap.com/75157

20:56 hiredman: om generates macros and functions with the same names for the tags

20:56 amalloy: what does your namespace form look like? a quick look at om suggested to me that it generates both macro and function versions of div, etc

20:57 llambda: amalloy: [om.dom :as dom :include-macros true]

20:57 `szx: llambda: try it out, works fine here

20:57 llambda: `szx: i did, it doesn't work here

20:57 `szx: strange

20:58 llambda: you probabyl aren't using macros?

20:58 amalloy: i guess i don't know enough cljs to diagnose the problem - it sounds like you've only got the macro versions of these tag functions in your ns, but you need to use the function one

20:58 llambda: `szx: what are you requiring from om?

20:58 `szx: (:require [om.core :as om :include-macros true]

20:58 [om.dom :as dom :include-macros true])

20:58 llambda: what version of om are you using?

20:58 `szx: 0.5.3

20:59 llambda: oh i have 0.5.0

20:59 seems like a longshot but

21:00 hyPiRion: bugfixes, bugfixes

21:01 llambda: well it seems to work now...

21:02 thanks everyone!

21:02 next time i'll try updating first i guess heh

21:04 `szx: lein-ancient is your friend :)

21:05 gfredericks: reiddraper: I feel like just reporting the :seed is a little too coarse

21:06 since one seed is used to generate many trials

21:06 reiddraper: gfredericks: i'm about to head out the door, but am curious to hear the rest

21:06 gfredericks: I'll make a ticket

21:07 reiddraper: ty

21:10 beamso: how do i associate a map to a transient map?

21:10 gfredericks: beamso: I'm not sure what that means

21:11 hyPiRion: beamso: convert a map to a transient one, you mean?

21:12 beamso: i want to (def config (transient {})), then use clojure.edn/read-string to read in properties in edn format from a file, then associate those properties back to config

21:13 gfredericks: beamso: that's not a good way to use transients

21:13 why not (def config (clojure.edn/read-string ...))?

21:13 beamso: after asking the question i think i should be using an atom

21:13 i've no idea what the config filename is in advance

21:13 gfredericks: yeah an atom is definitely a better alternative than a transient

21:14 hyPiRion: beamso: use (def config (delay (clojure.edn/read-string ...)))

21:14 unless the file is dynamic

21:14 gfredericks: he said it is

21:14 hyPiRion: yes, I see that now. Then I'd use a promise, actually.

21:14 beamso: the filename is dynamic, not necessarily the file

21:15 hyPiRion: yeah, I meant filename

21:19 akurilin: Any of you folks here familiar with clj-pdf? I can't seem to figure out how to stuff multiple objects into one container obj. e.g. I want a cell to contain 3 paragraph objects, which I know should be possible by looking at the java library

21:20 beamso: using promise/deliver made execution hang.

21:20 akurilin: but it seems like the clj wrapper wants 1 thing

21:20 technically I can go ahead and just use a table inside of the cell, but I'm trying to figure out if that's the prescribed route

21:20 beamso: did you put the 3 paragraph objects into a vector?

21:21 akurilin: Yeah if I do that it only uses the last one

21:21 actually nvm it doesn't support that, I forgot how I got that that conclucsion

21:22 if you DON'T, then it uses the last paragraph

21:22 if you do, it throw an exception

21:35 Frozenlock: xeqi: is it me, or `kerodon.test/has' doesn't cause the test to fail as `is' would?

21:38 xeqi: Frozenlock: you'll need to be a bit more specific there

21:41 Frozenlock: xeqi: nvm, I see it's doing the thing as `is' in the repl. Somehow, when I do `lein test' it just ignores it. Must be my config.

22:06 * gfredericks considers creating a library of test.check utilities called test.chuck

22:09 guns: gfredericks: ooh, what kind of test.check utilities are those?

22:09 I'm writing a concurrent property test right now, and it's a real head twister

22:10 gfredericks: guns: not sure

22:10 I'd been considering collecting some things together for running slow/flaky tests

22:10 not sure if that applies to what you're doing

22:10 but I have a big pile of generator utilities too

22:10 guns: I'm really new to this, and I love the idea

22:10 gfredericks: I figured test.chuck was a good name for a dumping ground

22:11 guns: I see. I'll keep a look out.

22:11 gfredericks: Heck I'll make it right now.

22:11 guns: I got excited by the Erlang QuickCheck guy's wizard powers

22:11 John Hughes

22:11 gfredericks: right

22:16 https://github.com/fredericksgary/test.chuck

22:16 I need a logo of chuck

22:17 guns:

22:17 amalloy: gfredericks: http://robmason.org/projects/the-rules-of-manliness-according-to-chuck-norris/images/5.jpg

22:17 justin_smith: gfredericks: you should have a test.chuck.testa namespace for mocking data

22:17 amalloy: easy choice

22:17 gfredericks: I'm not sure how that didn't occur to me.

22:18 llasram: Because he's a bizarro racist?

22:18 gfredericks: oh snap he probably is isn't he

22:18 quick I need a better chuck

22:18 a liberal progressive chuck

22:19 llasram: http://en.wikipedia.org/wiki/Groundhog

22:19 amalloy: gfredericks: chuck taylor?

22:20 llasram: How many tests would a test.chuck chuck if a tech.chuck would chuck tests?

22:20 justin_smith: http://i.imgur.com/lioMEJA.jpg

22:20 chucky from child's play?

22:22 gfredericks: I'll go with ye olde land beaver

22:22 xeqi: gfredericks: http://jeffvrabel.files.wordpress.com/2012/07/chuck_e_cheese.gif

22:23 gfredericks: :)

22:28 The photo has a line through it but so does leiningen's; mine just looks worse.

22:29 and so it is that I created a 5-segment namespace O_o

22:32 uh oh my test.chuck code uses the gen/for macro that hasn't been merged yet

22:32 nobody use this yet

22:40 gs

22:40 * gfredericks oops

23:28 ToBeReplaced: how come people use routing libraries (eg. compojure) for http dispatch instead of multimethods?

23:29 justin_smith: ToBeReplaced: good question

23:29 ToBeReplaced: i can see a good argument for pedestal's version of routing since it is mostly data, but i don't see the same benefit for compojure

23:29 justin_smith: we made polaris because we wanted routes defined from a db, and reverse routing

23:31 amalloy: what value would multimethods bring to http routing? it doesn't sound like fun at all

23:31 xeqi: I'd imagine the dispatch function to be complex

23:31 ToBeReplaced: justin_smith: thanks i'll take a look... i'm out of touch with clojure-on-the-web; i like that the routing table is data/exportable

23:32 amalloy: (defmulti http-response :request-method), (defmulti get-response :request-uri), (defmethod http-response :get [req] (get-response req)), etc.

23:33 seems nice to me; lets you define the pipeline you follow to dispatch... easier to do things like separate off "what content type will this return?" from "what data will this return?", etc.

23:34 and you get all of the benefits of pluggability

23:35 amalloy: that's like super-fragile and special-case. now everything you want to do with ring has to live in a top-level var, which is your multimethod. how do you wrap just half of your routes in authentication middleware?

23:36 and if you want the same behavior for PUT /xyz and POST /xyz, you have to define it twice separately, in apparently-different places

23:36 xeqi: wildcard paths and proper ordering seem fun

23:38 ToBeReplaced: amalloy: hmm... top-level var commentary doesn't seem any different than compojure's solution, though i do see what you mean how at some point you'll have to break off and do routing via functions to manipulate at runtime

23:39 amalloy: ToBeReplaced: consider: (def app (routes (GET "/foo" [] (ok)) (wrap-authentication (GET /bar [] (print-username)))))

23:39 how can you possibly write an equivalent of that?

23:40 ToBeReplaced: i don't know what that does

23:40 amalloy: neither do i, i just made it up

23:40 the point is to replicate the wrapping of the middleware around just one route

23:40 ToBeReplaced: wrap-auth seems broken by design? authentication via middleware feels like a bad idea?

23:40 amalloy: okay, so wrap-json, whatever

23:41 (a lot of people disagree with you about auth, but that's not the point)

23:41 ToBeReplaced: oh, that's easy, isn't it? isn't that the same thing as injecting a new defmulti?

23:41 yeah, i know... some months ago i complained about it, but knew i wasn't going to put in the work to try to do it a different way (a la pedestal), so i quieted myself

23:42 ex. (wrap-head) is defined in my example above

23:42 although it's better, actually... because now you don't have to evaluate a request first (and then set body to nil)

23:43 which is a good example of a common complaint i have -- i don't have a mechanism to easily, for example, separate what content type will be returned vs what the content is

23:45 the put/post comment isn't fair either fwiw... solution would be (defmulti put-response :put [req] (post-response req))... one-liner

23:45 there's definitely some ickyness there though, b/c it's not data... so if you couldn't be consistent site-wide, complex dispatch paths would get very hard

Logging service provided by n01se.net