#clojure log - Jan 08 2013

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

0:12 tomoj: why would you need `lein repeat` to get a clean state?

0:30 pppaul: hello

0:36 bbloom: i'm pretty sure haskell's type system just empowers you to write programs that you shouldn't ever write b/c no 1 can ever understand them

0:39 tomoj: by "no 1" do you mean something like "people who haven't spent a lot of time using haskell" ?

0:40 bbloom: i think the real problem is that the only time i ever read haskell is when i want to implement some algorithm that i probably couldn't understand in clojure either

0:40 gtrak: anybody ever try to deal with openstreetmap data? what's the best way right now? Just downloaded a dump of a state.

0:43 aaelony_: at some point, you come to the conclusion that in order to understand a particular library, you're going to have to dive into and understand the source. When faced with a bithub src directory with a bunch of subdirs, what do people typically do to get a sense of things?

0:43 github

0:43 gtrak: aaelony_ , I find the best way is to get it compiling, then use emacs for code navigation... it's way faster.

0:43 repl it

0:44 and I feel this way about every clojure library ever

0:44 aaelony_: it would be nice to have a tool or something that could give a general idea of function flow, or whether the functions are mostly standalone or not, if not, then how then depend, etc..

0:45 gtrak: grep works pretty ok for that, sometimes it just takes time, but clojure source is small enough that you can read all of it usually

0:45 aaelony_: gtrak: where do you usually begin to grep it or repl it?

0:45 gtrak: the tests

0:46 aaelony_: I guess, the trick is to find the starting point. then the rest makes sense, since you know whence it came

0:46 tomoj: bbloom: I think when you read haskell, you can't just read the code, you have to meditate on the types to understand it. which is pretty different from most languages

0:46 aaelony_: the tests!!! awesome, thx

0:47 maybe the tests *are* the docs...

0:48 gtrak: ok, I have a 1GB xml file ;-), what now?

0:48 bbloom: tomoj: yeah, but then people go and add a bunch of unnecessary type aliases that just confuse me more :-P

0:48 how is a C different than a P ? oh wait, they are both Qs

0:48 wtf is a Q ?

0:48 * bbloom throws up hands in the air

0:49 gtrak: like you just don't care?

0:49 bbloom: *sigh*

0:50 tomoj: yeah they tend to like cute little names for things :(

0:50 I guess some of the information we convey in a name is conveyed by the type

0:50 aaelony_: gtrak: does a schema for the xml file exist?

0:51 tomoj: er, _more_ information than we convey in a name..

0:51 usually

0:51 gtrak: aaelony_ yes, I think so, it's openstreetmap

0:51 aaelony_: hopefully its helpful...

0:53 gtrak: I'm trying to compile all the intersections in a city

0:53 just for shits and giggles

0:54 tomoj: guess you need a lazy xml parser?

0:54 aaelony_: sounds cool

0:54 gtrak: yea, looking at clojure.data.xml

0:54 aaelony_: xml-seq ??

0:54 lazybot: aaelony_: Uh, no. Why would you even ask?

0:55 aaelony_: heh

0:55 gtrak: hah

0:55 is it so ridiculous?

0:56 xml-seq doesn't look bad

0:56 aaelony_: or maybe zippers

0:56 gtrak: I'm going to have to filter it a lot, I think

0:56 then cross-correlate

0:57 it's meant to go in a database, but whatever

1:02 alex_baranosky: do you guys use hiccup for generating XML?

1:03 gtrak: as it turns out, clojure.xml is not lazy :-)

1:03 Raynes: alex_baranosky: I'd hope not.

1:03 alex_baranosky: Why would you? clojure.xml supports the same syntax.

1:04 alex_baranosky: Also, did you figure out the problem with your irc stuff?

1:04 alex_baranosky: why I ask is that we have a bunch of old 1.2 code that generates hiccup-like vectors and makes XML from them using contrib.prxml… what's the easiest migration path off of contrib for that code ?

1:04 Raynes: alex_baranosky: clojure.xml has stuff that can take prxml structures.

1:05 alex_baranosky: Raynes: I'm pretty tired tonight, so haven't put much thought into it… I'm back to COloquoy for now, and will debug the situation better otmorrow

1:05 Raynes: ahhhh, I didn't know that, I thought it only worked with the map format

1:05 thanks

1:05 aaelony_: alex_baranosky: I asked a similar question a while back… the following works for me, maybe it is enough for your needs to? https://www.refheap.com/paste/8200

1:06 Raynes: Ugh

1:06 aaelony_: ha

1:06 Raynes: Just use clojure.xml :p

1:06 Also, I'm being stupid.

1:06 alex_baranosky: aaelony_: looks like your `x` is not hiccup-formatted

1:06 Raynes: data.xml

1:06 aaelony_: i'm not using hiccup

1:06 Raynes: alex_baranosky, aaelony_: I meant data.xml when I was saying that crap above. Please ignore everything I've said before now. data.xml, the contrib lib, has what alex wants.

1:06 aaelony_: currently

1:07 alex_baranosky: yeah, I knew what you meant :)

1:11 devn: http://getclojure.org/

1:12 still very beta

1:12 tomoj: 500 :(

1:12 devn: no pagination yet, so don't blow up your browser by searching for let

1:12 tomoj: http://getclojure.org/search?q=%28juxt+identity+inc%29

1:12 devn: tomoj: it's propagating, must have not made it to you yet

1:12 tomoj: oh, oof

1:12 tomoj: I see

1:13 supposed to search for a symbol, not a form?

1:13 devn: yeah, start with a symbol

1:13 like butlast or something

1:14 tomoj: these coming from codeq or what?

1:14 devn: output is screwed up -- it should be disabled when the result is ""

1:14 tomoj: not *yet*

1:14 tomoj: well, still cool

1:15 devn: tomoj: ive been toying with extending codeq with amrbose' analyze

1:15 holo: hi

1:15 devn: ambrose*

1:15 rlb: I have a situation where it looks like case isn't working for strings, but I assume I'm just doing it wrong. Anything obvious I might be missing?

1:15 devn: rlb: case?

1:15 rlb: got an example?

1:15 rlb: (case x "foo" 42 "bar" 99)

1:15 tomoj: &(case "foo" "foo" 42 "bar" 99)

1:15 lazybot: ⇒ 42

1:15 tomoj: seems to work

1:16 rlb: right

1:16 Raynes: devn: Where is the source code?

1:16 https://github.com/devn/getclojure duh

1:16 devn: Raynes: that's sort of the mess i've left

1:16 Raynes: devn: Awww, no laser.

1:16 I thought we were friends, man?

1:16 devn: laser?

1:16 Raynes: I thought we were friends.

1:17 https://github.com/Raynes/laser coolest new thing on the market

1:17 * devn buys 10

1:17 holo: with {:foo nil, :spam nil} has the same practical functionality as {}, but i can't test it as empty? . how can i achieve this kind of testing for the first map without filtering out all the nil values from the map?

1:17 devn: Raynes: oh, cool

1:18 tomoj: holo: not the same practical functionality, not even for ILookup: ##[(get {:foo nil} :foo 3) (get {} :foo 3)]

1:18 lazybot: ⇒ [nil 3]

1:18 tomoj: &(contains? {:foo nil} :foo)

1:18 lazybot: ⇒ true

1:19 tomoj: &(seq {:foo nil})

1:19 lazybot: ⇒ ([:foo nil])

1:19 tomoj: etc

1:20 holo: tomoj, i see. didn't remember that one hehe

1:20 amalloy: don't forget ##[(get {:foo nil} :foo 10) (get {} :foo 10)]

1:20 lazybot: ⇒ [nil 10]

1:21 tomoj: oh, it works with 10 instead of 3? :P

1:21 anyway, ##(empty? (keep identity (vals {:foo nil, :spam nil}))) or something

1:21 lazybot: ⇒ true

1:23 holo: keep - any reason for such a name?

1:24 >.> if i knew keep, i would have spared some filters

1:25 tomoj, thanks, that was a great one liner

1:26 amalloy, thanks

1:34 amalloy: hah. i can't read, tomoj. i saw a pair get returned and assumed you'd demonstrated ##(find {:foo nil} :foo)

1:34 lazybot: ⇒ [:foo nil]

1:34 tomoj: find is not in my vocabulary

1:35 why is it useful?

1:36 maybe for ##(conj {} (find {:foo nil} :foo)) ?

1:36 lazybot: ⇒ {:foo nil}

1:36 amalloy: (when-let [[_ v] (find m k)] ...)?

1:36 tomoj: ah, because it's truthy no matter the value

1:36 neat

1:36 amalloy: it's a handy way to combine contains? with get

1:38 holo: oh, ok i got the meaning of keep..

1:40 gtrak: gosh, clojure.data.xml sure spends a lot of time in Symbol.intern

1:40 amalloy: keywords, man. reading them from strings is expensive

1:41 gtrak: but I can count over the 1GB xml file in 30 seconds

1:41 so, I guess that's good enough

1:41 tomoj: how much of that is keywords?

1:41 gtrak: like all of it

1:41 according to jvisualvm sampler, haven't tried the profiler yet

1:42 I'll giver her a go

1:43 ah, maybe it's not as bad as I thought

2:14 francis: I just cloned the clojure.data.xml repoistory and would like to run some tests, however it seems that clojure.data.* projects don't use leiningen - what is the standard way of running tests for these projects?

2:22 alex_baranosky: anyone know how to run tests for the Clojure core maven-based projects?

2:27 noidi: alex_baranosky, mvn test? :)

2:34 seangrove: Will cljs source maps potentially work with code compiled in advanced mode?

2:34 Would make debugging *slighty* easier

2:36 bbloom: seangrove: i believe that is the goal

2:36 however, advanced mode compilation might be like a release mode C compilation

2:36 when debugging C code with full optimizations disabled, the debugger doesn't always move linearly or execute every line

2:37 etc

2:37 i mean enabled

2:38 seangrove: Yeah, I'm just getting an error, and the stack trace is useless - I don't even know where it might be coming from in the source

2:38 bbloom: does it happen w/o advanced mode?

2:39 seangrove: Nope

2:39 bbloom: are you using aget anywhere?

2:39 seangrove: Yes, a few places, actually

2:39 bbloom: search for those

2:39 anywhere you aget with a string is potentially your problem

2:39 seangrove: Built everything up with simple, and now I've just been going through with advanced mode and stamping out errors

2:39 ok, will grep now..

2:40 bbloom: (aget obj "abc") compiles to obj["abc"]

2:40 which might not be valid if abc has been minified

2:40 Ember-: oh, lol. What's the shortest implementation in Clojure that will cause a StackOverflowError?

2:40 ,(#(%%)#(%%))

2:40 clojurebot: #<RuntimeException java.lang.RuntimeException: java.lang.StackOverflowError>

2:40 Ember-: &(#(%%)#(%%))

2:40 lazybot: java.lang.StackOverflowError

2:40 Ember-: :)

2:40 got it from here http://codegolf.stackexchange.com/questions/9359/shortest-program-that-throws-stackoverflow-error

2:40 bbloom: ,(fn f[](f))

2:40 clojurebot: #<sandbox$eval59$f__60 sandbox$eval59$f__60@6076264f>

2:41 bbloom: ,((fn f[](f)))

2:41 clojurebot: #<RuntimeException java.lang.RuntimeException: java.lang.StackOverflowError>

2:41 Ember-: bbloom: one character longer ;)

2:41 bbloom: Ember-: yes, but my IRC client has a variable width font -- i win there

2:41 Ember-: :D

2:41 cheater!

3:11 alex_baranosky: Anyone got a good idea how to parse something of this form without using a read-string? "(= {:A 1} {:a 1, :c 3, :b 2, :d 4, :e 5})" I want to transform it into ["=" "{:A 1}" "{:a 1, :c 3, :b 2, :d 4, :e 5}"] where each of the three pieces can be any code clojure could write, but which I may not be able to read at the moment

3:13 noidi: alex_baranosky, why can't you use the reader?

3:13 alex_baranosky: because the forms aren't readable

3:17 maybe I just read one char at a time, and keep stack of {'s, ('s, and ['s and use a simple approach like that

3:18 but it seemed like maybe something already existed for this

3:18 alandipert: alex_baranosky: a parsing lib? or cobble together a reader with PushbackReader that does whatyou want

3:18 zilti`: alex_baranosky: Probably regex?

3:19 noidi: alex_baranosky, IIRC, Counterclockwise uses Parsely and a custom grammar to parse Clojure code. Maybe you could lift some code from CCW :)

3:20 alex_baranosky: thanks, I may check it out

3:20 noidi: https://github.com/laurentpetit/paredit.clj

3:36 alex_baranosky: I wonder if sjacket may be of some use: https://github.com/cgrand/sjacket

3:44 ejackson: Raynes: what are your thoughts on XPATH selectors ?

4:12 Raynes: ejackson: xpath

4:12 I do not know what this is.

4:15 ejackson: its a selector thingy that I recently came across

4:16 ro_st: select xml using a nested path syntax

4:16 ejackson: http://www.w3.org/TR/xpath/

4:16 Raynes: ejackson: Oh, I see, looks neat.

4:16 ejackson: its pretty old, but its got some really nice functionality

4:16 ro_st: Raynes is too young to have fussed with xml :-)

4:16 Raynes: This is one of those things you could implement on top of laser's existing selectors (probably need to add more selectors though).

4:16 ejackson: kids these days, forgetting the old ways (in this case, probably a good thing)

4:17 Raynes: But you can't do XML with Laser.

4:17 It uses a validating HTML parser.

4:17 ejackson: siblings was really interesting

4:17 bbloom: ejackson: with the exception of the attributes vs elements distinction, xpath & xquery were probably among the only good things to come out of XML :-P

4:18 Raynes: It could be used with xml in the same capacity as enlive is, but jsoup currently lacks a way to parse xml fragments.

4:18 ejackson: bbloom: i still have no idea what the distinction is. Baffled me every time

4:19 bbloom: ejackson: the only really interesting distinction has to do with streaming parsers/writers

4:19 ejackson: Raynes: anyway, you might find some nice ideas for laser in there.

4:19 Raynes: ejackson: Indeed. Thanks for the tip.

4:19 bbloom: ejackson: an element start tag can't be written without all it's attributes

4:19 so in that sense, it's like a header

4:19 ejackson: ok

4:19 bbloom: if you have a streaming XML reader, you may never see an end tag, but you won't see the head tag unless you also see all of it's attributes

4:20 gozala: Hi Folks do I need special privileges to comment on http://dev.clojure.org/display/design/Feature+Expressions ?

4:21 ejackson: yesterday I wrote an xpath: "//td[text()='foo']//following-sibling::td[2]", which gets the second sibling of all TDs containing the text foo. I thought it was pretty neat.

4:21 but I'm nooby at that sort of stuff

4:31 tomoj: but why strings?

4:32 ejackson: tomoj: in the xpath ?

4:33 i think it just predates data-thinking

4:33 tomoj: I mean, why use xpath or css string selectors when we have functions and data?

4:33 yeah

4:34 bbloom: it's useful for the same reason that regexs are useful

4:34 it's short hand for something you might do a lot

4:34 you could write a state machine out by hand

4:35 and somebody who doesn't know regexes could read that

4:35 but we write so many damn regexes, we might as well come up with a language to maximize our productivity there

4:35 tomoj: you can have short hand without putting it all into a string

4:35 bbloom: xpath & css selectors are codifications of a short hand for particular problem domains

4:35 i think css selectors are a nightmare, but that's another issue

4:35 :-P

4:36 tomoj: do you have a reasonable feature-complete edn-encoded xpath schema?

4:36 that is, can you express all xpaths/queries ad edn in a way that makes sense?

4:37 tomoj: doubtful, you need some functions

4:37 but I'm not writing laser, anyway :)

4:37 bbloom: :-P

4:37 tomoj: just a bit puzzled by "Biggest TODO at the moment is a function for turning a string representing a CSS selector into a selector function you can use (by combining existing selectors)."

4:38 well

4:39 you need some functions, but maybe they're just symbols in the data

4:40 doesn't seem inferior to putting a bunch of special keywords like following-sibling in xpath

4:40 seems superior since you can extend it

4:41 and it's programmable

4:41 xumingmingv: I am compiling a project(using lein), but one of the file compiled twice, and then the lein process hangs, anyone knows the reason? stacktrace: https://www.refheap.com/paste/8204

4:41 ejackson: tomoj: I wasn't suggesting a string be used for the selector. I was hoping there might be some selectors that XPATH makes possible that Raynes would be inspired by.

4:42 tomoj: sure, I was mainly responding to that TODO note in laser's readme, you just triggered me

4:42 muhoo: needs the word "selector" in there more.

4:43 i was looking at bootstrap.js recently, and less looks like an attempt to make a dsl out of css.

4:43 tomoj: isn't css already a dsl?

4:44 ejackson: guess so

4:44 tomoj: Raynes: that TODO seems like a case of reversed stupidity to me - don't give up on data selectors just because enlive has some problems, please :)

4:44 xumingmingv: never mind, i find the cause

4:44 ejackson: tomoj: you're suggesting that instead of a query string be a data structure.

4:44 a function composition say

4:45 tomoj: of course, you've probably thought about it much more than I have

4:45 muhoo: that's what i got from that TODO entry: some way of composing selectors, maybe?

4:45 * ejackson is just checking he understands

4:45 tomoj: yeah, not strings, clojure data structures

4:46 possibly including symbols referring to selector functions

4:46 ejackson: oh, so like a hiccup thing ?

4:46 but for building the selector

4:46 or a korma thing for sql

4:46 muhoo: actually, i'm pretty sure laser parses html into a hiccup-like structure

4:46 tomoj: sort of like hiccup, yeah

4:46 like enlive, really

4:47 ejackson: like enlive :)

4:48 muhoo: it seems to me like the use case is where you have chunks of html, but want to turn it into clojure data structures so as to Do Stuff (tm) to it.

4:48 which i guess is what enlive does, but maybe simpler?

4:49 anyway, neat stuff. will find an excuse to play with it soon.

4:49 tomoj: I suppose it's intentional that you can't use ns aliases in reader literals :(

4:51 I just realized datomic took #db/id

4:51 so the reader literal namespace-namespace is apparently the wild west as well

4:51 unless rich just gets special privileges :)

4:51 ro_st: course he does

4:52 abp: In a Compojure app that gets deployed into a servlet container later, should I just use ring.util.request/path-info to build any links etc., so the context-path of the servlet is always present?Also, is it a good idea to develop using jetty locally when deploying into a servlet-container?

4:55 N1c0: test

4:56 muhoo: the docs say that unqualified literals are reserved (for rich, presumably).

4:57 but qualified ones need to be unique i guess. so in that sense it's wild west like artifact naming maybe.

4:58 #inst made life very pleasant in json-land recently.

5:09 bbloom: ok wtf is the deal with this [trace missing] business?

5:09 it makes debugging really annoying sometimes

5:12 ejackson: yeah, I've had that one recently too

5:13 Ember-: ccw?

5:13 clojurebot: ccw is http://github.com/laurentpetit/ccw

5:13 Ember-: it has a bug

5:13 you need to use (pst) for now

5:14 bbloom: i'm using vim-foreplay

5:14 but i've had it at the normal nrepl before

5:16 TobiasRaeder: there are probably some people using emacs + nrepl around here arent there?

5:17 i just migrated to the new clojure-mode + nrepl but when trying to hit enter in the nrepl i just get Wrong type argument: integer-or-marker-p

5:17 emacs 24.1.x

5:17 ejackson: TobiasRaeder: not seen that, sorry.

5:18 dimovich: hello ppl

5:19 for a new type, how would one implement withMeta from clojure.lang.IObj?

5:23 bbloom: dimovich: simply add a meta field to your type and then call your constructor with the new meta

5:24 (deftype Foo [a b m] clojure.lang.IObj (withMeta [this meta] (Foo. a b meta)))

5:24 or, if you use reify, you get metadata for free

5:24 dimovich: bbloom, thanks a lot

5:32 Raynes: ejackson: Uh, what was he calling me stupid for?

5:34 ejackson: Wait, was he saying it was stupid for me to implement real CSS selectors instead of some ridiculous vector and keyword representation?

5:34 I don't get it.

5:34 I'd rather not implement selectors at all. I think we should just use functions instead.

5:35 I don't know what he means by 'data selectors'.

5:54 ro_st: why would someone use scala instead of clojure? in a nutshell.

5:55 vijaykiran: typesafety

5:55 ro_st: and "hybrid" programming

5:56 ro_st: by "hybrid" I mean - OO & Functional at the sametime.

5:56 ro_st: that sounds terrifying

5:56 the hybrid bit, i mean

5:57 vijaykiran: ro_st: I didn't say it is "good" :)

5:57 ro_st: ok. i guess i was implicitly asking what the good reasons are

5:58 vijaykiran: typesafety is the one I see being pushed as important/good thing.

5:58 ro_st: and that's the typical class heirarchy with static type checking story?

5:59 hyPiRion: no, not afaik

5:59 Isn't Scala doing more Haskell-like type derivation? I've not used Scala, so I may be way off.

6:02 vijaykiran: the answer here summarizes better (of what I'd in my mind) - http://stackoverflow.com/questions/3112725/advantages-of-scalas-type-system

6:02 ro_st: thanks vijaykiran

6:03 now i'm more terrified.

6:05 hyPiRion: heheh

6:05 Raynes: ro_st: Scala is pretty terrifying.

6:05 ro_st: it looks it. -closes tabs-

6:05 hyPiRion: Malbolge is worse though.

6:05 bbloom: i keep saying it: scala is to java as c++ is to c

6:06 that's all you need to know

6:06 vijaykiran: bbloom: +1 :)

6:06 ro_st: that's four languages i've never used :-) doesnt' say much to me, personally

6:06 but i reckon i get the gist of it

6:07 scala now has 'condemned. stay out' on it in my head.

6:08 Raynes: Scala is a kitchen sink language.

6:08 It's worth looking at, but I wouldn't want to write code in it.

6:08 They just added macros in the latest version.

6:08 While that might sound like a good thing, if you've ever seen a piece of even marginally complex Scala code and tried to read it you'd understand why it really isn't.

6:09 ejackson: Raynes: macros in a non-homiconic language is just rusty-nail eyeball scraping.

6:10 Raynes: I had someone telling me that Nimrod's macros are more powerful than Lisps a few days ago.

6:10 ejackson: i keep being tempted by "its like Haskell, but on the JVM"...

6:10 bbloom: it's all the complexity of haskell with all the verbosity of java

6:10 Raynes: I was left pretty speechless.

6:10 ejackson: that's quite scary

6:10 hyPiRion: bbloom: I don't think it's specifically verbose though. It's just that there's so much stuff in Scala that you have to remember

6:11 And so many special cases etc.

6:11 bbloom: i'm currently porting this: http://hackage.haskell.org/packages/archive/FPretty/1.0/doc/html/src/Text-PrettyPrint-FPretty.html to clojure

6:12 here's the scala version: http://code.google.com/p/kiama/source/browse/src/org/kiama/example/imperative/PrettyPrinter.scala

6:12 *cringe*

6:12 ooops wait

6:12 bad link

6:13 ro_st: scala looks like java with four times more syntax rules

6:13 bbloom: dammit google code, why can't you suck less and be more like github?

6:14 here: http://code.google.com/p/kiama/source/browse/src/org/kiama/output/PrettyPrinter.scala

6:14 hyPiRion: compare that to the haskell version

6:14 which, btw, the haskell version also lacks some serious bugs b/c it includes a normalizer that is necessary according to the original paper lol

6:17 if i had to write java, i'd rather write scala, but i suspect i only say that now like i used to say "if i had to write c, i'd rather write c++"

6:17 now i rather quit and get another job :-P

6:21 hyPiRion: Man, I am happy I don't have to touch so much C++

6:25 Raynes: bbloom: I feel like I'd probably rather write C.

6:25 bbloom: Raynes: that's what i'm saying, i prefer C to C++

6:25 Raynes: Oh.

6:25 bbloom: but i was saying that i *might* prefer scala to java

6:26 but that might only be because i *used to* prefer C++ to C ... until i used C++

6:26 :-P

6:26 i've written some non trivial toy apps in scala and found it to be a huge step up over java, but i feel like it might have just felt liberating coming from java

6:28 jro__: bbloom: what is your preferred way to write scala? Following Haskell style, or just as extended Java?

6:29 bbloom: jro__: i don't really have a preferred way b/c i only used it for a few weeks a few years ago

6:29 jro__: but i suspect it would be like how google uses c++: like C with 2 extra features

6:29 :-P

6:30 alex_baranosky: any idea why "[:method [:-cdata "Overnite FedEx"]]" would be getting parsed as a clojure.data.xml.Element and not a clojure.data.xml.CData? ?

6:41 asteve: I have a line that is `1123.918 [0 1.1.1.1:57979] "do" "something"` and I want to remove from [ to ]

6:43 ejackson: str/replace should do it ?

6:44 asteve: s/replace #"\[\.\+\]" "")?

6:44 ejackson: yeah

6:51 bbloom: is there a function version of doall to force side effects?

6:52 like i want (mapv print foo) without having a big empty vector of nils

6:52 rather than (doseq [x foo] (print x))

6:53 basically: (defn each [f coll] (doseq [x coll] (f x)))

6:54 ro_st: i guess there is now :-)

6:54 asteve: ejackson: do you see something wrong with this: (let [clean-tuple (s/replace tuple #"\[\.\+\]" "")]?

6:56 noidi: bbloom, there's dorun

6:56 ,(doc dorun)

6:56 ro_st: #"\[[^\]]+\]"

6:56 bbloom: (doc dorun)

6:56 clojurebot: "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. dorun can be used to force any effects. Walks through the successive nexts of the seq, does not retain the head and returns nil."

6:56 "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. dorun can be used to force any effects. Walks through the successive nexts of the seq, does not retain the head and returns nil."

6:56 bbloom: sooo (dorun (map print coll)) ?

6:56 noidi: yes

6:56 bbloom: ok cool, i figured that existed

6:56 noidi: it's not your `each`, but it doesn't retain head like doall does

6:57 bbloom: the main reason i want the each thing is b/c i frequently find myself creating sequences via ->> and then, for debugging purposes, wanting to slap a (each print) at the end of the chain

6:59 ejackson: asteve: (str/replace "1123.918 [0 1.1.1.1:57979] \"do\" \"something\"" #"\[.*\]" "")

7:00 don't escape the .+

7:00 ,(str/replace "1123.918 [0 1.1.1.1:57979] \"do\" \"something\"" #"\[.*\]" "")

7:00 clojurebot: #<CompilerException java.lang.RuntimeException: No such namespace: str, compiling:(NO_SOURCE_PATH:0)>

7:00 ejackson: ,(replace "1123.918 [0 1.1.1.1:57979] \"do\" \"something\"" #"\[.*\]" "")

7:00 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core$replace>

7:00 ro_st: clojure.string/replace :-)

7:00 ejackson: ,(clojure.string/replace "1123.918 [0 1.1.1.1:57979] \"do\" \"something\"" #"\[.*\]" "")

7:00 clojurebot: "1123.918 \"do\" \"something\""

7:00 ejackson: ro_st: hehe, was just checking ;)

7:03 ,botsnack

7:03 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: botsnack in this context, compiling:(NO_SOURCE_PATH:0)>

7:03 ejackson: i tried

7:03 I'll give to the other bot... you watch me !

7:03 $botsnack

7:03 lazybot: ejackson: Thanks! Om nom nom!!

7:03 ejackson: yeah.... yeah.... how you like that ?

7:07 aroemers: Any of you Clojurians know of a job opening in Clojure in the Netherlands?

7:10 Not all at once! :P

7:10 ejackson: hehe, sorry dude.

7:11 aroemers: Suspected that it would be difficult, but hey, I can try

7:12 ro_st: job for you if you live in Cape Town, South Africa :-)

7:13 ejackson: aroemers: you should immigrate.

7:13 Clojure in Cape Town .... what a pleasure.

7:13 aroemers: hmm, the commute is a tad long from here

7:13 hyPiRion: psh, 12 hrs?

7:14 ejackson: but no jetlage !

7:14 Raynes: aroemers: Don't feel too bad, I've got to move 2000 miles in less than one month for a full time Clojure job.

7:14 aroemers: true

7:14 ejackson: i had to give up my job to do clojure !

7:14 :)

7:15 aroemers: ejackson: but you found a job in it?

7:15 ejackson: i created one :)

7:15 metacircular employment

7:15 very lispy

7:15 aroemers: Raynes: oh, I am willing to travel, but Cape Town...

7:15 hehe, nice

7:16 asteve: ejackson: thanks for the help

7:16 Raynes: aroemers: If you're willing to travel, travel to California. So much Clojure there that they've parenthesized all road signs.

7:16 ro_st: haha

7:16 ejackson: aroemers: however, I am teaching a Clojure course in Amsterdam with samaaron and cgrand in a couple of months !

7:17 hyPiRion: There's a place in Finland afaik

7:17 ejackson: yeah, there's lots in Finland

7:18 aroemers: ejackson: an introductionary course I guess?

7:18 ejackson: London too if you want to do banking

7:18 aroemers: and an intermediate

7:18 otherwise cgrand gets too bored and starts drawing on the walls...

7:19 aroemers: hehe

7:19 intermediate might be interesting, where can I find more info?

7:20 ejackson: www.lambdanext.com

7:21 not much there now, but we're planning quarterly courses, with Amsterdam being the next

7:21 sign up and you'll get the mailshots

7:22 aroemers: done

7:23 ejackson: groovy - you can be the official beer guide !

8:17 cemerick: tpope: I finally got around to releasing nREPL 0.2.0-RC2 last night. Sorry for the stupid delay, I just totally forgot about it. :-(

8:17 Raynes: cemerick: When are you going to write nREPL for Haskell?

8:17 cemerick: ha-ha

8:18 Raynes: cemerick: Did you ever find someone to write those examples?

8:18 cemerick: yup

8:18 Raynes: I felt bad for not doing it. I totally would have, it just would have taken a while because I'm unfamiliar with most of those languages.

8:18 cemerick: well, then it's good that you didn't :-)

8:19 Raynes: It would have taken me a while because I would have written *good* examples.

8:19 Asshole.

8:19 cemerick: I wanted the resulting code to be somewhat idiomatic, since it'll be used for public examples/documentation.

8:19 :-P

8:19 Raynes: I've got friends proficient in every language under the sun. Somebody would have reviewed my code.

8:19 :p

8:20 cemerick: Raynes: I welcome your haskell examples, using the JVM lib via whatever they use for C++ calls

8:20 Raynes: Scary.

8:20 cemerick: did that in python once

8:55 varioust: exit

9:36 Raynes: Just wrote a 3685 word guide to laser.

9:36 I am satisfied with myself, to say the least.

9:39 hyPiRion: Sounds long

9:41 Raynes: hyPiRion: Sounds awesome, you mean.

9:42 hyPiRion: Well, they're not mutually exclusive.

9:42 xeqi: sounds like its almost one yegge long

9:42 hyPiRion: Okay, wasn't as long as I feared it would be

9:43 Raynes: It is meant to be thorough. :p

9:45 hyPiRion: At least it's not like me, I sometimes have longer commit messages than the commits themselves.

9:45 ro_st: writing a technical book will beat that right out of you -grin-

9:46 last time i tried to write a tech book i nearly died.

9:46 Raynes: ro_st: I was writing a book, but I hit pause for now.

9:47 hyPiRion: Funfact: this guide is longer than laser itself.

9:52 hyPiRion: Raynes: I think a lib I made has more lines with docstrings than code.

9:53 Urgh. Actually, 3685 is totally fine.

9:54 After looking at my own docs, 3685 is succinct.

9:59 Raynes: hyPiRion: The fact that you write a lot of documentation isn't necessarily a bad thing.

9:59 hyPiRion: https://github.com/hyperion This isn't you, is it?

10:01 hyPiRion: Raynes: yes.

10:01 Raynes: Really?

10:01 hyPiRion: Wait, hyPiRion it is

10:01 babilen: :-D

10:01 Raynes: I was about to say

10:01 hyPiRion: I said yes to "This isn't me".

10:02 Raynes: If this guy is you, you sure are a majestic and handsome feller.

10:02 hyPiRion: And apparently Greek too.

10:02 Raynes: Yeah, definitely not as majestic as this other guy.

10:02 hyPiRion: Well, Russian, but both are Greek to me anyway.

10:02 Raynes: He is remarkably picturesque.

10:03 hyPiRion: Raynes: If I photoshop a crown on top of my head, would that make me more majestic?

10:03 Raynes: hyPiRion: Wow, you were boring as hell from June to October.

10:03 https://github.com/hypirion

10:04 hyPiRion: Raynes: On github, yes.

10:04 Raynes: I'm looking at all your private code too though.

10:05 I traced your IP address with a visual basic program and hacked in.

10:06 hyPiRion: Well damn it

10:06 You got me there.

10:07 Raynes: I was generally boring as hell pre October really

10:08 S11001001: Raynes: a visual basic gui?

10:09 Raynes: S11001001: Definitely.

10:09 S11001001: Well, I traced the physical location of the binary from hyPiRion

10:10 hyPiRion: I'm apparently a lucrative target for hackers.

10:11 juxovec: isn't APL more suitable for this kind of job?

10:20 Raynes: hyPiRion: You're a pretty cool guy for a new guy.

10:20 I'm probably exaggerating 'new', but I only noticed you coming out of your shell at least in the past maybe 2 months.

10:21 I like active new guys. <3

10:22 hyPiRion: Raynes: heh, thanks

10:23 I appreciate it :)

10:23 Raynes: It's weird how I can still pick new people out of a crowd of over 500.

10:24 "Oh, cool, never seen him send a leiningen patch before."

10:24 "TARGET ACQUIRED. BEGIN SURVEILLANCE."

10:26 hyPiRion: Hmm, that's also a way of finding out, but it has one flaw though

10:27 "Huh, who is Rich Hickey? Never seen him send in a Leiningen patch"

10:27 Raynes: lol

10:27 hyPiRion: "Must be a new kid"

10:27 Raynes: I was implying that it was merely one method.

10:27 S11001001: would be accurate hyPiRion :)

10:27 * nDuff wonders where he fits in (as someone who mostly doesn't use Leiningen)

10:27 Raynes: I also know, for example, that S11001001 is not as active as either of us, but still talks on occasion, while juxovec was pretty much just born here.

10:29 uvtc: Raynes: could you please send me a copy of hyPiRion's dossier? I seem to have misplaced my copy since the last insider's meeting.

10:29 hyPiRion: juxovec sounds like a combination of juxt and vec.

10:29 juxovec: Raynes I am very new to Clojure and all the functional programming world

10:30 getting thru SICP days and nights these times :)

10:30 hyPiRion: I like that.

10:31 uvtc: Oh fiddlestix; that was my best joke all morning.

10:31 Raynes: juxovec: Welcome!

10:31 juxovec: I for one am very happy to have you. :)

10:31 I can already tell that we'll be the best of friends.

10:31 juxovec: thanks a lot :)

10:32 uvtc: juxovec, are you using a Scheme, or using Clojure with SICP?

10:32 juxovec: mit-scheme

10:32 and trying the same things in Clj too

10:35 uvtc: Sounds fun. I haven't gotten as far as I'd like in that book. The "counting change" example was pretty darn amazing to me. Should probably go back with Clojure in-hand.

10:35 juxovec: after 2 weeks playin with clj I finished small affiliate server + I am finishing some helper app for my fiancee's job. And I really like (this (new (approach))) :)

10:35 Raynes: :D

10:38 clgv: juxovec: better (approach (new (this))) in terms of execution order or (-> (this) new approach) ;)

10:40 juxovec: clgv:correct :)

10:43 after 14 years of imperative/oop programming, there's only one problem. I don't see places where I can use macros. I am comfortable with functions all the day, but I realize that there absolutely new space in reaching DRY with macros.

10:45 foodoo: juxovec: The first rule of the macro club is: Don't write macros

10:46 juxovec: If functions help you enough with DRY, then everything is fine

10:47 Raynes: juxovec: That's a good thing.

10:51 juxovec: foodoo: the thing is that there maybe are places where I can use macro. I just doesn't see it because I am in the prison of "use given syntax and don't complain"

10:52 clgv: juxovec: you will notice macro application opportunities when you notice "thats absolutely similar code structure but I cannot implement that structure only with functions and higher order functions"

10:52 nDuff: juxovec: ...well, it's better to start by finding a place when you want to do something but can't without them.

10:52 juxovec: macros are great when you need them, but they're trouble when they're a solution in search of a problem.

10:55 Raynes: Have solutions, will trade for problems.

10:55 juxovec: most of the time, I doesn't feel I need macro

10:56 I used them, when I started making my own HTML form generator (http://pastie.org/5648725)

10:56 francis: juxovec: clj-record is a great example of using to many macros

10:56 juxovec: you can view the author's apology here: http://elhumidor.blogspot.com/2012/11/why-not-to-use-my-library-clj-record.html

10:57 juxovec: so I can write (required ... other validation rules ... )

11:01 jsabeaudry: When looking at ring-jetty-async-adapter I see that it is 2 years old, is it stable or unmaintained?

11:14 TimMc: Raynes: An advantage of Enlive's CSS selectors, unless I misunderstand them, is that you can parameterize them without bothering with CSS encoding functions.

11:15 Raynes: You know what would be fantastic? If I could write ["div.foo input[name=${bar}]" input-name]

11:15 err, {:bar input-name}

11:15 Raynes: I guess, but I don't really see how it's any better or worse.

11:16 TimMc: Because it means you're not doing string concatenation, wherein lies sorrow, madness, and broken sites.

11:16 Raynes: I meant the paramertizing enlive selectors.

11:16 parameterizing*

11:16 TimMc: Abstraction, broseph.

11:17 Raynes: Still not clicking.

11:17 TimMc: I'd like to write funcitons that take in parameters such as field names and do HTML transformations that target those fields.

11:18 Maybe I'm wrong about something in Enlive, let me check...

11:18 Raynes: I don't see why you couldn't do that with laser.

11:18 TimMc: If your suggestion involves a call to str I'm going to frown very hard at you.

11:19 Raynes: *shrug*

11:19 TimMc: Raynes: o\__/o

11:20 (str "div.foo input[name=\"" (escape-css-attr-value input-name) "\"]") is asking for trouble.

11:21 THat approach will result in anything from randomly broken code to an exploitable security hole.

11:22 Raynes: TimMc: I was saying I don't see why you can't do it with regular selector functions.

11:23 Laser doesn't do css selectors at all for the time being. I don't really care about them, so it'll be a thing I do when I get bored or something someone else does because they want them that bad.

11:26 TimMc: Sure, it's just a thing to keep in mind.

11:33 wingy: there is a fn that returns what is passed to it i think .. what's the name of it?

11:33 Raynes: identity

11:33 TimMc: $findfn 5 5

11:34 * Raynes takes a nap while findfn works.

11:34 lazybot: [clojure.set/union clojure.set/intersection clojure.set/difference clojure.core/time clojure.core/dosync clojure.core/long clojure.core/short clojure.core/+ clojure.core/* clojure.core/doto clojure.core/unchecked-long clojure.core/+' clojure.core/unchecked-short... https://www.refheap.com/paste/8226

11:34 wingy: yeah

11:34 TimMc: mua ha ha

11:34 WAKE UP RAYNES

11:34 Raynes: NERRRR

11:35 TimMc: &(* "hello!")

11:35 lazybot: java.lang.ClassCastException: Cannot cast java.lang.String to java.lang.Number

11:35 yogthos: TimMc: hey did that markdown-clj change make any difference? :)

11:36 TimMc: I dunno, it wasn't my bug.

11:36 cjfr<TAB> was the one who discovered it

11:36 I was jsut the one who decided to yell at you for using with-redefs. :-P

11:36 Raynes: TimMc: Also, cegdown, cause I like competing with yogthos.

11:37 yogthos: lol

11:37 Raynes: oh yeah should we stick that into lib-noir so we can provide md->html thingie? :)

11:37 Raynes: yogthos: Sure, we can do that. Even with pegdown as a dependency I think it's pretty lightweight.

11:38 yogthos: Raynes: I think so :)

11:43 TimMc: Grah, I still don't understand why (/ 0.0) throws and (/ 1 0.0) doesn't.

11:44 THe unary / doesn't inline, and just calls the binary version with a first arg of 1.

11:53 S11001001: TimMc: does the binary one inline?

11:53 TimMc: Yes.

11:53 Hmm, do you suppose that the unary's call to the binary *doesn't* inline?

11:53 S11001001: for the unary case are you inlining (/ 1 0.0), or (/ 1 n)?

11:55 TimMc: ([x] (/ 1 x)) https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L972

11:55 S11001001: great minds

11:55 TimMc: In that instance, it doesn't know that x is a double, so I guess it goes to the general case...

11:56 &(let [x (identity 0.0)] (/ 1 x))

11:56 lazybot: java.lang.ArithmeticException: Divide by zero

11:56 TimMc: Oho!

11:57 https://github.com/clojure/clojure/blob/clojure-1.4.0/src/jvm/clojure/lang/Numbers.java#L153

11:57 ^ if (yops.isZero((Number)y))

11:57 Seems a bug to me.

12:09 hyPiRion: ,(/ 0.0 0.0)

12:09 clojurebot: NaN

12:10 peat: If any Clojure/Twitter hackers are intrested, the twitter-api project is working on Twitter API v1.1 support. If anyone is curious, or wants to help test the pre-release branch: https://github.com/adamwynne/twitter-api/tree/resource-naming

12:12 TimMc: &((juxt (comp) #(%%%)) 5)

12:12 lazybot: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn

12:14 TimMc: &((juxt (comp) #('%%%)) 5)

12:14 lazybot: ⇒ [5 5]

12:14 TimMc: hyPiRion: ^ a shorter identity

12:14 for all your golfing needs

12:15 jlewis: or #(do %)

12:15 TimMc: Hmm, if you don't count spaces, that is the same length.

12:16 &((juxt (comp) #('%%%) time) 5)

12:16 lazybot: java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/time

12:16 TimMc: oh right

12:17 jlewis: i don't understand what #('%%%) is

12:17 TimMc: ,(min "g")

12:17 clojurebot: "g"

12:17 technomancy: in the shower this morning I actually came up with a justifiable use for a juxt inside a juxt.

12:17 TimMc: juxtifiable

12:18 OK, min is a clear winner

12:18 technomancy: aw yeah

12:18 uvtc: teehehe

12:18 tmciver: technomancy: hey, what a man does in the shower is nobody's business.

12:18 TimMc: tmciver: Except when it's code golfing.

12:18 jlewis: ooh, min.

12:18 gfredericks: amalloy_: ping?

12:20 TimMc: &((juxt (comp) comp) 5)

12:20 lazybot: ⇒ [5 5]

12:20 TimMc: \o/

12:21 jlewis: ##'#('%%%)

12:21 lazybot: ⇒ (fn* [p1__194818#] ((quote p1__194818#) p1__194818# p1__194818#))

12:21 jlewis: ummm...

12:21 i don't think that clears anything up :)

12:22 Raynes: drewr: Hey Mr Last Name Sounds Like My Nickname. Why does postal require :from? You can configure this for sendmail outside of postal. Not even sure what to put there.

12:23 drewr: Raynes: haha.. re: names I had no choice

12:23 gfredericks: amalloy_: unping

12:24 drewr: Raynes: the purpose of postal was to quickly generate a well-formed rfc822 message in a clojurey way, and send it via SMTP to a smart host

12:24 that's the case it's optimized for

12:24 but I'm curious -- why would you construct a message without from:?

12:25 you can always set the envelope sender to something else

12:25 Raynes: drewr: It doesn't seem to do anything after I configured it in main.cf. I can put "random person" and I still get the thing I put in main.cf.

12:26 drewr: sure, sendmail is going to have the last word if you're using it as the transport

12:26 it can do whatever it wants to your headers (and more!)

12:26 TimMc: jlewis: Simplified: (fn* [arg] ('arg arg arg))

12:27 jlewis: Since 'arg is a symbol, unrelated to the value being passed in, it tries to look itself up in arg.

12:27 Raynes: drewr: I just figured that since you supported sendmail, :from could be optional. It doesn't seem to actually matter though.

12:27 TimMc: Since it inevitably fails, being a gensym, it defaults to the second argument: arg

12:27 jlewis: Blame hyPiRion.

12:27 Raynes: But disclaimer: I do not know how mail works at all.

12:29 drewr: postal also uses from: to populate the envelope sender so you don't have to explicitly define both

12:30 jlewis: TimMc: *shudder*

12:30 Raynes: So there are reasons for :from that I can't see, which would make it bad for me to give it a bogus value? The problem I'm facing at the moment is that I expect sendmail to be configured however and I don't have access to that information.

12:30 clgv: when I want the same function to handle a route for GET and POST how do I define that in compojure?

12:30 jlewis: TimMc: but kind of awesome, i admit.

12:32 weavejester: clgv: You can have both routes call the same function. Or if this is a common problem and not an exception, you can define some middleware.

12:32 iwo: hey, does anyone know how to do the reverse of clojure.data.xml/sexp-as-element?

12:33 clgv: weavejester: ah ok so there is no built-in abbreviation to write it only once?

12:33 iwo: i have some xml and i'd like to create an sexp that represents that xml, the structure of the sexp should be the kind of thing that sexp-as-element accepts

12:33 weavejester: clgv: No, because strictly speaking it's not good practise. There are exceptions, especially when integrating with legacy systems, but they tend to be rare.

12:34 TimMc: &((comp (comp comp) (comp)) 5)

12:34 lazybot: ⇒ 5

12:35 iwo: clojure.data.xml/parse appears to create a more verbose structure with keys like :content and :attrs

12:36 TimMc: &((comp (comp ((comp) comp) comp) comp (comp)) 5)

12:36 lazybot: ⇒ 5

12:36 TimMc: OK, I'm done.

12:37 egghead: (def dove (comp comp))

12:37 technomancy: egghead: spoilers!

12:38 egghead: true

12:38 hyPiRion: TimMc: My identity fn is swearjure-usable

12:38 :(

12:38 egghead: I just wrote a blog post on to mock a mockingbird, good stuff

12:39 TimMc: True, that is an... advantage.

12:39 technomancy: egghead: linky?

12:39 I got stuck right around the dove and have been meaning to circle back to it

12:39 hyPiRion: indeed. Very practical when you're goofing off trying to do nothing.

12:40 egghead: heh, it's a little long winded technomancy and uses js for the example code: http://samesake.com/log/2013/01/03/Three-little-birds/

12:40 clojurebot: http://homepages.inf.ed.ac.uk/kwxm/JVM/codeByNo.html

12:40 egghead: basically just explains the y combinator in terms of smullyan birds

12:40 hyPiRion: TimMc: ##(= 5)

12:40 lazybot: ⇒ true

12:40 egghead: culminates in the horrible assignment free factorial at the bottom :p

12:41 technomancy: cool

12:41 hyPiRion: oh right, damn.

12:41 ,(or 5) ;then

12:41 clojurebot: 5

12:41 egghead: technomancy: I was blown away when I saw that BML was the y combinator

12:42 technomancy: I wonder if I can still find my mockingbird notebook

12:42 jlewis: hyPiRion: or's a macro, not a function, though.

12:44 iwo: i guess i need to parse xml to hiccup-style data structre

12:47 hyPiRion: jlewis: so the goal is the shortest form such that (apply form id) = id ?

12:48 TimMc: hyPiRion: Just a replacement for identity.

12:48 as in (filter ___ coll)

12:49 hyPiRion: kay.

12:50 gtrak: oh jeez it's abusing the fact that symbols look themselves up and can give a default instead

12:50 seangrove: Is there a way to pass flags to the closure compiler using cljsbuild? It just seems to be ignoring the :debug setting

12:51 gtrak: all to save 1 letter

12:51 hyPiRion: gtrak: But that one letter. Think of the trees!

12:51 gtrak: we really should huffman-encode clojure's core.clj

12:52 or just the vars

12:54 hyPiRion: ,(filter _ [1 2 nil true false])

12:54 clojurebot: (1 2 true)

12:54 TimMc: !

12:54 hax

12:54 hyPiRion: bzz, wish it came in Clojure.

12:58 egghead: &(letfn [(starling [a] (fn [b] (fn [c] ((a c) (b c))))) (kestrel [a] (fn [b] a)) (identity [a] (((starling kestrel) kestrel) a))] (identity (rand-int 100)))

12:58 lazybot: ⇒ 47

13:01 egghead: I was looking at shens automatic partials, looks so nice, wish clojure supported that

13:02 (* 2) for instance is a valid expression which means the same as (partial * 2)

13:02 clojurebot: #<RuntimeException java.lang.RuntimeException: java.lang.NumberFormatException: For input string: "*">

13:02 TimMc: egghead: * is binary in shen?

13:02 egghead: I believe it's variadic like clojures

13:03 * TimMc dubiouses

13:03 hyPiRion: Can't be 0 or 1-arg though.

13:03 TimMc: Type inference?

13:03 egghead: http://www.shenlanguage.org/learn-shen/tutorials/shen_in_15mins.html f3 for 'partial'

13:06 Raynes: drewr: I'm trying to send an HTML email, but images aren't loading in anything but gmail's web app and my iPhone.

13:06 I'll get you an example.

13:07 drewr: https://www.refheap.com/paste/8230 <-- See anything obvious that might be wrong with this.

13:07 drewr: Note that I can send this with Commons Email and it works fine.

13:07 TimMc: Raynes: href="

13:08 Raynes: Oh, that was a transfer typo.

13:09 https://www.refheap.com/paste/8231

13:09 egghead: how is geni, you guys are right around the corner

13:09 figuratively

13:09 drewr: Raynes: could be a bug; do you have the commons code? I want to check the difference in generated javamail Messages

13:09 Raynes: egghead: Yeah, around the corner and two thousand miles away until next month.

13:10 drewr: I can send an email with both things and then send you the source that my email client receives. Will that work?

13:10 drewr: Raynes: it might be sufficient

13:10 let's try that first

13:10 Raynes: Alright, give me a sec.

13:10 egghead: We're great. We just got acquired.

13:11 egghead: nice, congrats :)

13:11 technomancy: Raynes: no kidding? how's that going?

13:11 Raynes: technomancy: Great. We keep our team, I get a full time job, etc.

13:12 And Geni doesn't go away. We actually got to make a bunch of stuff free that didn't used to be free.

13:12 technomancy: good deal

13:13 TimMc: Raynes: And I assume this isn't just your mail client blocking external images?

13:13 Raynes: TimMc: It isn't. I've checked in a couple of clients and confirmed that to be off in all of them.

13:14 TimMc: I used to write HTML emails for a job a few years back. It was a nest of compatibility vipers.

13:14 We actually managed to crash a few customers' computers in one mailing...

13:16 Raynes: drewr: https://www.refheap.com/paste/8232 from postal.

13:17 antoineB: hello, i followed this http://ujihisa.blogspot.fr/2011/12/read-raw-post-request-body-in-compojure.html to get the :body part of a POST, but the HttpInput give me nothing?

13:21 Raynes: drewr: Well, actually, the problem with the above example was href != src, and I'm tired enough to not notice that.

13:21 It actually works if I change it to src. But my larger HTML example still only works in certain clients. Unfortunately, I can't show that to you. :\

13:22 I guess I'll need to investigate more and see if I can narrow anything down and get a reproduce case I can actually show you.

13:26 TimMc: Raynes: derp!

13:26 I should have caught the src thing.

13:27 Raynes: TimMc: Yeah, but it's still all screwy with the real HTML. :(

13:27 And only with postal. It's crazy.

13:27 TimMc: Oh! Weird.

13:27 Raynes: I can send the exact same HTML with commons email and it works fine.

13:28 So it makes me wonder if it might be some kind of formatting problem in postal, but I can't reproduce without the huge private HTML I've got here.

13:29 TimMc: It's showing alt text in Postal.

13:29 Ugh. Postbox

13:29 Sorry, guys, I'm on no sleep.

13:29 TimMc: If it is showing alt text, I guess that means it parsed the img tag but merely couldn't resolve the image for some reason?

13:29 seangrove: Ah, damnit

13:31 I need a file from closure.jar that wasn't added until oct. 26th, and was last updated nov. 12th. The cljs closure.jar is pretty far behind

13:33 Raynes: drewr: Looks like it only happens when postal sends as quoted printable.

13:34 drewr: How can I make postal send with quoted printable?

13:34 TimMc: Raynes: Correct re: alt text

13:38 antoineB: ok, i suspect the HttpParser, being already parsed by "wrap-param" ring middleware

13:39 drewr: Raynes: momentito

13:39 Raynes: can you give me the source of a message that renders correctly for you?

13:40 ...in the client that was giving you trouble

13:40 Raynes: Sure, one second.

13:41 drewr: https://www.refheap.com/paste/8233

13:42 Sent with https://www.refheap.com/paste/de8ba8549b55df52dcc4053e5

13:42 drewr: that one renders correctly or incorrectly?

13:42 Raynes: Correctly.

13:42 drewr: it's 7bit though

13:43 Raynes: Yeah, I can't figure out how to force quoted printable.

13:43 The failing email gets sent in it, but I don't know what triggers it.

13:44 Also, I noticed that there is a difference between the encoded text from commons email and the encoded text postal sends.

13:44 Not sure if its significant.

13:44 But they look quite a bit different.

13:51 Or not.

13:51 I guess I was seeing things, they look the same.

13:56 drewr: Raynes: what's the source of a commons-generated one look like?

13:57 Raynes: drewr: Alright, so the encoded body of both emails looks exactly the same. I don't think they are different at all. I'm tempted to run them through diff, in fact. And that's the part that I can't show you. Give me a sec and I'll paste the headers on both of these.

13:58 drewr: it would surprise me if they were significantly different since they both rely on javamail to handle attachment encoding

13:59 Raynes: drewr: https://www.refheap.com/paste/b6d0b201d76b25c436867b613 this is the version that postbox (and inky, and mail.app) both chew up and spit out that comes from postal.

13:59 drewr: https://www.refheap.com/paste/3494bb397f375b658fab1fdd2 is the working version from commons email

14:00 drewr: yeah, identical in the places that matter :-/

14:00 maybe something in the attachment body?

14:00 * drewr &

14:00 lazybot: java.lang.RuntimeException: EOF while reading

14:00 Raynes: Attachment body?

14:01 drewr: (the html.. in the mime part)

14:01 estebann: lein uberjar works well for me when :omit-source is not set to true, but when it is I get: "Could not find or load main class" when I try to run the jar, any thoughts?

14:01 drewr: gotta get some food

14:01 Raynes: drewr: The HTML is the same in both versions, and it works with commons.

14:06 DaReaper5: How do i increment a value within an agent that is a map

14:07 (send-off agentMap assoc key (+ (@agentMap key) val))

14:07 above does not work due to asych issues

14:07 gtrak: DaReaper5: update-in

14:08 DaReaper5: (update-in agentMap [key] + val) ?

14:08 Raynes: drewr: Well, I've got to take off for the night. If you happen to have any magic ideas that I could try, let me know. Otherwise, I'll spend some time later/tomorrow trying to come up with a reproduce case with some different HTML. FWIW, shelling out to sendmail doesn't seem to be working for this either.

14:09 gtrak: yea, if you wanted to make what you wrote work, you would capture the value in a closure instead of derefing twice

14:09 drewr: Raynes: I can't think of what you can do; if the source is the same I'm not sure how postal could be causing the problem

14:09 let me know if you notice any differences

14:09 very curious

14:10 TimMc: Raynes: for the night... did you sleep last night, or move to Europe?

14:10 *not sleep

14:10 Raynes: I didn't sleep last night, TimMc.

14:10 TimMc: >_<

14:11 gtrak: DaReaper5: in other words, send-off acts like apply for convenience, but it only needs a fn of 1-arg

14:12 (send-off agentMap update-in [key] + val)... I don't know if that'll work, that's too much indirection for me..

14:13 (send-off agentMap #(update-in % [key] + val)) is more clear

14:14 maybe it's meant to be used the flat way, try it :-)

14:19 riley526: Quick question: Given a Compojure route handler function, how do you get the route's URL?

14:20 technomancy: riley526: :path IIRC

14:20 or maybe :uri?

14:21 riley526: technomancy: thank you, I'll look into that.

14:28 DaReaper5: hi am back sorry. What was the suggested usage of send-off and update-in?

14:28 riley526: technomancy: Is that documented somewhere?

14:29 technomancy: riley526: it's part of the Ring spec

14:30 pmonks: @DaReaper5: "gtrak: (send-off agentMap update-in [key] + val)... I don't know if that'll work, that's too much indirection for me.."

14:30 gtrak: DaReaper5: well, send-off passes the value of the agent into the function and applies the args from in the second to nth position, and update-in does a similar thing, so perhaps maybe it'll do the right thing if you write it all flat

14:30 pmonks: @DaReaper5: "gtrak: (send-off agentMap #(update-in % [key] + val)) is more clear"

14:30 gtrak: if you want to be explicit about it, you can do it the way I mentioned

14:31 DaReaper5: thanks!

14:32 gtrak: (update-in x [k] + val) is like (update-in x [k] #(+ % val)), a similar trick

14:35 riley526: technomancy: Oh I see. I don't think :uri is what I'm looking for. That gets the path for the given request. I'm looking for a way to reverse a Compojure route handler to get its URL. Is there such a thing?

14:36 technomancy: Like Django's `reverse()` https://docs.djangoproject.com/en/dev/ref/urlresolvers/#django.core.urlresolvers.reverse

14:36 gtrak: riley526: there's no general solution for that.. you'd have to invert the computation. maybe core.logic :-)

14:38 riley526: gtrak: Alright thanks.

14:38 svedubois: How I can convert this java line to clojure?

14:38 new long[]{ 20, 30, 40 },

14:38 S11001001: riley526: what gtrak implies is that the reverse function you posted doesn't do what you say, and in fact the django docs admit to that

14:39 bpr: &(long-array [20 30 40])

14:39 lazybot: ⇒ #<long[] [J@4c0e1f>

14:40 bpr: svedubois: ^

14:40 S11001001: svedubois: unless you didn't mean that absolutely literally

14:40 svedubois: java arrays aren't as common in clojure as in java

14:41 nDuff: svedubois: the common/native thing would be to just use a vector: [20 30 40]

14:41 bpr: yeah, that's true. typically you'd just want [20 30 40]

14:45 riley526: S11001001: I'm not sure what you mean. Can you elaborate?

14:45 S11001001: riley526: quote: "The reverse() function can reverse a large variety of regular expression patterns for URLs, but not every possible one."

14:46 svedubois: This java line could be translated to this ?

14:46 final Img< FloatType > img1 = imgFactory.create( new long[]{ 20, 30, 40 }, new FloatType() );

14:46 (def ^FloatType img1 (-> (imgFactory) (.create (long-array [20 30 40]) (FloatType.))))

14:47 gtrak: riley526: you could probably mimic what django does, but there's also no way to access routes globally right now.

14:47 S11001001: svedubois: don't use def

14:48 svedubois: let?

14:48 clojurebot: let is creating a local binding in your lexical scope

14:48 riley526: S11001001: Yes, I'm aware of that, but that doesn't mean it isn't useful. I'm just wondering how other people avoid hard-coding URLs in other places (e.g. template rendering).

14:48 bpr: this looks more correct (based on the java snippet): (-> imgFactor (.create (long-array [20 30 40]) (FloatType.)))

14:48 riley526: But maybe that's not what Compojure is meant for anyway.

14:48 S11001001: riley526: reverse would make a poor solution to that problem, given its non-totality.

14:48 unreliability, rather

14:49 svedubois: bpr: java.lang.IllegalArgumentException: No matching method found: create for class clojure.lang.Var$Unbound

14:49 bpr: svedubois: actually in that case i wouldn't even use the thread-first macro. just: (.create imgFactory (long-array [20 30 40]) (FloatType.))

14:49 riley526: S11001001: Agreed.

14:49 gtrak: django can say 'here's the django way', compojure can't make religious arguments as much

14:50 bpr: svedubois: yeah, i mis-typed imgFactory in the first attempt

14:51 svedubois: bpr: (.create imgFactory (long-array [20 30 40]) (FloatType.))

14:51 java.lang.IllegalArgumentException: No matching method found: create for class clojure.lang.Var$Unbound

14:51 bpr: svedubois: can you paste your code somewhere?

14:52 gtrak: svedubois: imgFactory would be the unbound thing

14:52 svedubois: bpr: https://github.com/imagej/imglib/blob/master/imglib2/examples/src/main/java/Example1c.java

14:53 gtrak: Yes, you are right

14:53 (def ^FloatType imgFactory (^FloatType CellImgFactory. 5))

14:53 (.create imgFactory (long-array [20 30 40]) (FloatType.))

14:53 It works

14:53 #<CellImg CellImg [20x30x40]>

14:53 bpr: good

14:58 aaelony: hmmm, the following works: ((juxt :c :b :a) {:a 1 :b "blah" :c 3}) but if I put it in a function I get an "clojure.lang.ArraySeq cannot be cast to clojure.lang.IFn" https://www.refheap.com/paste/8247

14:59 amalloy: svedubois: those ^FloatType hints are just getting ignored by the compiler and making the code harder to read

14:59 aaelony: (apply juxt ks)

14:59 aaelony: do'h

14:59 amalloy: although really a better solution to the problem is (map m ks)

14:59 aaelony: amalloy: thanks

15:01 dnolen: the perf boost for small maps in 1.5.0 is nice

15:03 svedubois: amalloy: Can you elaborate the way to work with ^FloatType hints?

15:04 S11001001: svedubois: get it working without hints first.

15:04 amalloy: don't put them there. the compiler already knows what (CellImgFactory. 5) returns

15:04 ohpauleez: then see where the compiler is hitting the need for deep reflection, and hint at those spots

15:04 TimMc: ...but only if performance demands it!

15:05 ohpauleez: I'm of the opinion you should always remove points of reflection once you have something working and refactored

15:06 technomancy: that's just busy work

15:06 amalloy: i prefer the noncommittal "you may always..."

15:06 svedubois: ohpauleez: How I can know where the compiler is hitting the need for deep reflection?

15:07 cemerick: dnolen: I didn't follow the thread(s) carefully; have you benched small map vs. records?

15:07 S11001001: svedubois: We're saying that you shouldn't think about that at all yet.

15:07 technomancy: spending time thinking about reflection before it's proven to be a bottleneck is a waste of time

15:09 dcb: Is there a simple way to have an agent loop on a function? IE fill its queue so a function is always in its queue?

15:09 bpr: dcb: i would say use a future with a loop for that

15:11 dcb: bpr: My use case is I want the agent to run for a set amount of time (say 5 minutes) and complete as many iterations of the function as it can, but all from the same thread. If I have futures in a loop that could parallelize it to many threads, right?

15:12 gtrak: dcb: that sounds like not a queue at all, but a loop

15:13 or a seq

15:13 bpr: dcb: i meant something like: (future (loop ...))

15:13 dnolen: cemerick: I haven't done any testing like that

15:13 bpr: yeah, good point: (future (doseq ...)) could work too

15:15 dcb: gtrak: yes, but id like it to be interruptible, which I think you can do with (shutdown-agents)

15:15 dnolen: cemerick: but they seem 2X faster which is never a bad thing

15:16 seangrove: dnolen: Are source-maps blocked, or just not much time to work on them with all the core.logic stuff?

15:17 dnolen: seangrove: blocked by 1.5.0 and no tools.reader

15:17 seangrove: as soon as that story changes it will move very quickly.

15:17 seangrove: Is there a ticket I can subscribe to?

15:17 bpr: dcb: (let [stop? (atom false)] (future (loop [...] (when-not @stop? ...))) (fn [] (swap! stop? true)))

15:17 dnolen: seangrove: hmm not really, but bump the thread on the dev list

15:17 bpr: meh... s/swap!/reset!/

15:18 seangrove: Willdo

15:19 arrdem: what place does testing have in your clojure devel cycle? do you do test-driven or do you test and repl to correctness and test after the fact?

15:19 dcb: bpr: cool, I definitely didn't think about that, thanks

15:19 gtrak: thanks as well

15:19 amalloy: bpr: (swap! stop? not), for style points

15:19 bpr: amalloy: nice. thanks

15:20 amalloy: (don't actually do that, it's ugly. reset is better, but this is funnier)

15:23 seangrove: arrdem: generally repl to correctness, then maybe write a test to make sure it doesn't break later

15:23 But certainly far fewer tests than in other languages

15:25 arrdem: seangrove: mmkay. that's what I was expecting. just pondering cultivating (or not) an OO style testing "habbit".

15:26 aaelony: amalloy: (map m ks) is quite elegant. Is there something like that for the case where keys may contain nested maps? Trying to avoid a massive let statement with get-in calls...

15:27 amalloy: i don't understand "keys may contain nested maps"

15:28 carlocci: hello, is leiningen named after the ant fighting guy?

15:28 hiredman: yes

15:28 amalloy: it'd be quite a coincidence otherwise, i suspect

15:28 aaelony: oh, {:a 1 :b { :bee-1 "blah" :bee-2 {:cee 4} } :c 3 }

15:29 carlocci: is there some meaning behind?

15:29 metellus: ant is a Java build tool

15:29 or something like that

15:29 carlocci: ok, that makes perfect sense

15:30 thank you

15:31 amalloy: aaelony: so? calling (m :b) on that works fine

15:31 if you want the ability to use get-in instead, use get-in: (map #(get-in m %) keyseqs)

15:33 arrdem: ,(let [m {:foo 1}] (assert (= (m :foo) (:foo m))))

15:33 clojurebot: nil

15:34 aaelony: amalloy: thanks. I want to guarantee a certain order and would like to specify the order up front. Then give the ordering to a function that retrieves that order from a map that has arbitrary levels of nestings.

15:34 it works, just wondering if it can be more elegant

16:29 alex_baranosky: have any of you seen a Compiler error: "Unknown Collection Type"?

16:29 no7hing: i'am writing a wrapper around the java skype api and kind of wonder how i get clojure reflection and reify on the same boat

16:29 alex_baranosky: I'm seeing it moving a macro that worked on 1.2.1 to 1.4

16:30 no7hing: this screams to be DRY'ed up: https://www.refheap.com/paste/8250

16:30 S11001001: no7hing: the return type of create-connection-listener isn't inferred

16:31 no7hing: and this is more a macro case than a reflection case

16:32 no7hing: sry for the confusion: the reflection is not in yet

16:32 i'am thinking about it, but don't want to start until i have an idea how it could look like

16:33 basically i want to generate the methods for 'reify' through reflection of the java listener interfaces

16:33 S11001001: no7hing: write a macro that takes the interface symbol, resolves it (getting the interface), etc

16:34 jlewis: anyone know the threshold of consecutive conj's after which it's better to make the collection transient first? is making it transient first always worth it, if you're doing more than 1 modification?

16:34 no7hing: hmm, damn, that would actually work

16:35 i was thinking too complicated - again

16:35 thanks!

16:36 S11001001: np

16:37 amalloy: jlewis: just use ##(doc into) and don't worry about it, most of the time

16:37 lazybot: ⇒ "([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined."

16:38 amalloy: alex_baranosky: i don't think so, but i'd be interested to see such a macro

16:39 jlewis: nice, i guess the fact that it's implemented to always use transient answers my question

16:39 thanks

16:40 amalloy: jlewis: creating a transient is a small O(1) cost, as is persistent!-ing a transient

16:40 you only pay for the changes you actually make

16:40 to me this seems like magic, but allegedly that is how it works

16:42 jlewis: I suppose it isn't particularly surprising - it could be a flag (and thread machinery, etc) that says to edit in place instead of path copying

16:42 assuming that last bit is implemented, of course

16:49 odie5533: Would clojure be a good language to use to learn functional programming?

16:50 egghead: ya

16:50 odie5533: k

16:50 egghead: there are others that some might argue would be better, scheme or shen, but I learned functional w/ clojure and enjoyed it immensely

16:50 hiredman: lisp is a great language for learning anything about the structure and interpretation of computer programs

16:53 egghead: I see what you did there.... :p

16:53 no7hing: sicp

16:53 sneaky

16:55 bpr: i really think SICP should be CS 101 everywhere

16:55 Sgeo_: I wish I went to a school that offered CS

16:55 Rather than some bs "Computer Programming/Information Systems"

16:55 arrdem: bpr: meh... Algo & Datastructures wasn't bad in Java

16:56 but I did read SICP on my own that year.

16:56 bpr: the concept of composeable abstractions is expressed more clearly in SICP than anywhere else i know of

16:56 arrdem: also, why will (contains?) never do a linear search?

16:57 hyPiRion: Well

16:57 ,(doc contains?)

16:57 clojurebot: "([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'."

16:57 technomancy: contains? is too cool for your linear data structures

16:58 hyPiRion: It looks up a key, not a value.

16:58 arrdem: I mean I see the evil O(N) case... but I'd think that as an "informed" programmer I can incur that cost if I want to.

16:58 and (contains? (set [:foo :bar :baz]) :baz) is still O(N)...

16:59 hyPiRion: arrdem: contains? doesn't cause that, though. That's the conversion to the set.

16:59 hiredman: you are also free to use the java collections api

16:59 (.contains ...)

17:00 arrdem: hyPiRion: well right. I'm just askin' here.

17:00 hiredman: arrdem: if you are doing lots of O(n) operations you should pick a different datastructure where that operation is O(1)

17:01 hyPiRion: Nothing like bacon and premature optimization for dinner, eh.

17:01 no7hing: hmm, (defmacro [interface] (let [members (:members (r/reflect interface))] )) always reflects a clojure var - how can i force evaluation of 'interface' ?

17:02 where r/ref… is clojure.reflect/refl...

17:06 alex_baranosky: amalloy: we found it. The old code had a macro with a syntax quote like this `(f ~a '~regex-patterms) … we changed it to `(f ~a `(vec regex-patterns)) which now compiles

17:07 amalloy: well, that should compile but give a totally different result, right?

17:08 alex_baranosky: shoot I had a typo, should be: `(f ~a ~(vec regex-patterns))

17:11 no7hing: silly me, i was actually working with the clojure symbol not the resolved interface

17:12 weavejester: Does anyone have any suggestions for libraries I've missed on clojure-toolbox.com?

17:12 I'm giving it some long overdue updates.

17:12 bpr: Raynes' conch

17:13 amalloy: weavejester: i wouldn't include algo.monads without including the much-superior protocol-monads, whichever fork of that is active these days

17:13 technomancy: weavejester: why not look through the top-ranked libs on clojuresphere?

17:13 amalloy: and take sexpbot off the irc-bot list; he's long since dead

17:13 technomancy: might be a good starting place

17:14 weavejester: All good points

17:14 ian_: I'm using Noir. Is there a way to destructure a list of HTTP request parameter values into a variable? The Servlet api allow one to get a List<String> of values given an HTTP parameter name, but I can't figure out how to get that in Noir.

17:14 technomancy: (clojure.set/difference (take 100 clojuresphere/libs) clojure-toolbox/libs)

17:14 Bronsa: also http://clojure-libraries.appspot.com/

17:15 weavejester: ian_: You mean variables with the same name?

17:15 callen: is there a way to do global state that persists within a request's lifespan without using Kiln in Ring?

17:15 weavejester: Um, parameters with the same name

17:15 callen: Klin is a bit more complicated than I really need.

17:15 amalloy: i don't see anyplace for "handy datastructures", of which i have written a few. ring buffers, sets and maps that retain insertion order when seq'ing over them. people ask for those moderately often

17:15 technomancy: Kiln is more complicated than most people need from what I can tell

17:15 ian_: weavejester: Yes, the same param name

17:16 weavejester: ian_: I don't know whether Noir include wrap-nested-params by default

17:16 callen: technomancy: that's correct. I'd like something like Flask's g object.

17:16 weavejester: which because I couldn't work out a good way of parsing it

17:16 gtrak: callen: I find compojure's 'context' macro really useful for pulling request-scoped stuff into a binding

17:16 weavejester: currently means that if you want a multiple params *and* nested params, you need to name them like 'foo[]'

17:16 e.g. foo[]=bar&foo[]=baz

17:17 amalloy: oh, and a lot of people seem to use org.flatland/protobuf, weavejester (in addition to the other stuff i mentioned above but didn't highlight you on)

17:17 ian_: weavejester: Thanks for the help. I'll give that a try.

17:17 weavejester: But straight Ring will automatically parse parameters into lists if they have more than one value

17:17 callen: gtrak: if you're talking about what I think you are, that's pretty weak.

17:17 gtrak: so weak.

17:17 the weakest

17:18 it can easily be generalized into a function of the request

17:18 ian_: weavejester: it worked! Thanks.

17:19 is wrap-nested-params a ring thing?

17:19 callen: gtrak: I need something the templates can access without manually juggling a context map.

17:19 weavejester: ian_: I'm amazed you were able to understand my confusing explanation :)

17:19 ian_: yes. Ideally it should allow "foo=a&foo=b" as well as "foo[]=a&foo[]=b"

17:20 TimMc: weavejester: So if I give a ring app duplicate params, there's a good chance it will throw a type error because it expects a string instead of a list? :-P

17:21 gtrak: callen: context-map has nothing to do with it, it just prevents you from having to destructure too repetitively. The value's in a key on the request.

17:21 weavejester: TimMc: Well, yes...

17:21 gtrak: so I'm not sure what you think I'm referring to

17:21 callen: gtrak: that's far removed from the problem I was trying to address and is exceedingly trivial.

17:21 gtrak: I'm trying to do something analogous to auto-cycled global state triggered by serving a request.

17:22 gtrak: what's an auto-cycle?

17:23 TimMc: Lovely.

17:23 callen: gtrak: don't reify something that obviously isn't meant to be.

17:23 gtrak: and then pretend you're confused when you mis-reified a description of something

17:24 gtrak: sure...

17:24 ian_: Using hiccup, I'm doing a lot of stuff like this: [:ul (map #(vector :li %) (:values thing))]

17:24 Is there a more idiomatic way to do this?

17:24 TimMc: weavejester: Is there a different API for getting single value for a key vs. all of a key's values?

17:24 weavejester: TimMc: No, but I'm wondering if there should be.

17:25 callen: ian_: no, and there's not lot of redundancy there that a macro could help with either.

17:25 weavejester: Or whether to rely on something like a precondition

17:25 yogthos: weavejester: re: clojure toolbox clj-pdf? https://github.com/yogthos/clj-pdf :)

17:25 callen: ian_: you could write a function to wrap the iteration part of it.

17:25 ian_: callen: Thanks! I'm very new to clojure, so I'm still trying to figure out how bad my code is :)

17:25 aperiodic: ian_: [:ul (for [value (:values thing)] [:li value])] gets the point across a little more cleanly

17:26 hiredman: (defprotocol IMultiMap (multi-get [_ k default]) (multi-assoc [_ k v]))

17:26 yogthos: weavejester: this one also gets some usage and I'm maintaining fairly actively https://github.com/yogthos/markdown-clj

17:26 weavejester: and also have this :) https://github.com/yogthos/clj-rss

17:26 callen: ian_: nah that's not bad, but it's a pretty common pattern so you might as well write a function.

17:26 weavejester: ian_: A for loop loops better. Also… (unordered-list (:values thing))

17:27 ian_: Great, thanks, All.

17:31 gtrak: callen: looks like an interesting problem anyway

17:31 weavejester: yogthos: Added

17:31 gfredericks: why is clojure.java.jdbc/insert-records so crazy slow?

17:31 yogthos: weavejester: cool stuff :)

17:32 hiredman: gfredericks: I think because of the datastructure manipulation it does under the hood

17:32 weavejester: amalloy: Which libraries of yours are data structure libs?

17:32 yogthos: weavejester: oh and Raynes has https://github.com/Raynes/cegdown which is a pegdown wrapper

17:32 gfredericks: hiredman: I don't suppose you know if any of the other functions are faster?

17:32 callen: gtrak: it's really not and it is disconcerting that it's an otherwise unsolved problem save for Kiln.

17:33 amalloy: weavejester: flatland/ordered and amalloy/ring-buffer

17:33 callen: gtrak: http://flask.pocoo.org/docs/api/#flask.g

17:33 hiredman: I happen to have a clj file somewhere where we needed to load gigs of data as fast as possible, we ended up generating csv data and using database native stuff for loading from there

17:34 gfredericks: :/

17:34 weavejester: yogthos: Added that too

17:34 gfredericks: korma's even a whole lot faster

17:34 I was trying to speed _it_ up

17:34 hiredman: gfredericks: but between insert-records and that we switched to insert-rows

17:35 yogthos: weavejester: I'm still waiting for clojars to start tracking stats :)

17:35 gfredericks: how do I figure out what order to put the values in? do a select on the table and see what order they come back in?

17:36 hiredman: we would break the data up in to chunks of 10,000, and make a single transaction+insert-values call per 10,0000

17:36 gfredericks: I believe it is the order they are specified when creating the table

17:37 I forget how that works out with autogenerated keys

17:37 technomancy: yeah a lot less consing going on to insert in order

17:37 gtrak: callen: well, it looked interesting when I read about kiln. flask.g just looks like it could be implemented with a var.

17:37 weavejester: amalloy: I've added them in a Data Structures category

17:37 callen: gtrak: have you done much Ring?

17:37 gtrak: yea

17:37 yogthos: callen: could add something along those lines to lib-noir

17:37 callen: gtrak: you know, try that, let me know how it goes.

17:38 gtrak: report back when you figure out why that doesn't work in a Ring app

17:38 TimMc: weavejester: I'd find it useful to have two ways of accessing querystring keys: last value (string), and all values (vec/list)

17:39 gfredericks: hiredman: yeah that's my current issue :D

17:39 weavejester: TimMc: Maybe as a function "param" which just gets the last

17:39 callen: You want some global state to be changed by a request?

17:39 gtrak: callen: then proxy over a var... if you need threadlocal, that's what vars do

17:39 weavejester: callen: Sorry, got a little distracted and missed the explanation

17:40 hiredman: gfredericks: fiddle with it, maybe you can just leave it out, or pass a nil

17:40 gtrak: you'd have to be explicit about copying a value out of the thread-local scope

17:41 gfredericks: hiredman: got a workaround

17:42 hiredman: if you really want speed I think the "dump to csv and have the database load there" approach was orders of magnitude faster

17:42 gfredericks: yeah I don't doubt it

17:44 gtrak: if the problem is there's no association between request map and a thread, that can be solved

17:45 callen: gtrak: the problem is that you can't tie state to the request lifecycle, threads are besides the point

17:46 outside of middleware, Ring doesn't make a lot of provisions for statelessness.

17:46 ibdknox: what are you looking for?

17:46 gtrak: yea, I can see that

17:47 ibdknox: cross-request state? intra-request state?

17:47 callen: ibdknox: http://flask.pocoo.org/docs/api/#flask.g

17:47 ibdknox: intra

17:47 weavejester: callen: I don't understand what you mean by "tie state to the request lifecycle"

17:47 egghead: cross state requests are subject to federal law

17:47 ibdknox: callen: just use a piece of middleware that threat binds an atom - done.

17:48 callen: for an example look at how sessions work in libnoir

17:48 weavejester: callen: Ring handles a request in one thread

17:48 Because a handler is a function

17:48 callen: weavejester: ibdknox understands my question, leave it be. Thanks anyway.

17:48 ibdknox: thank you.

17:48 weavejester: Unless you explicitly kick off a new thread or use a future or something

17:49 callen: weavejester: not what I was talking about, I only used the word thread because others did

17:49 and only to say that wasn't what I was talking about

17:49 weavejester: Okay...

17:49 ibdknox: weavejester: Is that a hard guarantee outside of the jetty adapter?

17:49 weavejester: Because flask.g's functionality looks to me like a var

17:50 ibdknox: weavejester: yeah it's a var with an atom as the value

17:50 gtrak: callen: it's not obvious from ibdknox's trivial solution why no one else knows anything about what you're talking about

17:50 weavejester: ibdknox: It is within Ring itself

17:50 ibdknox: Aleph it might not be, but then you're stepping outside of Ring

17:51 ibdknox: weavejester: got it

17:51 weavejester: ibdknox: Remember, a Ring handler is a function, so unless you explicitly start a new thread, it'll all happen in one thread

17:51 ibdknox: weavejester: oh absolutely, I was just wondering whether it was guaranteed they'd be on different threads :)

17:52 multiple requests that is

17:52 weavejester: ibdknox: Yes, because that's the only way Clojure has of running functions concurrently.

17:53 TimMc: How could they not be?

17:53 ibdknox: nio magic?

17:54 gtrak: a loop is not concurrent

17:54 weavejester: I guess if you used continuation-passing style you could manually hypervise them

17:54 ibdknox: never said the requests necessarily were handled concurrently

17:54 TimMc: I guess non-concurrent requests could reuse a thread.

17:54 weavejester: gtrak: Oh, yeah, threads will be reused

17:54 Jetty uses a threadpool

17:54 So you're almost guaranteed to reuse threads.

17:55 amalloy: huh. if file A contains (defmacro foo [] `(do ~'(blah))) at line 5, and file B contains (foo) as line 20, and (blah) fails to compile, the compiler seems to report it as an error at line 5 of file B

17:55 callen: see, people are misunderstanding each other, don't even need me to be involved.

17:55 weavejester: haha :)

17:56 gtrak: a thread has meaning in hardware, and clojure functions map to C-stacks just like java functions do, so continuation-passing moves up the abstraction, but doesn't take you away from that

17:56 ibdknox: There are lots of strategies for request handling, I was just curious if ring explicitly took an approach, and it does :)

17:56 I hadn't really thought about it

17:57 callen: software has a way of letting you not think about things.

17:57 which I think is the point.

17:57 weavejester: gtrak: Oh, I meant with continuation passing style you could maybe stripe the execution of two functions

17:57 gtrak: A green-threads implementation

17:57 gtrak: weavejester: sure, but then you're just taking control from the OS scheduler and writing your own

17:58 arohner: I don't suppose anyone has 'pdoseq in a library anywhere?

17:58 weavejester: gtrak: Right. I'm not saying it would be useful ;)

17:58 arohner: or any clues on how to write pdoseq in a way that doesn't involve copy&paste of 'doseq?

17:58 dog_cat11: what I like about clojure is that it is closest to what I actually think

17:58 weavejester: arohner: Interestingly I've needed to do that recently.

17:58 gtrak: weavejester: so by using a higher abstraction, you've inadvertently forced yourself to think on a lower one :-)

17:59 weavejester: gtrak: It was just an answer to a hyporthetical need to execute two functions concurrently without threads

17:59 Apage43: arrdem: pcalls/for?

17:59 weavejester: gtrak: Not sure "concurrently" is the right word for it

17:59 arohner: I used a ThreadPoolExecutor and a LinkedBlockingQueue

18:00 Apage43: (apply pcalls (for [foo bar] (fn [] (* foo 2))))

18:01 not the best

18:01 gtrak: weavejester: sure, we were just talking about abstraction here :-). Clojure runs on a von Neumann machine, and it benefits from matching it closely (shared memory). All these scheduling issues come up in hardware too.

18:01 arohner: weavejester: interesting. I was thinking of somehow generating a lazy seq and reusing pmap

18:03 ibdknox: what's the disadvantage of (dorun (pmap ...))?

18:03 hiredman: pmap is pretty lame

18:03 ibdknox: ah

18:03 arohner: ibdknox: I wanted for/doseq sugar

18:03 ibdknox: hiredman: slow?

18:03 hiredman: it has bugs and is not very flexible

18:03 arohner: hiredman: what bugs?

18:03 technomancy: pmap only goes ahead of the first un-calculated value by N

18:03 hiredman: it can leak threads or something

18:03 amalloy usually chimes in about it

18:04 technomancy: N being somewhere in the ballpark of the size of the agent thread pool

18:04 hiredman: pmap also has interaction issues with chunking

18:04 technomancy: so it's a terrible choice unless each element is going to take roughly the same amount of time

18:05 weavejester: arohner: https://gist.github.com/4488786

18:05 hiredman: something like pmap would be way cooler if you could pass in the executor to use, and then tune it via the executor

18:05 weavejester: arohner: That's roughly what I did

18:05 hiredman: Wasn't there something in Clojure 1.5 or 1.6 that would allow you to specify the executor for futures etc?

18:06 hiredman: I think for agents, dunno if it works for futures

18:06 weavejester: hiredman: Oh yep, it's agents

18:07 yogthos: weavejester: green threads can be used effectively, erlang is a good exmaple :)

18:08 hiredman: :(

18:08 ibdknox: haha

18:08 yogthos: weavejester: the overhead per green process is only a few bytes I think, and each function gets spawned as its own process

18:08 nDuff: I asked about it earlier, and was told that setting the pool for send-off agents would impact futures.

18:08 hyPiRion: weavejester: Are there any information about Clojure 1.6 already?

18:09 dog_cat11: are there any good example of parallel algo's implemented in clojure?

18:10 not just embarasingly parallel stuff

18:10 nDuff: *shrug*.

18:10 Does the ants demo count?

18:10 yogthos: dog_cat11: http://rosettacode.org/wiki/Dining_philosophers#Clojure

18:10 weavejester: hyPiRion: Probably not :)

18:10 hiredman: oh, I misremembered it is seque that leaks threads or agents or whatever

18:11 weavejester: nDuff: I believe futures do use the agent pool

18:11 dog_cat11: idk, I can to clojure for parallel algo's and I really haven't found any really insightful ones

18:12 gtrak: dog_cat11: what kind of algorithm? immutable datastructures surely count.

18:13 dog_cat11: but i still think clojure is one of the few languages that 'gets' concurrency

18:13 nDuff: weavejester: it's the send-off agent pool, not the send one.

18:13 weavejester: ...annoyingly.

18:14 weavejester: nDuff: Ahh

18:14 yogthos: dog_cat11: making stuff immutable by default certainly goes a long way towards that end

18:14 nDuff: (well, I do understand why -- you could get deadlocks otherwise)

18:14 technomancy: concurrency is typically trivial in clojure algorithms, so you're unlikely to find anything particularly insightful

18:14 the whole point is you don't need to be particularly clever

18:15 dog_cat11: but there are problems that require particularly clever strategies to make concurrent

18:15 like branch and bound

18:16 amalloy: if you're looking for something clever you could look at reducers/fold in 1.5

18:16 dog_cat11: yeah, i saw those, great stuff

18:16 amalloy: hiredman: i got a patch into 1.5 so that seque at least no longer leaks agents

18:17 gtrak: dog_cat11: perhaps the parallel core.logic http://www.clojure.net/2012/03/26/Messin-with-core.logic/

18:17 yogthos: avout is neat too https://github.com/liebke/avout

18:18 and then there's storm https://github.com/nathanmarz/storm

18:18 hiredman: https://gist.github.com/4488907

18:23 Apage43: storm has some pretty neat magic in

18:36 jlewis: it looks like the convention for clojars is to have groupId == artifactId, right? so project 'foo' can be imported in lein with [foo "0.0.1"]

18:37 hyPiRion: jlewis: right

18:37 jlewis: is the a similar convention for the namespaces of such projects? there's this 'core' namespace convention, but what if the project will end up with just one file in it? is it 'acceptable' to have 'foo' as the one and only namespace? so you can (use 'foo)

18:38 is there a*

18:38 bbloom: jlewis: yeah, that's fine

18:38 hiredman: ~namespaces

18:38 clojurebot: namespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it

18:38 hiredman: bbloom: it is not

18:38 bbloom: why not?

18:39 besides conflicts

18:39 if your namespace is a trademark or something, that's totally fine

18:39 hiredman: exactly because of conflicts

18:39 jlewis: i suppose that's the origin of 'core', then. i guess the best alternative is 'foo.core?

18:39 bbloom: he's asking about core tho

18:39 mycompany.myapp vs mycompany.myapp.core

18:39 technomancy: jlewis: the best alternative is for you to come up with something that accurately describes your project in two words

18:39 hiredman: and because of the way that clojure maps namespaces to java classes (which is just another set of conflicts)

18:40 technomancy: since Leiningen doesn't know anything about your project, it called it core.clj, which is nondescript and unhelpful, but it can't do any better.

18:40 hiredman: clojure.core used to be just clojure and was moved to clojure.core for these reasons

18:41 jlewis: so maybe i could have a concrete suggestion. i wrote a library that has an implementation of union-find in it, and that's it. it would be nice to call it data.union-find, but the clojure data.foo packages have 'clojure.' in front of them, so it feels wrong to just do data.union-find

18:41 on the other hand, jordanlewis.data.union-find isn't so appealing either.

18:41 i don't want my name all up in there!

18:42 hyPiRion: jlewis: Why not? You'll be famous in no time.

18:42 technomancy: so you need to pick a name that is unlikely to conflict. you can either do that by coming up with something clever or by using a name you control, like your surname or a domain name.

18:42 (not that you really control your surname, but whatever)

18:43 in some sense you "own" it

18:43 hiredman: http://www.taguri.org/

18:43 similar work

18:43 jlewis: considering that my domain name is jordanlewis.org, i suppose jordanlewis isn't such a bad pick. i just thought that there might be a more standard alternative, since i've been seeing all of these single-namespace projects around.

18:44 technomancy: jlewis: the artifact/group you put in project.clj doesn't have to have anything to do with your namespace name

18:44 hiredman: a taguri is also most a valid clojure symbol, I think

18:44 technomancy: there are very few single-segment namespaces in real clojure projects, but lots of one-word artifact identifiers

18:46 jlewis: mm, i see. ok. now the converse: assuming i'd like to leave the namespace of my project jordanlewis.data.union-find, is there something wrong or deprecated about using a maven-style org.jordanlewis group id?

18:46 hiredman: nope

18:47 hyPiRion: most people use the maven-style I think?

18:47 At least a good portion of libs I use are on that form.

18:52 technomancy: most people use names that aren't everyday nouns, but if you are going to have a name like that it's best to namespace it

19:09 seangrove: I'm trying to take a seq of strings and return a map looking like {"s1" {:sn "s1"} "s2" {:sn "s2"}} (if given e.g. ["s1" "s2"] as input)

19:10 Having a hard time thinking of a way to do it concisely

19:11 hiredman: (apply merge (map (fn [s] {s {:sn s}}) ["s1" "s2"]))

19:11 ,(apply merge (map (fn [s] {s {:sn s}}) ["s1" "s2"]))

19:11 clojurebot: {"s2" {:sn "s2"}, "s1" {:sn "s1"}}

19:11 hiredman: ,(reduce (fn [m s] (assoc-in m [s :sn] s)) {} ["s1" "s2"])

19:11 clojurebot: {"s2" {:sn "s2"}, "s1" {:sn "s1"}}

19:11 hiredman: etc

19:12 seangrove: Ah, so create a seq of key-value pairs, and then merge them?

19:12 Sounds good, thanks

19:22 gtrak: ,(into {} (for [k ["s1" "s2"]] [k {:sn k}]))

19:22 clojurebot: {"s1" {:sn "s1"}, "s2" {:sn "s2"}}

19:22 egghead: :3

19:23 today I used map juxt and comp in the same line, felt good

19:23 gtrak: nice!

19:23 technomancy: ~o/

19:23 clojurebot: \o ... High five!

19:23 egghead: \o

19:23 gtrak: -_-

19:25 yedi: how often do new versions of the JVM come out (if at all)

19:25 are there active groups still working to make the core jvm better?

19:26 gtrak: yedi: yes

19:27 http://en.wikipedia.org/wiki/Java_version_history#JDK_Alpha_and_Beta_.281995.29

19:27 technomancy: yedi: invokedynamic is relatively new, and there's work to add lambdas and a not-horrible date class.

19:27 danostrowski: Anyone here used IntelliJ's Clojure plugin?

19:27 mcohen: anyone know to how to pass system properties on the command line with lein (not in project.clj)?

19:27 * technomancy suppresses a snicker at the "strings in switch" new feature of 7

19:28 ivan: danostrowski: I use it to read code

19:28 technomancy: huh; according to wikipedia jsr310 is going to be in 8. I wonder how accurate that is.

19:28 danostrowski: ivan, I guess that's something. :) Was it horrible?

19:29 yedi: i wonder how important new features to the JVM are for clojure...

19:29 gtrak: yedi: tail-recursion would be nice

19:29 yedi: one of the changes in java 7 was jvm support for dynamic langauges... whatever that entailed. i don't see how that was useful

19:29 technomancy: yedi: clojure doesn't explicitly take advantage of anything newer than 5 IIRC

19:29 ivan: danostrowski: it thinks a lot of things are invalid syntax and it takes quite a while to highlight the functions in lists

19:29 dnolen: yedi: invokeDynamic could be very useful once it's fast

19:29 ivan: danostrowski: also no paredit, if you want that

19:29 danostrowski: ah. good to know.

19:30 dnolen: yedi: it's possible Nashorn could influence direction of JVM if Oracle takes that project seriously which it looks like they are.

19:30 ivan: technomancy: ForkJoin!

19:30 danostrowski: Maybe I'll just vim-clojure for now.

19:30 I generally like the JetBrains products (I use PyCharm a _ton_) but it doesn't seem like the most active plugin.

19:30 gtrak: yedi: the master of this is Cliff Click, his blog explodes brains

19:31 technomancy: ivan: well, not in actually released clojure versions =)

19:31 ivan: yedi: I heard of invokedynamic being broken in 7 and fixed in 8

19:31 arrdem: danostrowski: I've been vimclojuring for several months now successuflly...

19:31 * technomancy still can't overcome his horror at #inst being implemented before jsr310 =\

19:32 technomancy: clojurebot: inst is http://themosthorriblething.com/horribleimgs/F7UCSS.gif

19:32 clojurebot: 'Sea, mhuise.

19:32 mcohen: danostrowski: the idea plugin will let you set breakpoints and step through debug, but other than serious folks seem to prefer emacs. sublime text is not bad if you're an emacs newb

19:32 danostrowski: it works on the server I edit Riemann files on, but I'm now embarking on, like, really learning Clojure.

19:33 I do love the debugger in PyCharm. Hmm.

19:33 mcohen: same debugger basically

19:33 yedi: why would nashorn be useful? embedding clojurescript code inside clojure?

19:33 danostrowski: figures. thanks mcohen and all.

19:33 yedi: gtrak: thanks for the blog suggestion

19:35 mcohen: hi technomancy, do you have a sec?

19:35 technomancy: mcohen: maybe?

19:36 mcohen: thanks. is there any way i can do something like lein repl -Da=b ?

19:36 danostrowski: If you wanted to expose an API to clients and allow them to add scripts to a program around events firing... what would be the best choice in Clojure? Whitelisting would be important. If I was doing it Erlang or Python I'd use Lua, because there's libraries ready to go for that. Not sure for Clojure...

19:36 technomancy: mcohen: if you want to do it on the CLI you'd do JAVA_OPTS="-Da=b" lein repl

19:36 mcohen: you can put it in project.clj as :jvm-opts too

19:36 gtrak: danostrowski: clojail might be useful for you

19:36 mcohen: awesome. in project.clj wasn't an options for me

19:36 thanks a bunch phil

19:36 technomancy: no problem

19:37 dnolen: yedi: nothing to do w/ CLJS. Nashorn needs to follow JS spec, JS spec is moving toward proper tails calls.

19:38 (or may already arrived there for ES6)

19:39 danostrowski: gtrak, hmm! I'll google that, thanks.

19:40 gtrak: dnolen: maybe we can make a spec for clojure, and give it tail calls :-)

19:41 danostrowski: although... Clojure for plugins may not be the most wise choice, haha.

19:41 not sure plugin developers are going to overlap with lisp people, but we'll see. ;)

19:43 gtrak: danostrowski: my next suggestion would be rhino or something

19:43 it is embedded in J2SE 6

19:44 danostrowski: that probably would be more accessible, I'll look at that after I've read clojail. Thanks for the suggestions, gtrak :)

19:44 gtrak: yea, no problem!

19:47 yedi: for languages that have tail recursion: is it automatic? does the parser/compiler recognize functions that can be tco'd and just does it?

19:47 gtrak: yes

19:48 though I've only used one that does it (scheme)

19:49 technomancy: TCO is more than just recursive calls though

19:58 augustl: what's a good way to get a counter/index in a doseq?

19:59 technomancy: augustl: (doseq [[x i] (map vector myseq (range))] ...)

19:59 augustl: only thing I can think of is to build a map with map-indexed or something

19:59 technomancy: won't that create a lot of temporary objects?

19:59 technomancy: yeah

20:00 augustl: some kind of lazy awesomeness would have been nice :)

20:00 technomancy: oh, I guess map-indexed is in core now

20:00 augustl: perhaps a recur is better

20:00 technomancy: but not doseq-indexed

20:00 don't use recur

20:01 augustl: hm

20:01 technomancy: unless you've already measured that object allocation is a bottleneck

20:01 augustl: true

20:01 amalloy: augustl: everything clojure does creates a lot of temporary objects

20:02 hiredman: lots of things

20:02 technomancy: rule of thumb: the GC is better than you think it is

20:04 gtrak: jdk7 can even throw em on the stack

20:08 yogthos: does anybody know if there's a pretty printer for outputting nicely formatted code?

20:08 gtrak: yogthos: more pretty than clojure.pprint?

20:09 yogthos: gtrak: differently pretty :)

20:09 gtrak: I'd like something that follows formatting similar to paredit

20:09 gtrak: hmm, yea, no idea

20:09 maybe there's something interesting in counterclockwise

20:10 yogthos: gtrak: likely, it has logic for indentation, although it still won't reformat selected code automatically :)

20:10 gtrak: so I suspect it's more of a state thing with it

20:11 amalloy: gtrak: i doubt if jdk7 can put many of clojure's temp objects on the stack, because just about all of them escape from the function they were created in

20:11 yogthos: pprint has a code-dispatch setting

20:11 gtrak: amalloy: it can also inline those functions they're created in

20:13 yogthos: amalloy: ah cool

20:20 amalloy: yeah it's exactly what I was looking for thanks :)

21:24 gfredericks: technomancy: I am curious if you're still a fan of the defproject syntax, or if in retrospect you might have preferred a bare map or something else

21:25 ed_g: Does the clojure.contrib.math library exist any more or should I be using Java's Math classes?

21:25 pppaul: contrib got split up into infinite repos

21:25 gfredericks: ~contrib

21:25 clojurebot: Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

21:26 gfredericks: apparently there is a clojure.math.numeric-tower

21:27 ed_g: oops, OK I had tried to :use it and didn't realize it wasn't bundled with the main distribution of clojure

21:30 thanks @pppaul, @gfredricks!

21:30 krl: i'm confused on this, why does (type (doall (lazy-seq [1 2 3]))) not return PersistentVector?

21:30 gfredericks: why would you expect it to?

21:31 ,(type (lazy-seq [1 2 3]))

21:31 clojurebot: clojure.lang.LazySeq

21:31 gfredericks: doall doesn't change the type of its argument

21:31 it just forces it

21:31 krl: ok. i guess i want a function to force and return the datastructure

21:31 gfredericks: I don't think there's a consistent general way to do that

21:31 why would you need that?

21:31 krl: for debug printing

21:32 gfredericks: oh you probably want prn

21:32 ,(prn (lazy-seq [1 2 3]))

21:32 clojurebot: (1 2 3)

21:32 krl: hmm. any way to get the result of prn as a string?

21:32 ToxicFrog: Yeah, if you're doing debug printing it'll get realized when it's printed, if not before

21:33 gfredericks: krl: yep. prn-str :)

21:33 also pr-str if you don't want the newline

21:33 krl: ok cool

21:33 pppaul: i love newlines

21:33 prn prints out stuff that can be evaled, right?

21:33 gfredericks: well read at least

21:34 it tries anyhow

21:34 ,(pr-str (Object.))

21:34 clojurebot: "#<Object java.lang.Object@701451eb>"

21:35 krl: ok thx, that should solve my problem!

21:37 devn: ,(binding [*print-dup* true] (prn {:a 1 :b 2}))

21:37 clojurebot: #=(clojure.lang.PersistentArrayMap/create {:a 1, :b 2})

21:38 gfredericks: woah man that's serious

21:38 ,(binding [*print-dup* true] (prn (into (sorted-map) {:a 1 :b 999}))

21:38 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

21:38 gfredericks: ,(binding [*print-dup* true] (prn (into (sorted-map) {:a 1 :b 999})))

21:38 clojurebot: #=(clojure.lang.PersistentTreeMap/create {:a 1, :b 999})

21:39 devn: sharp-equals club. be careful. :)

21:39 gfredericks: o_O

21:39 ,(type (sorted-map))

21:39 clojurebot: clojure.lang.PersistentTreeMap

21:39 gfredericks: ahsee

21:39 devn: ,(read-string "#=(clojure.lang.PersistentTreeMap/create {:a 1, :b 2})")

21:39 clojurebot: #<RuntimeException java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>

21:39 devn: ^-that would work in your REPL

21:39 but not with the bot

21:40 * gfredericks can't wait till that gets set to false by default

22:05 technomancy: gfredericks: you can use a bare map if you want

22:05 gfredericks: WAT

22:05 * gfredericks blown mind

22:05 technomancy: (def project {:name "whatever" :group "stuff" :version "1.0.0-COLLECTORS-EDITION"})

22:05 FSVO "bare"

22:05 gfredericks: oh I meant at the top level :)

22:05 technomancy: it's just super annoying because every symbol needs to be quoted

22:05 oh you mean like read-string instead of load?

22:06 eh

22:06 gfredericks: right

22:06 xumingmingv: Is there a style guide for how to document the parameter of function? like the @param tag in Java?

22:06 gfredericks: makes it feel more like data?

22:06 xumingmingv: I think folk normally just put that in the docstring; I don't know of anything more specific.

22:07 if you're using marginalia you can use markdown to some effect

22:07 technomancy: gfredericks: I don't think it makes much of a difference. some people take advantage of the fact that you can (def shared-value ...) before defproject, and that would be difficult with read-string

22:07 gfredericks: technomancy: oh man; that's a use case that never would have occured to me

22:07 technomancy: OTOH you can do a lot with read-eval

22:07 (but not that)

22:08 gfredericks: ooh a new data reader: #eval (def stuff ...)

22:09 okay am going to bed

22:09 technomancy: haha

22:09 * gfredericks has one day to prepare a clojurescript talk

22:09 hyPiRion: gfredericks: good luck

22:09 technomancy: an early version actually used strings for artifact ids

22:09 which was really annoying

22:09 gfredericks: technomancy: aaah!!!

22:09 I'm annoyed just hearing about it

22:09 technomancy: I think defproject is the only macro in leiningen

22:09 heh

22:09 gfredericks: hyPiRion: thanks

22:10 technomancy: "The Only Macro in Leiningen" would be a good title for something

22:10 technomancy: gfredericks: yeah, it also adds some defaults in, but you could do that with a map merge too

22:10 gfredericks: the first great work of clojure literature

22:10 amalloy: technomancy: checks out. just one macro. very surprised, personally

22:10 technomancy: with the lein-pprint plugin it makes it pretty easy to see the effective map value of various profiles etc

22:11 hyPiRion: Yeah, defmacro's the only macro in Leiningen.

22:11 defproject I mean

22:11 jweiss: what's the syntax to get the bot to test core functions to match input and output you give it?

22:11 xeqi: having not explored readers at all, can you add a new one at runtime?

22:12 gfredericks: $findfn 42 42

22:12 xeqi: yeah there's a var for it

22:12 lazybot: [clojure.set/union clojure.set/intersection clojure.set/difference clojure.core/time clojure.core/dosync clojure.core/long clojure.core/short clojure.core/+ clojure.core/* clojure.core/doto clojure.core/unchecked-long clojure.core/+' clojure.core/unchecked-short... https://www.refheap.com/paste/8259

22:12 xumingmingv: thanks gfredericks

22:12 jweiss: $findfn [inc [1 2 3]] {1 2 2 3 3 4}

22:13 lazybot: []

22:13 jweiss: $findfn [[1 2 3] inc] {1 2 2 3 3 4}

22:13 gfredericks: jweiss: no list around the args

22:13 lazybot: []

22:13 gfredericks: jweiss: also I know that function doesn't exist; I've wanted it a lot

22:13 jweiss: darn

22:13 gfredericks: I bet flatland/useful has it

22:14 hyPiRion: ,(zipmap [1 2 3] (map inc [1 2 3]))

22:14 clojurebot: {3 4, 2 3, 1 2}

22:14 jweiss: so what do you use? let/zipmap?

22:14 gfredericks: there's also (into {} (for ...))

22:14 jweiss: right, i wrote both and they looked ugly

22:14 oh well

22:14 gfredericks: it probably wasn't included because the use cases are slightly iffy

22:15 * gfredericks still wants it

22:15 jweiss: gfredericks: if you want to display information to a human? seems like a good use case.

22:16 gfredericks: yeah humans are the best

22:16 xeqi: other than robots

22:16 hyPiRion: ~botsnack

22:16 clojurebot: thanks; that was delicious. (nom nom nom)

22:16 gfredericks: ~botdance

22:16 clojurebot: I don't understand.

22:16 amalloy: the problem with that function is that it can't work unless the input values are unique

22:17 gfredericks: it could work as well as zipmap

22:17 if your input values aren't unique that's your own problem

22:17 I can't even see how that's even remotely a problem actually

22:17 even even

22:17 hyPiRion: yeah, no difference between that and zipmap

22:46 ravster: hello everyone

22:47 arohner: after binding clojure.core/*data-readers* to {}, I'm still seeing #uuids being loaded. any ideas on what to look at?

22:48 with-redefs [default-data-readers {}] "solves" the issue, but I'd like something that I can bind

22:49 bpr: arohner: i'm pretty sure *data-readers* is bound to {} in the first place

22:49 arohner: bpr: *data-readers* contains {}, but #uuid is still being handled

22:49 bpr: right

22:49 so, re-binding to {} wouldn't change things

22:53 arohner: ah, default_data_readers is hard coded in LispReader.java. that's unfortunate :-(

23:02 yedi: core.matrix would be sexy

23:03 bbloom: yedi: yes it would!

23:08 arohner: is there a built in fn that works like repeatedly, but stops when f returns falsey?

23:08 I guess (take-while identity (repeatedly f))

23:08 bbloom: arohner: that'd do the trick

23:12 xeqi: is there something to pass to spit to make it create any missing parent directories?

23:13 technomancy: I don't think so

23:20 bpr: xeqi: ##(doc clojure.java.io/make-parents)

23:20 lazybot: ⇒ "([f & more]); Given the same arg(s) as for file, creates all parent directories of the file they represent."

23:21 xeqi: bpr: thanks, that was my next step

23:21 bpr: k

Logging service provided by n01se.net