#clojure log - Jun 12 2012

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

0:15 alandipert: alex_baranosky: topo sort them maybe?

0:16 alex_baranosky: Hmmm… what is topo sort?

0:16 https://gist.github.com/1263783 ??

0:16 lazybot: alex_baranosky: What are you, crazy? Of course not!

0:16 alandipert: alex_baranosky: it's a way to sort directed graphs, which maps kinda are

0:17 alex_baranosky: aka topological sort

0:17 scottj: I like http://github.com/GeorgeJahad/difform

0:19 alandipert: alex_baranosky: yup that's one way, the the problem with converting to diff is that it's line oriented, interesting to think about a conversion that compensates for this

0:19 alex_baranosky: what's the prolem with just printing ?

0:20 alandipert: i think it depends on what you're interested in seeing in your diffs

0:20 like if the maps are different sizes by one, when printed the offset will make the diff massive

0:22 alex_baranosky: there is stuff like http://www.altova.com/diffdog/xml-diff.html for structural XML diff, maybe you could XML and see your maps in their viewer

0:23 alex_baranosky: bedtime but sounds like cool project, hit me up if i can help

0:23 alex_baranosky: will do. Take it easy

0:28 kwertii: Are there any VC funds or angels who specialize in Lisp-based startups? It seems like, if it's true that it gives you a huge competitive advantage (as Paul Graham has written extensively), there ought to be some funding sources somewhere that specialize in Lisp.

0:30 scottj: kwertii: there aren't, and it doesn't.

0:30 mthvedt: might have been true in 1995

0:30 scottj: re VCs, as for angels who knows.

0:31 kwertii: It occurred to me that Graham's own fund, Y Combinator, has no particular Lisp bias.

0:31 *even

0:31 scottj: kwertii: the thing is a startup is so many things other than what language you happen to use that any benefit there is drowned out by all the other factors.

0:31 kwertii: Makes sense

0:31 kreig1: language choice is really not that big a factor

0:32 scottj: kwertii: even once-big-time lisp fans like peter norvig have said that other factors overshadow language choice

0:32 kreig1: certainly not one I would be putting any emphasis on when putting together an investment portfolio

0:32 kwertii: It certainly seems to be far more popular to crank things out in Ruby or PHP

0:32 technomancy: scottj: well peter norvig has to weigh staffing a lot more heavily than a startup would

0:33 kwertii: much larger talent pool to draw from, makes hiring and firing easy

0:33 but if a team is "good" at all the other factors anyway (whatever "good" means), then it stands to reason that they might benefit from using Lisp

0:34 scottj: technomancy: true, but I seem to remember him not talking about this re staffing but saying that he'd underestimated the value of powerful tools like IDEs

0:34 kwertii: however, I expect that that's a sufficiently rare circumstance so as to make it impossible to build a whole portfolio around it

0:35 technomancy: scottj: I think that also ties into having a huge company

0:35 kwertii: A place like Google that needs to hire by the thousands can't really afford to build out in a less popular language, because there just aren't that many developers who can develop in it

0:36 scottj: here's the quote I misremembered: http://news.ycombinator.com/item?id=1803815

0:36 kwertii: languages with a low barrier to entry (Ruby, PHP) create a self-perpetuating cycle of having a large developer base, and then more companies use them because of that talent pool, etc.

0:37 ro_st: this looks like a fascinating conversation. i'm sorry i missed the start of it

0:38 kwertii: ro_st: the original question was, are there any VC firms or angels that specialize in Lisp, if indeed it gives you a competitive advantage as Paul Graham has written extensively. And no, there don't seem to be, so it must not give you such a huge advantage.

0:38 ro_st: or at least, any advantage Lisp gives is drowned out among the many other factors

0:39 ro_st: i see. makes sense. are there vcs that specialise in any programming language?

0:40 kovasb: solving a market need seems like a much more important objective for them

0:40 kwertii: re: Norvig quote - I agree; I'd certainly rather have excellent developers working in Visual Basic than terrible developers working in Lisp

0:40 (I'd have them write a Lisp interpreter first :)

0:40 ro_st: i should think they'd specialise as far as a specific business model; as that's where their expertise would help

0:40 kovasb: starting with technology is not the way to make money

0:40 kwertii: kovasb: yeah, the business side doesn't really care what tech you use

0:41 ro_st: as long as you remain competitive

0:41 which was part of PG's point

0:41 lisp made them ultra-competitive

0:41 kwertii: as long as people keep paying you. there are banks today still running COBOL, and major science projects in academia still using FORTRAN

0:42 ro_st: banks are hardly the sort to use edge technologies :-)

0:42 with good reason!

0:42 kwertii: ro_st: that's what I was getting at -- if Graham was right, if Lisp per se actually makes you ultra-competitive, there ought to be a specialized VC funding segment for it, but there isn't

0:42 kovasb: i think moments like the birth of the internet are a unique time when tech can give u the edge

0:42 mature stacks in shitty languages were not available yet

0:43 so its more of a level playing field

0:43 ro_st: kwertii: that makes the investment potential for such a company far too small

0:43 scottj: kovasb: well, and it was harvard phds who had written books about their languages vs average joe

0:43 kovasb: same thing in e.g. big data now

0:43 kwertii: ro_st: I think the factors that make one a great Lisp programmer don't correlate much with the factors that make one a good startup founder

0:43 TheBusby: good VC's invest in good people, and hopefully good ideas. I doubt the tech stack is an issue until acquisition time

0:43 ro_st: i'm in SA. we don't have tech-only VCs here. you're talking about a tech VC that demonstrates an incredibly high tech awareness

0:44 kovasb: scottj: right but nowadays doing via web in some ruby on rails thing would be trivial

0:44 ro_st: sa, south africa

0:44 kwertii: TheBusby: even then, they'll just buy it and rewrite it if they want it - Graham's ViaWeb got rewritten in C++ when Yahoo couldn't figure out his Lisp code

0:44 TheBusby: kwertii: the lisp may turn away potential purchasers though

0:44 technomancy: we had a symbolics guy invest in Sonian who was kind of amused to see lisp making a comeback

0:45 ex-symbolics obviously

0:45 TheBusby: didn't someone just write a blog talking about their experiences porting a hotel booking application from Ruby to Lisp and then defending their decision during an acquisition?

0:45 kwertii: technomancy: I first heard about Clojure from a guy on the CL committee during a discussion on why CL languished in obscurity. he was very pleased that it seemed to be fixing all the baggage and political issues with CL

0:46 technomancy: TheBusby: there's also a good paper from the Xen authors on the same situation with OCaml

0:46 scottj: TheBusby: not sure the ref, but there is a clojure app for hotel bookings

0:47 technomancy: kwertii: that's better than many CLers on IRC who seem to be horrified that a non-CL lisp could take off.

0:47 kwertii: there's Reddit, too; originally written in Lisp (CL?) and then converted to Python. that was a YC company, too

0:47 kovasb: theres lots of startups using clojure

0:47 kwertii: technomancy: yep. the other CL people were definitely less impressed

0:47 TheBusby: ahh here is the link, http://www.colinsteele.org/post/23103789647/against-the-grain-aws-clojure-startup

0:48 kovasb: actually PG just posted to the yc founders list, they got a discount on the clojure/core roadshow training

0:49 TheBusby: now for a dumb clojure question, is there a simple way to generate the following ([0 10] [11 20] [21 30] [31 40] [41 50] [51 55]) for N (where in this case N is 55)

0:50 hiredman: yes

0:50 several

0:51 TheBusby: hiredman: yes, embarassing question but what's the simple idiomatic performant method?

0:52 * TheBusby is implementing reducers against mmap'd files (via JNI), and the chunking method for testing is the biggest issue...

0:53 kovasb: TheBusby: sounds cool. is there a github? :)

0:53 TheBusby: kovasb: not yet, this is for work so I'd need to pursue a public release when I'm done :(

0:54 kovasb: so do you load a big chunk into memory and then run the reducer?

0:54 hiredman: you know you can get a mmap'ed byte buffer on a file via java nio?

0:54 TheBusby: I have multiple apps, in multiple languages mmap'ing the same file

0:54 and I haven't heard many good things about nio...

0:55 hiredman: the lest error prone way to do that kind of thing is something like (map (juxt first last) (partition-all chunk-size (range size)))

0:55 least

0:55 (the cleariest, most expressive of intent, least likely to screw up)

0:56 TheBusby: so?

0:56 TheBusby: maybe you should read up on it then

0:56 TheBusby: hiredman: that takes 3.4 seconds on my box

0:57 hiredman: http://docs.oracle.com/javase/6/docs/api/java/nio/channels/FileChannel.html#map%28java.nio.channels.FileChannel.MapMode,%20long,%20long%29

0:57 TheBusby: hiredman: regarding java's nio I did do some initial testing, and am using java.nio.ByteBuffer to wrap JNI stuff

0:57 hiredman: *shrug*, carry on then

0:58 TheBusby: hiredman: yeah, there are a number of other factors as well which lead the JNI route. :(

0:59 hiredman: I was doing the above with range earlier, but since that has to iterate through all N elements it becomes slow as N gets into the millions

1:00 hiredman: TheBusby: the less apparent approach is to do it via division, but that is easier to get wrong

1:00 amalloy: hiredman: why not addition?

1:01 hiredman: if you really want to do it fast you should avoid the seq all together

1:01 amalloy: divsion + addition

1:01 and you have to deal with the remainder

1:01 TheBusby: the chunk-size will usually be rather larger (typically less than 10 chunks), but N can be in the billions

1:02 xeqi: &((fn [x] (map vector (conj (iterate (partial + 10) 11) 0) (concat (take-while (partial >= x) (iterate (partial + 10) 10)) [x]))) 55)

1:02 lazybot: ⇒ ([0 10] [11 20] [21 30] [31 40] [41 50] [51 55])

1:05 TheBusby: xeqi: thank you!

1:13 scottj: &((fn [x] (map vector (concat [0] (range 11 (inc x) 10)) (concat (range 10 x 10) [x]))) 55)

1:13 lazybot: ⇒ ([0 10] [11 20] [21 30] [31 40] [41 50] [51 55])

1:14 xeqi: thanks, I forget range can take a step

1:15 TheBusby: using this now, (fn [n chunk-size] (let [[x & xs] (partition 2 1 [n] (range 0 n chunk-size))] (conj (map (fn [[x y]] [(inc x) y]) xs) (clojure.core/vec x))))

1:15 scottj: xeqi: your solution shows more skill

1:15 sayyestolife: When I comment in the code that is out-commented in this http://pastebin.com/AnhG1BKK, the function just waits. How come?

1:15 TheBusby: scottj: definitely

2:10 tomoj: suppose for some pairs of values of a type in cljs, equality cannot be determined synchronously. you can't sensibly use = on values of this type, then, correct?

2:12 of course not

2:22 amalloy: tomoj: what kind of type would that be?

2:24 tomoj: say an IPending/IDeref

2:25 a promise

2:25 where the desired equality compares the eventual value

2:25 but IDeref can't block in cljs

2:26 but it can just be (fmap =)

2:28 amalloy: tomoj: i don't think that's a correct "desired equality"

2:28 which i guess is the same as your conclusion, that you can't use = on them

2:29 francis: I keep getting a null pointer exception when to use a function I've defined in a diffrent namespace. I belive that the problem is arising because I have not correcly loaded the namespace. Does this seem like a reasonable hypotheis?

2:29 amalloy: francis: reasonable, but not likely

2:30 you'd usually get a different exception, like "what the hell is this function you're calling"

2:30 tomoj: amalloy: well, why not in clojure? e.g. (= (future 1) (future 1))

2:30 amalloy: &(= (future 1) (future 1))

2:30 lazybot: java.lang.SecurityException: You tripped the alarm! future-call is bad!

2:30 amalloy: ,(= (future 1) (future 1))

2:30 clojurebot: false

2:31 amalloy: whew

2:31 tomoj: why _not_ have that be equality?

2:32 we have identical? if we want that

2:33 hmm

2:33 amalloy: because you want to be able to store blocking things in (eg) hashmaps

2:33 tomoj: ah

2:33 hiredman: amalloy: well, you can store them just fine

2:33 and I would look askance at a scheme that involved using them as keys

2:33 amalloy: sure, i meant as keys

2:34 hiredman: more likely might be sets

2:34 amalloy: hiredman: why not? ((memoize identity) (delay)) needs to store [(delay)] as a key

2:36 hiredman: because once you've started using references as keys you've given up computing with values completely, maps are no longer functions of values

2:37 amalloy: i agree it's a bad thing to do on purpose

2:37 tomoj: couldn't you somewhat analogously argue that lazy seqs shouldn't implement equality because you might want to ((memoize identity) a-lazy-seq)?

2:37 amalloy: but it's not a fundamental error, and things like memoize will lead to it happening accidentally

2:37 tomoj: good point. perhaps my argument is no good

2:43 Sgeo_: You know what would be nice? Not having NullPointerExceptions

2:43 Just making them things that don't happen.

2:43 >.>

2:48 spjt: You can't not have nothing.

2:49 KIMAvcrp: Sgeo_: like in haskell

2:49 Sgeo_: KIMAvcrp, yes


2:49 amalloy: no instance found is way better, amirite?

2:50 spjt: why not?

2:50 Sgeo_: amalloy, you mean the compiler-time error?

2:50 Yes

2:50 Because it's a compile-time error

2:50 KIMAvcrp: the problem with nullpointer is that you don't have to check for them they can be in everything

2:50 spjt: Sgeo_: Because you can't have everything-is.

2:50 amalloy: well then...whatever one happens when you call (tail [])

2:50 for incomplete functions

2:50 Sgeo_: amalloy, tail shouldn't exist

2:51 KIMAvcrp: if you use sth like maybe monad you dave to explicitly check for nothing

2:51 Sgeo_: And incomplete functions shouldn't be written.

2:51 (To the maximum extent avoidable)

2:51 amalloy: *shrug*

2:51 spjt: neither should functions that cause nullpointer exceptions :)

2:51 amalloy: i like haskell and its type system, don't get me wrong

2:51 but if every language were the same, what would be the point?

2:51 Sgeo_: spjt, that's harder to avoid

2:52 spjt, since every variable can take a null value (at least, in most languages)

2:52 Languages that have nulls like that, I mean

2:55 amalloy: $heval tail []

2:55 lazybot: ⇒ *Exception: Prelude.tail: empty list

2:57 Sgeo_: $heval let safeTail (_:xs) = Just xs; safeTail [] = Nothing in safeTail []

2:57 lazybot: ⇒ Nothing

2:58 Sgeo_: $heval drop 1 []

2:58 lazybot: ⇒ []

2:58 Sgeo_: $heval let safeTail = drop 1 in safeTail []

2:58 lazybot: ⇒ []

2:58 * Sgeo_ stops

3:23 ro_st: anyone using the bishop library? https://github.com/tnr-global/bishop

3:23 i'm trying to figure out how to write tests for it

3:24 ah i had to include :request-method

3:31 wmealing_: what is the closest thing to django templating for clojure ?

3:34 michaelr`: wmealing_: i don't know about django templating

3:34 but i used StringTemplate

3:34 and it's pretty cool

3:35 * wmealing_ looks

3:35 wmealing_: its a pretty basic template language

3:36 michaelr`: yup, on porpuse

3:36 this encforces the separation of view and logic

3:36 wmealing_: ive seen my share of php, i completely get why.

3:49 michaelr`, yeah i think string template is going to work for me.

3:49 thanks for the pointer

3:50 ro_st: how do i deal with a java.lang.ClassNotFoundException: org.mortbay.log.Logger issue when trying to run midje?

3:50 i certainly didn't ask for this class anywhere in my own code

3:51 wmealing_: i imagine that is part of jetty

3:51 which jvm are you running ?

3:51 ro_st: 1.6.0_31

3:52 Java(TM) SE Runtime Environment (build 1.6.0_31-b04-415-11M3635)

3:53 it looks like it's ring-serve's fault

3:53 lein/lein2 deps isn't pulling it down, however

3:53 argh. i hate issues like this :-(

3:55 so now i have to choose between being able to test with midje or being able to run a ring server from within my slime repl

3:55 -sigh-

3:57 sometimes, it really feels like i'm the only one trying to use the combination of tools i use, although i'm using what appears to be the tools used by the majority

3:58 michaelr`: there is also the silent majority :)

3:58 wmealing_: i feel your pain

3:58 i was having all kinds off no-fun with midje --lazytest

3:58 s/soff/of/g

3:59 ro_st: so. how do i get lein to fetch org.mortbay.log.Logger?

3:59 here's the culprit: https://github.com/weavejester/ring-serve/blob/master/src/ring/util/serve.clj line 4

4:01 i already have all the deps that ring-serve does

4:03 wmealing_: did you come right with midje?

4:04 wmealing_: eventually

4:04 * wmealing_ looks at the clj

4:05 wmealing_: i'm just thinking out loud here

4:05 ro_st: the reason midje is getting ring-serve is because ring-serve doesn't work when it's only in dev-deps

4:05 wmealing_: you may be able to get aroun dit by adding it to your projects.clj

4:05 i see

4:05 Sgeo_: Gah

4:06 I saw a recent version of Pharo recently, and it mentioned something called rings, so now when I see rings in here I get confused

4:06 ro_st: actually, that's not true, i take that back. ring-serve is only in dev-deps. along with midje

4:07 cljnewb02345: dumb question: will apple release a 17" mbp with retina display?

4:07 ro_st: yes, but not right away

4:07 *wild guess*

4:07 cljnewb02345: oh

4:07 here's what I don't get

4:07 other lcds can't even ship without dead pixels

4:07 Sgeo_: I have a feeling that the two rings are completely unrelated

4:07 cljnewb02345: how does amazon get retina display w/o dead pixel

4:08 s/amazon/apple

4:08 wmealing_: cljnewb02345, order in the millions.

4:08 have each display checked by a human, and machine

4:12 ro_st: argh. this is ridiculous!

4:12 Sgeo_: I have a vague idea of what Pharo rings are

4:12 What are rings in Clojure?

4:13 ro_st: ring is a wrapper for http

4:13 https://github.com/mmcgrana/ring

4:14 Sgeo_: Something completely different, then.

4:14 Wasn't expecting similarities

4:14 ro_st: yup

4:19 how do i bind the whole body of a ring request? in this case the request POSTs a json blob. i want to destructure that whole blob in the route, if possible

4:20 this is a compojure question

4:24 ifesdjeen: ro_st: mapping your request to body is not the best approach, try matching on URI and do additional sub-routing withing

4:24 *within

4:25 ro_st: i have (POST "/scores" [] (do-stuff …))

4:25 i want to pass the entire post body to do-stuff

4:25 ifesdjeen: you have an access to request

4:25 so just retrieve body from (:body request)

4:26 ro_st: within do-stuff itself? can i not destructure it in the route def so that the do-stuff function is not ring-dependent?

4:27 ah! just found this on the web: (POST "/scores" {body :body} (do-stuff body))

4:27 ifesdjeen: ah :D now I see what you have meant

4:27 I thought you want to destructure based on body contents :/

4:28 ro_st: sorry that i wasn't clear :-) the posted body in this case will be a json blob, which i'll hand off to cheshire

4:28 ifesdjeen: cool

4:31 Sgeo_: Is clojure-koans good?

4:31 ro_st: i think so

4:31 francis: does anyone know what the library equivilent for clojure.contrib.str-utils is? I'm working through Manning's Clojure in Action book and I need some of the functions that it has.

4:31 ro_st: i got pretty far. haven't finished yet. stuck at recursion :-)

4:32 francis: *had

4:33 Sgeo_: I just checked it out

4:33 Their is-even? isn't tail recursi... oh, right

4:33 ifesdjeen: francis: most of them are in core.string now

4:33 francis: thanks

4:34 * Sgeo_ pats Clojure on its head

4:34 Sgeo_: There, there, Clojure. We know it's not your fault. It's that nasty JVM

4:34 ifesdjeen: francis: but if you want something more sophisticated, just find an old repo and port it from there ;) additional learning perk!

4:34 Sgeo_: some say that 4clojure is good

4:35 Sgeo_: ifesdjeen, tried it, it doesn't teach what's needed inline >.>

4:35 francis: ifesdjeen: I'm hoping I don't have to do that - I would like to get this TDD/mock/stubs down tonight

4:35 Sgeo_: Have to go hunting for documentation

4:35 ifesdjeen: francis: sure sure. good luck on that one!

4:36 Sgeo_: Oh, hmm

4:37 ifesdjeen: Sgeo_: i haven't tried them myself. i have an 'algorithm/logic puzzles', gives me enough headache

4:37 Sgeo_: ifesdjeen, ooh, sounds interesting

4:37 But I should really get a better grasp of basic Clojure first, probably.

4:38 ifesdjeen: Sgeo_: if want to get to java interop, you can check out https://speakerdeck.com/u/ifesdjeen/p/java-interop

4:38 ro_st: Sgeo_: clojurebook.com and joyofclojure.com. both excellent books. can't recommend them both enough.

4:38 ifesdjeen: Sgeo_: actually it would get you started with most of clojure concepts, like reify, proxy, defrecord, deftype, function calls, destructuring etc

4:38 Sgeo_: ifesdjeen, want to avoid Java interop for as long as possible

4:39 I think my interest in Clojure has to do with everything BUT that lol

4:39 ifesdjeen: Sgeo_: well, most of java interop concepts are very clojuric. for example protocols, they just happen to be good fit for interop, but they let you do polymorphism in a 'new' way

4:40 * Sgeo_ plans to implement Lenses in Clojure

4:40 Sgeo_: At some point

4:40 ifesdjeen: Sgeo_: what's Lenses (for uneducated part of the crowd, like me)

4:41 ah

4:41 amalloy: ifesdjeen: no way. protocols are a compromise with the jvm - if multimethods could be as fast, protocols wouldn't exist

4:42 ifesdjeen: amalloy: well, as everyone says, protocols cover 90% of what multimethods do

4:42 amalloy: sure

4:42 but to say that they "happen" to fit well with interop is misleading. that's the exact reason they exist

4:42 ifesdjeen: they're easier to understand, stuff

4:42 right

4:42 thanks amalloy

4:44 Sgeo_: What's #'

4:44 ?

4:44 Raynes: &(var 'println)

4:44 lazybot: java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.Symbol

4:44 Raynes: blue

4:44 &(var println)

4:44 lazybot: ⇒ #'clojure.core/println

4:44 Raynes: It's a var.

4:45 Sgeo_: Common Lisp uses that to refer to named functions as objects, I think Racket uses it for ... syntax objects?

4:45 It gets confusing

4:45 ro_st: #'foo = (var foo)

4:45 Sgeo_: Hmm, ok

4:45 ro_st: &(= (var println) #'println)

4:45 lazybot: ⇒ true

4:49 dbushenko: isn't #' syntax obsolete?

4:50 borkdude: dbushenko in some cases you need it

4:50 dbushenko when you need the var instead of the value

4:52 ro_st: ok. so i know i can do (PUT "/scores" {body :body} (…)). how do i destructure like that and also use a param?

4:52 (PUT "/scores/:id" <some how mix [id] and {body :body}> (…))

4:52 Sgeo_: Lesse

4:53 (This is based on my understanding, and, as such, may be wrong in subtle or not-so-subtle ways)

4:53 A lens could be thought of as a first-class way to refer to something in a data structure

4:53 dbushenko: borkdude: Can't I use just ' instead of #' for getting the var?

4:54 Sgeo_: So, you'd have functions that take a lens and an object, and either retrieve the value mentioned by the lens, or "set" (as in return a new copy) of the structure with the place modified

4:54 borkdude: dbushenko no, then you will get the quoted symbol

4:54 ,'foo

4:54 clojurebot: foo

4:54 borkdude: ,#'foo

4:54 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve var: foo in this context, compiling:(NO_SOURCE_PATH:0)>

4:54 Sgeo_: Easy example: keywords could be lenses

4:54 ,(get :alpha {:alpha 5})

4:54 clojurebot: nil

4:54 Sgeo_: ...?

4:55 ro_st: ,(get {:alpha 5} :alpha})

4:55 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unmatched delimiter: }>

4:55 ro_st: ,(get {:alpha 5} :alpha)

4:55 clojurebot: 5

4:56 Sgeo_: ,(assoc {:alpha 5} :alpha 6)

4:56 Kototama: hi, I have problem using ring uberwar , any idea what the error could be: http://paste.lisp.org/display/129977

4:56 clojurebot: {:alpha 6}

4:56 Sgeo_: So, you see how :alpha is being passed into those to refer to a location

4:56 Thus, :alpha would be an example of a lens

4:57 Another lens could be one that gets/sets the first item in a list

4:57 Lenses are also composable

4:58 So I could combine them, then pass the combined lens around

4:58 clgv: Kototama: try to get the full trace. the best info is contained in the initial exception

5:00 Sgeo_: I could also, to be silly, write a lens that gets/sets 1 above the number

5:00 So getting a number through this lens results in a higher value, and setting results in lower than the set value

5:00 dbushenko: borkdude, maybe you're right, I have to investigate that deeper

5:01 Sgeo_: get-in, assoc-in, and update-in analogues wouldn't strictly speaking be necessary, since lenses would have a comp-lens function

5:02 * clgv gets the impression that Sgeo_ is an optician.

5:03 Kototama: clgv: how can i get the full stacktracE?

5:03 i run it from the command line

5:03 clgv: Kototama: hmm I always found that difficult with leiningen. does leiningen's interactive mode provide a command?

5:05 ordnungswidrig: Sgeo_: is there a lenses lib for clojure, yet?

5:07 Kototama: ring uberwar from lein interactive does just returns nil without showing anything

5:14 Sgeo_: ordnungswidrig, I don't know, I don't think so

5:15 They should be reasonably simple to implement, though

5:15 ordnungswidrig: Sgeo_: beside that update-in etc. are lenses for associative data structures

5:15 borkdude: is a lens not simple a function which uses update-in

5:15 simply

5:16 Sgeo_: Hmm. I wouldn't call update-in a lens, I'd say that update-in takes a lens as one of the arguments

5:16 borkdude: lens = an accessor path?

5:17 Sgeo_: borkdude, that sounds like a good summary

5:17 * Sgeo_ is tempted to just start writing code

5:28 ro_st: with ring, if i have a (-> ) macro for my ring handler, in what order should i place a middleware that augments the request, the handler and a middleware that augments the response?

5:28 -> req-mid handler res-mid ?

5:29 ordnungswidrig: ro_st: sounds good

5:29 ro_st: and if the handler is a compojure defroutes?

5:30 amalloy: ro_st: it might be easier to think about if you drop the ->, figure out the order things should go in, and then put it back in as just a syntactic transformation

5:30 ro_st: sure. the difficulty here is that i don't know how compojure's defroutes plays with

5:31 ordnungswidrig: ro_st: the go first in the process

5:32 ro_st: (def app (-> app-routes wrap-json-params wrap-json-response wrap-access-control-allow-origin))

5:32 that seems wrong to me

5:33 i know that app-routes and access-control are working (i can see it in the response data in Charles)

5:33 ordnungswidrig: I see, no it'd be (-> wrap-json-params app-routes wrap-json-response ...)

5:33 ro_st: it's not json-ifying the response data itself, though, because i'm getting back {:symbol "string"}

5:33 yeah that gives me a null pointer exception

5:34 ordnungswidrig: ro_st: have a stacktrace pase?

5:34 ro_st: only has one entry: java.lang.NullPointerException, compiling:(app.clj:63)

5:34 63 in this case only has "(->" on it

5:35 ordnungswidrig: seems to be related to compojure macro expansion

5:41 wink: ifesdjeen: halfway done porting from congomongo to monger, and it seems to work with mongodb 1.4 as well :P

5:42 ifesdjeen: wink: w0000t!

5:42 wink: we started development from 1.8 iirc, congrats, and glad you made that leap!

5:42 wink: (testbox with debian squeeze :P)

5:42 Sgeo_: I'm starting to think there might not be a good reason to bring lenses to Clojure

5:43 ,(get-in {:hi [4 5]} 0 :hi)

5:43 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

5:43 Sgeo_: ,(get-in {:hi [4 5]} :hi 0)

5:43 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword>

5:43 Sgeo_: ,(get-in {:hi [4 5]} [:hi 0])

5:43 clojurebot: 4

5:43 borkdude: ,(get-in {:hi [4 5]} [:hi 0])

5:43 clojurebot: 4

5:43 ifesdjeen: wink: are you on Twitter?

5:43 what's your handle

5:43 wink: ifesdjeen: @anderiasch (but half of it is German)

5:44 ifesdjeen: wink: i speak some german)) i'm in Germany anyways

5:44 aaaahhh

5:44 Sgeo_: But still, there's only one way to ... hmm, even that could be worked around rather easily

5:44 wink: ifesdjeen: I was the big blonde guy yesterday ;)

5:44 ifesdjeen: wink: :D now I can correlate

5:44 wink: hehe, yeah, sorry

5:46 Sgeo_: Are there any cases where one might want to make a view into an object that the creator of the object didn't think of?

5:47 Becauses lenses would be good for that

5:47 borkdude: I guess the "Central" issues are gone now?

5:48 hiredman: Sgeo_: just expose the view has an ILookUp

5:48 then you can mostly treat it as a map

5:48 Sgeo_: What does ILookUp do?

5:49 hiredman: it is the interface that keywords use to lookup values when called as a function

5:49 (:foo x) ;; works when x implements ILookup

5:50 https://github.com/arohner/clj-wallhack/blob/master/src/wall/hack.clj#L38 ILookup for private field access via reflection

5:50 Sgeo_: Ok, cool, it doesn't do what I want it to do

5:50 That means my ideas might still have a use

5:51 ....oh, I see what you mean

5:51 Wrapping the object in a wrapper that makes ILookup work how you want

5:51 hiredman: you can then do things like (let [{:keys [somePrivateField]} (mirror obj)] ...)

5:52 Sgeo_: ...that doesn't compose well.... I still have a reason to make lenses!

5:52 >.>

5:53 hiredman: (:somePrivateField (mirror obj))

5:53 ILookup enables all the features you know and love

5:54 get-in uses ILookup

5:54 Sgeo_: But ILookup is a feature of the object being looked in, not the value used to refer to a location in that object

5:55 hiredman: Sgeo_: so?

5:57 Sgeo_: So.... it's not maximally flexible and convenient for certain tasks which I'm actually having trouble imagining

5:58 Suppose I wanted to look up items not by their index in a vector, but by the reversed index

5:58 So that 0 is the last item, etc.

5:58 And I want a get-in that lets me, in the list, mix reversed indexes and regular indexes

5:59 And this is still on ordinary, vanilla lists.

6:01 hiredman: ,(get (let [x [1 2 3]] (reify clojure.lang.ILookup (valAt [_ k] (get x (- (count x) (inc k)))))) 0)

6:01 clojurebot: 3

6:01 hiredman: ,(get (let [x [1 2 3]] (reify clojure.lang.ILookup (valAt [_ k] (get x (- (count x) (inc k)))))) 2)

6:01 clojurebot: 1

6:02 Sgeo_: So, you're making a new object that supports the reversed lookup?

6:03 I want to, hypothetically, write (get-in [[1 2 3] [4 5 6] [7 8 9]] [(rev 0) 0])

6:04 And I would get 7

6:08 mrb_bk: How can I find the available flags for leiningen 2's javac task? I want to see verbose output during the compilation

6:23 clojureman: Sgeo_: assuming you have a get-rev fn, just do (-> [[1 2 3] [4 5 6] [7 8 9]] (get-rev 0) (get 0)) to get 7 (I know you could be posing prob in larger context than I see here, so feel free to ignore answ)

6:58 dikidoom: hey, can someone tell me if seq-utils made it into the new modular system yet?

7:00 borkdude: dikidoom http://dev.clojure.org/display/doc/Clojure+Contrib

7:01 dikidoom: thanks borkdude, but seq-utils is not mentioned there, so i can only guess ...

7:01 borkdude: dikidoom hmm, yeh, I guess not then

7:02 dikidoom: okay, thanks for the hint! :)

7:02 ro_st: i'm having a brainfart with compojure. i've used swank/break to break all the way to the point where the fn that my compofure route talks to returns its data, and the data (a map) is there. but in the browser, there's no data. content length 0.

7:04 when i trigger my ring handler in the repl, i get the data back.

7:05 ordnungswidrig: ro_st: did you restart the jvm? I struggled with that before and some ns was not reloaded completely

7:07 ro_st: trying that now.

7:07 just found your compojure-rest lib, ordnungswidrig

7:08 ordnungswidrig: *g*

7:08 ro_st: same issue

7:09 when a compojure handler returns a map, must that map conform to the ring response spec?

7:09 ordnungswidrig: ro_st: compojure routing can be hard to debug.

7:09 ro_st: yes

7:09 ro_st: nfc. i'm trying to return a map for wrap-json-response to json-fiy

7:09 -ify*

7:09 nfw*

7:09 ordnungswidrig: ro_st: can you show some code?

7:12 ro_st: this is what i'm trying to do

7:12 https://www.refheap.com/paste/3102

7:12 clojureman: ro_st: I observed similar behaviour once with jetty and a domainname without any dots in it (defined in hosts-file) - once I changed to a domain with dots (localhost.xxxxxx.com) everything worked. I did not have time to investigate further, as I had already lost a bit of time...

7:12 ro_st: it appears that i need to do some response wrangling inside my compojure handlers

7:13 i was hoping to have my handlers return POCOs and let the ring middlewares do all the make-up

7:14 ordnungswidrig: ro_st: you can return a map like this: {::jsonify {:a 1 :b 2}} and make the wrapper jsonify it

7:14 ro_st: the middlewares i have there are the ones from https://github.com/ngrunwald/ring-middleware-format

7:16 i guess a hack would be to wrap my map in a vector and de-vectorise on the client

7:16 thanks for the tip clojureman

7:17 ordnungswidrig: hhm, never used that but associating the map as {:body mymap} should work with wrap-json-response

7:18 ro_st: wooohoop

7:18 that works.

7:18 on the plus side, i now have a good grasp of debugging with breakpoints

7:19 ordnungswidrig: ro_st: make a blog post :)

7:19 ro_st: thanks ordnungswidrig

7:19 now i can reward myself with some Diablo 3

7:20 ordnungswidrig: lol

8:05 dabd: I'd like to work on Clojure on a Windows environment. ClojureBox is no longer maintained. did anyone take over this project?

8:07 ordnungswidrig: dadb: I think is is not needed any more.

8:08 dabd: What is the simplest way to setup a development environment on win?

8:08 clgv: dabd: you can get started pretty quickly with Eclipse+CCW and leiningen

8:08 dabd: I'd like Emacs+Clojure

8:08 Not a fan of Eclipse/Netbeans

8:08 ordnungswidrig: download emacs 24.1 from gnu.org, install clojure-mode using package.el (which is shipped with 24.1), install leiningen and there you go.

8:08 dabd: ok

8:09 ordnungswidrig: maybe you'd have to configuration path to leiningen from emacs.

8:09 kmicu: dabd: it is no problem to work with eclipse and leiningen on Windows

8:09 ordnungswidrig: I had to setup my new windows 7 box the other day and it went rather well.

8:10 borkdude: ordnungswidrig what is the difference in list-packages and package-list-packages in 24.1?

8:10 ordnungswidrig: borkdude: i don't know. I only knew package-list-packages

8:11 borkdude: ordnungswidrig I guess this package thing also worked in ?

8:11 ordnungswidrig: I upgraded from emacs 23.x today and I did not use 24.0.x

8:11 borkdude: ordnungswidrig in 24.1 my screen gets mangled in OSX

8:12 ordnungswidrig: borkdude: on my osx machine i'm still on 23.x

8:21 ejackson: borkdude: I get the same mangling in terminal, but not out of terminal

8:21 borkdude: ejackson I havn't used it in terminal

8:22 ejackson I used the build from emacsformacosx.com

8:22 ejackson: same here

8:22 Vinzent: Hi. Why can't I derive from class?

8:22 dabd: kmicu: I am used to emacs

8:23 ejackson: with emacs -nw I get shearing, double lines, vanishing lines etc. But in its own GUI frame its 100% fine

8:23 borkdude: ejackson hm, nwo it seems to work, don't know what caused it

8:23 ejackson: its intermittent... :P

8:24 borkdude: I will give it another try then

8:25 kmicu: dabd: sorry, i had in mind emacs :)

8:29 Vinzent: So, can somebody explain why I can't (derive ::foo SomeClass)?

8:30 cshell: ,(doc derive)

8:30 clojurebot: "([tag parent] [h tag parent]); Establishes a parent/child relationship between parent and tag. Parent must be a namespace-qualified symbol or keyword and child can be either a namespace-qualified symbol or keyword or a class. h must be a hierarchy obtained from make-hierarchy, if not supplied defaults to, and modifies, the global hierarchy."

8:31 ohpauleez: haha, well there you have it

8:31 cshell: The second argument has to be a symbol or keyword?

8:32 ohpauleez: Vinzent: derive is just for creating related hierarchies, not for inheritance of any kind

8:32 Vinzent: I know, my question was why is it so.

8:32 ohpauleez, I know.

8:32 ohpauleez: Vinzent: So in what use case does it make sense that a parent is a class?

8:33 cshell: Oh, oops - yeah I can't explain :)

8:33 ohpauleez: you'd most likely want the class name as a symbol or a keyword, but not the whole class

8:38 Vinzent: ohpauleez, here is a little example: https://www.refheap.com/paste/3103

8:39 ohpauleez, the only way to work around it is to derive Number from ::number, but I don't see much sense in that

8:42 clgv: Vinzent: you can use `type` instead of `class` - then it will look op the :type metadata

8:44 Vinzent: clgv, I'm not sure how it'll help... I still can't derive from class, so it won't make any difference

8:44 clgv: Vinzent: what do you want to do exactly?

8:44 Vinzent: Look, my question is why the derive works the way it is, what's the background behind this decision

8:44 clgv, in that example (foo x) should return "number"

8:45 clgv: Vinzent: well then why don't you derive the other way round?

8:46 (derive Number :number) (derive :complex-number :number)

8:46 now both are numbers

8:46 Vinzent: clgv, that's exactly what I've said above: "the only way to work around it is to derive Number from ::number, but I don't see much sense in that"

8:47 clgv: and why?

8:47 ohpauleez: Vinzent: Why not? that makes more sense to me

8:47 You want to classify a group of things as a :number - what are those things?

8:48 the actual number class, :complex-number … maybe :imaginary-number

8:48 Vinzent: Creating unnecessary entity just to work around some limitation makes more sense? Oh, come on

8:48 ohpauleez: an :imaginary-number may or may not be a NUmber

8:49 Vinzent: I didn't mean for my remark to sound insulting, sorry about that

8:50 Otherwise is seems like you're tightly coupling these hierarchies (potentially) to a class hierarchy and that's undesirable

8:50 clgv: Vinzent: it's no workaround - it makes actually sense to say Number is a :number and your new complex number is a :number

8:50 ohpauleez: both for the language and for design

8:51 Vinzent: Looks like the only thing preventing from deriving from class is (assert (namespace parent)) in the derive source code

8:52 ohpauleez, no, it doesn't sound insulting :) No, I don't think I'm coupling these things

8:52 clgv, how is it better than saying that complex number is a number?

8:53 S11001001: Vinzent: yes, that's to prevent you from putting unsafe stuff in global-hierarchy. If you want no rules, use your own hierarchy

8:53 clgv: because it is not. your complex number is a map. it shares nothing with the Number class

8:53 Vinzent: S11001001, I can't, actually

8:54 clgv: the other way round the Number class can be of an abstract type :number

8:54 Vinzent: clgv, why should it share something? We're talking about hierarhies, not java inheritance

8:54 I think "number" is abstract enough :)

8:54 ohpauleez: So you want to toss in a class, and under the hood it just uses the Symbol for that class? or the class as keyword? Or some other rule to convert your set of classes into acceptable parents in the hierarchy?

8:54 clgv: java inheritance is mapped into the whole isa? concept which hierarchies is using

8:56 Vinzent: clgv, I don't see how it affects the issue

8:57 clgv: Vinzent: if class A inherites from class B and you can derive the other way round that would make no sense

8:57 S11001001: just using ::number sounds better, Vinzent

8:57 Vinzent: ohpauleez, you mean implementation? Hierarchies are implemented with plain maps

8:58 clgv: &(isa? Integer Number)

8:58 lazybot: ⇒ true

8:58 Vinzent: clgv, the same with keywords. There is nothing specific to classes here.

8:58 S11001001, I don't think so.

8:59 clgv: a map of type :complex should now be derivable from the Number class which is absolutely not true in java inheritance?

9:00 Vinzent: We're talking about clojure hierarchies, not java inheritance

9:00 S11001001: ok

9:00 clgv: Vinzent: well clojure hierarchies includes java's inheritance as seen in ##(isa? Integer Number)

9:00 lazybot: ⇒ true

9:01 clgv: so (derive :blubb Number) does not make any sense

9:01 Vinzent: clgv, I know, but so what? Let's deny multiple inheritance in clojure because (isa? Integer Number) ⇒ true, or what? I don't understand what do you mean.

9:03 ohpauleez: Vinzent: you can easily write one function, that converts your classes into however you want to interpret them for the hierarchy. At the end of the day, we have to accept the platform we're on

9:04 Vinzent: ohpauleez, how is such function supposed to work?

9:04 I have to redefine derive then, which is not a good idea.

9:04 S11001001: Vinzent: how is a function that accepts a java.lang.Number but gets a map instead supposed to work?

9:05 clgv: Vinzent: (fn [x & _] (case (type x) :complex-number Number (type x)))

9:05 S11001001: no.

9:05 that's a separate type

9:05 not a specialized type

9:05 Vinzent: S11001001, well, that's not a question actually :)

9:05 S11001001: oh, I am reading this wrong

9:06 borkdude: zombie numbers

9:06 sorry I had to say that, don't know why :P

9:06 * S11001001 wanders away

9:07 clgv: hehe. I think java inheritance is a special case embedded in clojure's hierarchies. so classes can derive from anything else in those hierarchies, but deriving from classes would break the semantik of the embedded java inheritance

9:07 Vinzent: clgv, I'm not sure how it would help.

9:07 (by it I mean that function)

9:07 ohpauleez: Vinzent: It could be something as direct as (keyword (str %))

9:07 clgv: that dispatch function would translate your :complex-number type to Number thus making your code work.

9:08 Vinzent: ohpauleez, I don't understand, could you show the whole solution?

9:08 ohpauleez: Personally, I think the best solution is the double derive, especially if you're defining your own hierarchy

9:08 Vinzent: clgv, dispatch function is fixed (and it was `class` in my example)

9:09 clgv: change it ^^

9:09 Vinzent: How? It's in some library, for example.

9:10 ohpauleez, well, actually I was asking about the reasons why derive works this way, not about solution :)

9:10 clgv: seemed like you defined it yourself

9:11 Vinzent: derive works that way because the decided that the inheritance relation of java classes shall be a part of clojure's hierarchies

9:12 Vinzent: well, then maybe I should replace the mulimethod with a single `case`, huh? :)

9:12 clgv: Vinzent: I would introduce the :number parent if I were you.

9:16 Vinzent: clgv, well, as I've probably said above, I don't see how (derive ::foo SomeClass) breakes java inheritance. Anyway, we should finish the discussion

9:22 clgv: Vinzent: it breaks the java inheritance hierarchy inside clojure's hirarchy

9:47 ro_st: can i run more than one slime repl in emacs at a time?

9:53 S11001001: ro_st: in general, slime supports that, as do certain swank-clojure arrangements, but I'm not sure that technomancy supports that in general

9:53 it works perfectly well with common lisp, if that helps ;)

9:55 cshell: with slime emacs, has anyone been able to get a repl running for days at a time?

9:55 without having to restart it?

9:55 S11001001: yep, no problem

9:55 weeks, even

9:55 kreig1: cshell yah

9:56 cshell: cool, can you get all of the command history too?

9:56 S11001001: what's "all"?

9:56 kreig1: yah, it's emacs, it's in a buffer

9:56 cshell: If you defined a function on the first day and you now want to move that into code, can you get back to it so you can copy it or is there a clojure function that will print the source?

9:58 ro_st: S11001001: thanks for that

9:58 kreig1: cshell: yah, but you would be much better off working in a file and then evaluating

9:58 S11001001: cshell: press M-< to go back to the top of the repl buffer

9:58 also inc kreig1

9:59 cshell: Okay, so depending on the size of your buffer you can keep as much as you want

9:59 kreig1: that's what I've been doing but didn't know if that was teh idiomatic way :)

9:59 S11001001 & kreig1: thanks guys

9:59 S11001001: there's no scrollback limit like in terminals, at least not by default; you keep everything unless you clear explicitly

10:00 ro_st: even on my monster quad core machine i've found that performance degrades pretty quickly with a long repl history

10:00 S11001001: ro_st: it's significantly more useful in CL, so you can test in different CL implementations simultaneously

10:01 ro_st: that is useful. in my case, i have a project that does my sql->mongo conversion, and a project for my json api. it'd be nice to have both running so that i can tweak the convertor and test in the api service

10:02 S11001001: can both projects be compatibly loaded in the same image?

10:02 ro_st: i could lein repl the one, but i want to be able to push code to both repls as i move on

10:02 with minor adjustments, yes. but doesn't slime repl depend on the deps present in project.clj?

10:03 S11001001: yes, but you can use checkouts to unify your sources

10:03 so you'd make a dummy project with the deps union

10:03 ro_st: what is this sorcery you speak of

10:03 S11001001: and add both source trees to checkouts/

10:03 ro_st: checkouts? wossat?

10:03 S11001001: then lein will add src/, test/, resources/, etc from both your source trees

10:03 ro_st: (clojure/emacs newbie. about a month in.)

10:04 kreig1: ro_st: very large single output blocks can slow it down when they accumulate

10:05 if you disable font-lock mode, M-x font-lock-mode, it won't have much of an impact tho

10:05 aka, the overhead is in all the syntax hilighting

10:05 ro_st: ah, that makes sense

10:05 kreig1: Iusually keep my repl buffer clean

10:05 ro_st: i prefer to C-c M-o regularly

10:06 clears the output, but retains entered command history

10:06 S11001001: anyhow, then you jack in to your dummy project, and should have the deps union you wrote, plus both source trees, available

10:06 ro_st: S11001001: where can i read more on how to do this?

10:07 S11001001: lein help checkouts maybe

10:07 ro_st: nope :-(

10:07 gfredericks: checkouts are described in the lein readme, or one of the doc files

10:08 there's not much to it though

10:08 mkdir checkouts && ln -s /some/other/project checkouts/some-other-project

10:09 ro_st: and then anything special in project.clj?

10:09 gfredericks: you do have to have the project listed in your :dependencies like normal

10:09 but nothing extra for using checkouts

10:09 ro_st: ah i see. is it possible to refer to another project on disk in deps? or do i have to put it into git first

10:10 S11001001: the git bits are an afterthought; I've never used them, just symlinking

10:11 gfredericks: and you don't need the project in dependencies

10:11 gfredericks: S11001001: at least if it has its own deps, right?

10:11 S11001001: I don't know the situation with lein2

10:11 gfredericks: S11001001: the lein docs have always said so

10:11 S11001001: but lein1 wouldn't pick up transitive dep changes

10:11 ro_st: forgive me for rehashing this, but what would the dummy project need in place? project.clj, checkouts folder with 2 symlinks, and an app.clj with nothing in it from which to clojure-jack-in ?

10:11 S11001001: I've used checkouts without referring to the project I checkouts-ed

10:12 not even an app.clj

10:12 ro_st: i guess i'd need to pull something from each project into app.clj so that it's compiled

10:12 kmicu: can sbd try to run this https://github.com/stuartsierra/cljs-formatter ? :) lein 2.0.0 needed

10:12 gfredericks: S11001001: you're a naughty naughty dev

10:12 S11001001: gfredericks: so I'm building a new library for use in a project.

10:12 should I make a dummy release before it has anything in it? No thanks.

10:13 ro_st: your project.clj would need all the deps both need, and compatibly, because checkouts doesn't pick up transitive deps. That's why I asked whether they could work in the same image

10:13 ro_st: ok great

10:13 i can do that

10:14 so jack-in'll use the deps env from dummy's project.clj, and then load src from the two subs as though they were source in dummy?

10:14 S11001001: yeah; you can see what'll happen with lein classpath in your dummy tree

10:15 ro_st: sweet

10:15 thanks for the tip

10:15 gfredericks: S11001001: you can install it locally; but yeah that's not worth it if you don't have to

10:15 S11001001: I hate snapshots

10:15 gfredericks: S11001001: I was only arguing about lein's opinion on the matter, not my own

10:16 S11001001: I would think lein would agree about snapshots :/

10:17 as for that recommendation, I think that's just to pick up what would be transitive dependencies for the library you're working on. It's a hack, and doesn't work perfectly, but it's okay

10:20 ro_st: thanks again. break time

10:25 gfredericks: S11001001: half of the time I use checkouts it's to debug some third party library that's already listed in my project.clj

10:26 S11001001: definitely

10:26 duck1123: checkouts are good when you're developing a support library alongside your main project

10:33 clgv: duck1123: and if you want to build all checkouts at once from your main project you can use lein-checkouts

10:37 llasram: TimMc: ping

11:02 TimMc: llasram: pong

11:05 llasram: TimMc: Had been trying to just /msg you, but apparently IRC is hard

11:05 devn: TimMc: I found a way to beat roulette

11:06 TimMc: You just wager the same amount on both red and black

11:06 winner every time.

11:06 llasram: devn: What about green?

11:09 TimMc: llasram: I've been offline since yesterday afternoon.

11:09 Ah, and I see your PMs.

11:12 * nDuff grumbles about APIs depending on Java annotations

11:15 wink: devn: you know the bank has a cut usually? :P

11:19 gtrak: you win on roulette by being a casino..

11:35 hyPiRion: Is there a more idiomatic way of writing (fn [x] (if (not= v x) x))?

11:36 ohpauleez: hyPiRion: when-not

11:37 hyPiRion: So basically (when-not (= v x) x) then.

11:37 okay, thanks.

11:38 ohpauleez: np, happy to helo

11:38 S11001001: ((set/difference set-of-all-values #{v}) x)

11:38 definition of set-of-all-values left as exercise for y ou

11:39 ohpauleez: if you're using it in a binding form, you'll want to look at when-let and if-let

11:39 S11001001: ohpauleez: not so much

11:39 ohpauleez: S11001001: What do you mean?

11:40 S11001001: ohpauleez: how would you write that with when-let or if-let?

11:40 also, (first (set/difference #{x} #{v}))

11:40 sets are cool, like bowties

11:40 ohpauleez: I'm saying if his end goal is to use these values in a binding form

11:40 Iceland_work: S11001001: "for certain values of cool" ;)

11:41 S11001001: ohpauleez: there's nothing useful you could put in the value-to-test position of an if-let or when-let that would give you the behavior of the aforementioned function

11:42 ohpauleez: I was not speaking to the function, but equality check - whether that's in a function is irrelevant to me

11:42 S11001001: equality checking returns a boolean

11:43 ohpauleez: (and 1 2)

11:43 (when-let x (and 1 2))

11:44 hyPiRion: Sets are cool when you deal with small value ranges, not when you deal with 2^31 different values.

11:45 S11001001: ohpauleez: what's that second thing?

11:53 clgv: hyPiRion: 2^31 value on a jvm lets your RAM explode pretty much, doesn't it? ;)

11:57 ohpauleez: hyPiRion: There might be a cool shorthand for that in the Hacker's Handbook too, not sure if this is performance sensitive

12:05 pepijndevos: Is there a function like descendants for java hierarchies?

12:10 tbaldridge: pepijndevos: I don't think the JVM does what you want. Doing (descendants Object) would require clojure to return every single type the JVM knows about

12:10 possible, but doesn't seem like it would work too well.

12:10 pepijndevos: tbaldridge, probably...

12:11 tbaldridge: also, the JVM doesn't track subclasses of types. As in you can say "get all children of this type" so it would require a linear search of all objects with a (instance?) on each

12:13 S11001001: besides, classes load lazily, so it would be unhelpful

12:16 devn: llasram: I actually think green doesn't matter in TimMc's game. At least we saw it count as even

12:17 oskarth: trying to generate and save an image with quil without generating an applet. Any ideas how to do this?

12:20 dnolen: oskarth: do you mean without constructing an Processing applet instance? How can you do any drawing then?

12:22 oskarth: dnolen: I guess I mean without doing anything unnecessary, I just want the image-file

12:25 found what I was looking for, :target :none in the sketch fn

12:26 sthuebner: what's the *practical* difference between the 'type and 'class functions? I mean, for what use cases does 'type go beyond 'class?

12:27 dnolen: sthuebner: type will also look at the :type field in meta

12:28 TimMc: devn: It's not my game.

12:29 sthuebner: dnolen: I assumed, that - for most cases - that field contains the same information. No?

12:29 ibdknox: is aot absolutely necessary to run a clojure program from an uberjar?

12:29 TimMc: ibdknox: Yes, at least for the main class.

12:30 ibdknox: The rest can be dynamically loaded quite easily. I wrote lein-otf to handle that.

12:30 * ibdknox goes to check out lein-otf

12:31 kreig1: otf?

12:31 TimMc: on-the-fly :-)

12:31 "jit" was confusing people.

12:32 kreig1: recompiled files when they change?

12:32 sthuebner: dnolen: ah, not right. type returns (class x) if no :type field is found.

12:32 kreig1: me no good at english tenses

12:33 TimMc: kreig1: Nothing so fancy. It's just my term for the opposite of ahead-of-time compilation.

12:34 kreig1: AOT compilation has to be used to some extent to make an uberjar. lein-otf injects a small AOT'd loader namespace that takes the place of your own main class, then asks the Clojure runtime to load the real one.

12:34 s/an uberjar/any executable jar/

12:38 ibdknox: TimMc: sweet, I think that'll work

12:38 TimMc: the CLJS compiler keels over when it's AOT'd :(

12:39 dnolen: pepijndevos: re: FD, I think you're right about IFiniteDomain. I do note that B-Prolog had (has?), CLP(FD), CLP(Tree), CLP(Set), CLP(Boolean)

12:41 pepijndevos: so we could probably break out ICLPFD, ICLPSet? need to think about naming ...

12:41 TimMc: ibdknox: Curious. What breaks, exactly?

12:42 ibdknox: Oh, and FYI: llasram is working on some enhancements to lein-otf, such as lein2 compat.

12:49 pepijndevos: dnolen, right... was just trying to formulate my thoughts in an email

12:56 brainproxy: using lein-ring with :auto-reload? true... have a (route/resources "/") in my handler, an when I load a page in browser from resources/public, only the path name is coming back, not the contents of the .html file

13:01 jsabeaudry: Anyone has had problems where agents die of heap exhaustion after a few hours?

13:04 bordatoue: is there a sleep equivalent in clojure

13:05 rlb: bordatoue: (Thread/sleep 1000)?

13:05 Guest79414: rlb: then what about the interrupted exception

13:05 TimMc: Catch it if you want to.

13:06 Guest79414: TimMc: so there is no compile time error if i don't catch it

13:06 TimMc: Right.

13:06 Checked exceptions are a Java thing, not a JVM thing.

13:07 Guest79414: TimMC: what do you mean saying it is a Java thing

13:08 hello

13:08 why is my name change to Guest

13:09 brainproxy: hmm, okay, it seems to be the :auto-refresh? option for `lein ring` that's got a problem.. not correctly processing GET req's associated with html coming up out of resources/public

13:09 guess I can wait for weaverjester to come back online :)

13:09 rlb: Guest79414: means that java the language (and hence compiler) cares whether or not you catch those exceptions, but the JVM doesn't, so clojure doesn't have to (and it doesn't).

13:22 Guest79414: hello

13:25 bordatoue: h

13:48 Sgeo_: Someone pinged me here but I missed it L(

14:03 gtrak: Sgeo_: there are logs

14:04 Sgeo_: gtrak, where?

14:05 gtrak: http://clojure-log.n01se.net/

14:05 Sgeo_: ty

14:12 pepijndevos: dnolen, food for thought: https://github.com/clojure/algo.generic probably not fast enough for you, though ;)

14:21 sorenmacbeth: someone told me about a clojure specific pastebin.com-like site

14:21 *** the other night. Anyone know what the name of it is?

14:22 gtrak: refheap

14:22 sorenmacbeth: gtrak: that's it. cheers

14:23 nDuff: gist.github.com has quite good Clojure syntax highlighting

14:23 (in addition to allowing git as a client, keeping revision history for gists, allowing multiple files, and all the other shiny things it does)

14:36 eggsby: I'm trying to use a routing library 'clout' by weavejester, it uses a method which when invoked with a route string and a request object, (route-matches "target" ring-request), given one request how can I easily do a sort of case/switch while capturing the result if it matches?

14:36 all I can think of is nested if-let's which seems horrifying

14:36 jbarrios: hmm, why can't my code find the log4j.properties file? I've put it all over the classpath

14:37 amalloy: eggsby: do you just want `some`?

14:37 eggsby: hmm

14:38 I'm thinking maybe thread last?

14:38 amalloy: that sounds like nonsense

14:38 eggsby: probably :)

14:38 amalloy: eg, compojure.core/routes is basically just (fn [& handlers] (fn [request] (some #(% request) handlers)))

14:39 eggsby: ya, maybe I should just use compojure

14:39 dustingetz: hi guys, i'm new to clojure - i find myself restarting the repl a few times an hour because of ns conflicts

14:39 is this normal or am i missing a best practice

14:39 nDuff: ...what kind of conflicts?

14:39 gtrak: what's an ns conflict?

14:39 pvncad: n00b here. I am having little trouble in understanding head retention. I think, i understood it in thoery

14:40 dustingetz: my `use` statements fail in the repl because something is already defined

14:40 nDuff: dustingetz: ahh. require is your friend.

14:40 dustingetz: i hesitate to use require because a lot of the time im including multiple packages of the same thing

14:40 * neotyk is wandering what is understanding in practice

14:40 pvncad: but not able to understand following example for it

14:40 gtrak: dustingetz: try 'require :as'

14:40 pvncad: (let [[t d] (split-with #(< % 12) (range 1e8))] [(count d) (count t)])

14:40 eggsby: amalloy: I basically want 'cond' but I want to capture the result of the test and provide it to the form that matches

14:40 pvncad: any help?

14:40 eggsby: is there a simple way to do that?

14:41 nDuff: dustingetz: ...I'm not sure I follow what you mean by "multiple packages of the same thing" in a way that would rule out require.

14:41 dustingetz: `(require [korma.db :as korma] [korma.db :as ???]

14:41 i want them both in 'korma' ns

14:41 aliased ns, whatever

14:41 kreig1: that's not how aliases work

14:41 dustingetz: otherwise i may as well just reference them explicitly

14:41 gtrak: eggsby: I'm imagining a cond-let

14:41 kreig1: first, you prolly don't want korma.db, just saying

14:41 korma.core I alias as kql

14:41 TimMc: No, korma.db is useful.

14:41 kreig1: you CAN access things without the alias

14:42 gtrak: eggsby: https://github.com/richhickey/clojure-contrib/blob/2ede388a9267d175bfaa7781ee9d57532eb4f20f/src/main/clojure/clojure/contrib/cond.clj#L18

14:42 kreig1: interesting, I only use it for starting up DBs

14:42 eggsby: huh, cond-let exists, how about that

14:42 kreig1: so I just [:require "korma.db"] and then call (korma.db/whatever

14:42 TimMc: eggsby: Use to exist.

14:42 nDuff: dustingetz: ...notably, you _can_ clean out a namespace with less than a restart...

14:42 kreig1: see ns-unalias etc...

14:43 gtrak: why shouldn't cond-let exist?

14:43 it seems like people re-invent it all the time

14:43 amalloy: gtrak: with different semantics each time, is why

14:44 neotyk: pvncad: what problem do you have with it?

14:44 dustingetz: i mean im not terribly wroried about restarting the repl a few times an hour

14:44 gtrak: hmm

14:44 dustingetz: its just 10 seconds of blocked thought

14:44 = reddit

14:44 haha

14:45 pvncad: neotyk: I am not able understand how reversing the count calls solves the problem

14:45 neotyk: pvncad: what problem?

14:45 pvncad: neotyk: head retention issue

14:46 neotyk: (let [[t d] (split-with #(< % 12) (range 1e8))] [(count d) (count t)]) -- the sample code

14:47 neotyk: pvncad: (count d) will realize d

14:47 pvncad: neotyk: won't it be true for (count t) as well?

14:48 neotyk: pvncad: yes, but it contains 12 elements

14:48 pvncad: while d contains 1e8 - 12

14:50 pvncad: neotyk: yes. [(count t) (count d)] and [(count d) (count t)] should behave same, right?

14:50 borkdude: neotyk what line was it again to Backbase from central station?

14:50 26?

14:50 neotyk: borkdude: I always ask skuro

14:50 borkdude: let me ping him

14:51 pvncad: neotyk:but former works but latter throws out-of-memory

14:52 neotyk: pvncad: imho both should throw oom

14:52 amalloy: pvncad: d and t both hold a reference to the 100-million-element sequence. if you count the short one first, then the compiler can release memory as it goes while it counts the big one

14:52 if you count the big one first, it has to realize the whole thing before it can start counting the small one (which is also when it can start releasing memory)

14:54 neotyk: (inc amalloy)

14:54 lazybot: ⇒ 23

14:56 neotyk: borkdude: yes, line 26

15:00 pvncad: amalloy: thanks. What is max memory used in both the cases? Is it 100M elements or ~200M elements

15:00 amalloy: meh. depends on how you count things

15:01 for the OOM case, i would accept either 100M or 200M; for the non-OOM case 0, 100M, and 200M are all good approximations

15:03 pvncad: amalloy: won't doing (count smaller-one) realizeentire the data source (range 1e8)?

15:04 amalloy: no

15:04 pvncad: amalloy: here is the code I am referring (let [[t d] (split-with #(< % 12) (range 1e8))] [(count d) (count t)])

15:06 nDuff: pvncad: why would that need to realize the entire range? Both take-while and drop-while are lazy.

15:06 pvncad: amalloy: t holds reference to lazy (range 1e8) and (count t) will realize that lazy range seq

15:07 gtrak: eggsby: you could do condp :>> identity

15:08 http://clojuredocs.org/clojure_core/1.2.0/clojure.core/condp#example_44

15:08 borkdude: neotyk tnx

15:28 Sgeo_: Why isn't there a link to logs in the topic?

15:39 TimMc: Sgeo_: Because chouser hasn't put it there. :-P

15:41 jweiss: recommended way to define a var that is only set once, at runtime: just do (defn setup [] (def myvar "x")), or (def myvar (atom nil)) (defn setup [] (reset! myvar "x")) ?

15:41 TimMc: defonce

15:41 err, maybe not...

15:42 amalloy: (def myvar (delay "x")) ;; ...at runtime, use @myvar...

15:43 jweiss: oh, hadn't thought of that amalloy

15:44 not sure that really works though, since myvar might depend on function arguments

15:44 amalloy: (def myvar (promise)) (defn setup [] (deliver myvar (f x y z))) ...

15:47 jweiss: amalloy: nice.

15:47 doesn't allow easy monkeying with the value at the repl though

15:48 i guess i'll stick w atoms since there's no apparent consensus here

15:49 TimMc: jweiss: alter-var-root doesn't help from the REPL?

15:50 jweiss: TimMc: well of course i can reset the promise and re-deliver it, but it's more of a pain

15:50 TimMc: Nah, just reset it to an atom.

15:50 It's still an IDeref

15:50 jweiss: ah true

15:51 i'd thought about just using a var because i don't have to explicitly deref and concurrency is not an issue

15:53 neotyk: is leiningen.git-deps from clojurescriptone available as standalone?

15:59 Sgeo_: Are there good FRP libraries for Clojure?

16:08 dnolen: Sgeo_: no, Stuart Sierra started on something, https://github.com/stuartsierra/cljque

16:09 but it doesn't look actively developed these days.

16:09 TimMc: How do you pronounce that, anyway? :-P

16:09 Bronsa: Cljque is pronounced "clique" or "click"

16:09 TimMc: kludge-cue?

16:09 ah

16:09 tbaldridge: I've done some playing around with FRP style coding in Clojure. The killer is the debugging

16:10 kovasb: state strikes again..

16:10 tbaldridge: If everything is async (as with cljque) it's hard to know of the event you just sent is waiting to process or it was filtered out

16:11 gtrak: ah the silent J

16:12 Raynes: The silent killer.

16:12 gtrak: trajgic

16:12 Bronsa: lol

16:13 gtrak: or tragjc

16:13 kovasb: problem is the logic is complected with the propagation

16:13 hard to test the logic seperately

16:13 tbaldridge: you basically run into the same issues as testing actor oriented code

16:14 gtrak: cljurmudgeon

16:17 kovasb: i think any frp solution should let you compute the same result "classically" on values, in addition to doing it on refs/event-sources

16:18 tbaldridge: so how do you handle the multiple output situation? For example:

16:19 (defn dispatch [source event]

16:19 (if (= source :one) (send output1 event)

16:19 (= source :two) (send output2) event)))

16:20 so that's more or less the way you'd do it in Erlang, but that litters side-effects throughout your code....

16:20 aperiodic: (inc gtrak)

16:20 lazybot: ⇒ 1

16:22 Chousuke_: tbaldridge: I think you should have a dispatch table for something like that. (send (*outputs* source) event)

16:22 kovasb: observing is more FRP style than sending IMHO

16:23 you have something that produces values, and other things that chose to consume them

16:24 how the consumers are told there is a new value to work on is an implementation detail

16:24 oh i see

16:24 misread the code

16:26 are output1 and output2 supposed to be receivers, or values?

16:26 tbaldridge: receivers

16:27 kovasb: ok

16:27 yeah that just looks like event processing to me then

16:30 tbaldridge: But the issue I see is how to perform this without ending up with impure functions.

16:30 TimMc: FRP... That's what Out of the Tar Pit talks about, right?

16:30 tbaldridge: In push-based FRP what we end up is basically Rx (from .NET) or something that looks close to what Dataflow is

16:30 dnolen: TimMc: not really

16:31 tmciver: TimMc: no, functional reactive programming, I think.

16:31 TimMc: What's this FRP, then?

16:31 Or that one.

16:32 tbaldridge: So at it's core, Reactive Programming is about connecting things together. For instance:

16:32 x = 5 * y

16:32 in reactive programming would say (x is always 5 times y, always, if y changes re-calculate x)

16:32 dnolen: TimMC: Out of the Tarpit is about Functional Relational Programming.

16:33 TimMc: Ah.

16:33 kovasb: was looking at this dissertation over the weekend

16:33 http://www.cs.brown.edu/research/pubs/theses/phd/2008/cooper.pdf

16:33 this is the flapjax guy

16:34 but more in-depth than the flapjax papers on the ideas

16:35 i think one point is, anytime you see something "send" thats basically a callback

16:36 callback is the enemy

16:37 tbaldridge: kovasb: thanks. This looks good. I'm going to have to read it.

16:37 kovasb: yeah, i finally bit the bullet and started reading these papers :)

16:37 tbaldridge: I'm on page 5 and already they're expressing the issues I run into every day.

16:38 kovasb: that one is good. the flapjax papers are also good.

16:38 definitely need to read a good FrTime paper

16:38 since that seems to be the original

16:39 also http://lampwww.epfl.ch/~imaier/pub/DeprecatingObserversTR2010.pdf

16:39 very good breakdown the problems with callbacks

16:40 though their solution is very much like flapjax, just scala-fied and more complicated

16:40 tbaldridge: don't those two go hand-in-hand? *takes cover *

16:40 kovasb: yes

16:41 its pretty interesting putting like ftp://ftp.cs.brown.edu/pub/techreports/09/cs09-04.pdf

16:41 side by side with the scala version

16:42 the question I'm really interested in tho

16:42 is how would you write that hiccup-to-dom function

16:43 in a way that lets you put refs at any point in the hiccup

16:43 but without putting a "is this a ref" logic at every branch point in the hiccup transformation code

16:46 and none of that FRP stuff really helps with that

16:49 uvtc: I saw a snippet posted here a while ago (by xeqi) and was trying to figure out how it works. Here it is, with a bit more formatting: https://www.refheap.com/paste/3113 . My question is,

16:50 how does that (conj ...) not go off and create an infinite list causing the whole thing to blow up?

16:50 Whenever I use `iterate`, I'm always careful to put it inside a `take`...

16:52 matthavener: uvtc: because map will evaluate it lazily with (concat ...) and (concat ...) is bounded by the size of x

16:52 Sgeo_: Infinite lists are not a problem unless you try to show them

16:52 Or otherwise do something with every element

16:53 uvtc: Oh. I realized that map *returns* a lazy seq, but did not realize that it evaluates its args lazily as well.

16:53 Also, I see how it goes lock-step with the concat-generated seq.

16:53 Thanks!

16:53 Sgeo_: :/

16:54 That's ... not quite... arguments in Clojure are always strictly evaluated, if I understand correctly

16:54 S11001001: uvtc: it doesn't, and can't, *not* evaluate its args, because it is an ordinary function. It does just so happen to not force what you give it, if it's a lazy seq

16:54 as Sgeo_ says

16:54 Sgeo_: $heval (const 5) (1/0)

16:54 lazybot: ⇒ 5

16:55 Sgeo_: ,((constantly 5) (/ 1 0))

16:55 clojurebot: #<ArithmeticException java.lang.ArithmeticException: Divide by zero>

16:55 Sgeo_: In the former, the arguments are lazily evaluated. The 1/0 is never even done

16:55 In the latter, even though (constantly 5) ignores its argument, the argument is still evaluated

16:56 Thus the blow up

16:56 ,((constantly 5) (repeat 3))

16:56 clojurebot: 5

16:57 Sgeo_: In this case, (repeat 3) is evaluated. However, all it returns is an object that, when something asks, will give back stuff

16:57 Although it is in principle an infinite sequence, it is such that it doesn't try to store all of them at once.

16:57 However, the (repeat 3) still does get evaluated.

16:57 S11001001, is that a clear demonstration?

16:57 uvtc, does this help?

16:58 uvtc: (sorry, distracted --- family came home ... just a minute)

16:58 S11001001: Sgeo_: yes

16:59 Sgeo_: So glad lazybot can do Haskell >.>

16:59 S11001001: constantly is particularly good for examples; in truly nonstrict languages, the evaluation behavior of the second arg is totally irrelevant by definition

16:59 as Sgeo_ showed were I to scroll back up more :)

17:01 uvtc: Sgeo_, I'm not familiar with `const`. I don't see any docs for it, and it's not listed at clojuredocs...

17:02 Sgeo_: uvtc, $heval does Haskell, not Clojure

17:03 const in Haskell is similar to constantly in Clojure

17:03 With the illustrated difference, due to Haskell being nonstrict and Clojure being strict.

17:03 brehaut: (inc Sgeo_)

17:03 lazybot: ⇒ 1

17:03 brehaut: ^ points for semantic pedantry

17:03 Sgeo_: lol

17:04 I personally don't actually understand the difference between nonstrictness and laziness, but I vaguely know there is one.

17:04 brehaut: likewise :P

17:04 i think bottom is involved?

17:04 Sgeo_: I _think_ that laziness is a way of being nonstrict but not the only way?

17:05 As in, laziness is a subset of nonstrictness? I may be totally wrong though

17:07 uvtc: Sgeo_, Ok, I see what you mean. ((constantly 5) x) evaluates x (which is why ((constantly 5) (/ 1 0)) blows up), but although it evaluates the arg in ((constantly 5) (repeat 3)) , `repeat` returns a lazy result. I'm just used to seeing look non-lazy because I evaluate it in the repl.

17:08 Sgeo_: uvtc, correct.

17:08 uvtc: Thanks, Sgeo_ !

17:08 Sgeo_: <elliott> Sgeo_: Non-strictness is about operational semantics.

17:08 <elliott> Laziness is a certain implementation strategy of non-strictness (call by need).

17:13 xeqi: uvtc: looks like you got an answer, and there was a better solution using partition w/ 4 args later

17:14 uvtc: Hi xeqi, Yes, thanks. I was going to look at that one next, but I got stuck on the first one. :) Now I'm just writing up some notes before continuing.

17:21 Sgeo_: How often are there questions about Clojure's nonstrictness or lack thereof?

17:22 brehaut: not that often

17:25 Sgeo_: brehaut, aww

17:25 That means less opportunity for me to be helpful

17:25 I don't actually know much Clojure

17:26 I had to check the cheatsheat to see that repeat actually exists

17:55 brehaut: Sgeo_: most of the clojure questions about laziness are around people mistakenly putting side effecting logic or accessing dynamic bindings in lazy code

17:56 Sgeo_: Ah

17:57 8:24 of the second song in [S] Jane: Enter?

17:58 ....wrong channel

17:59 pepijndevos: is there something like vim starterpack?

18:02 gfredericks: no, vim is completely ideal by default

18:10 is there a java/clojure library that can easily compute distance between two lat/lng pairs?

18:12 mwillhite: quick google: http://openmap.bbn.com/

18:12 http://stackoverflow.com/questions/120283/working-with-latitude-longitude-values-in-java

18:14 gfredericks: mwillhite: thx; you're apparently a better googler than I

18:37 semperos: gfredericks: the GeoTools lib is part of a larger suite of open source geo tools that get a lot of development attention, have been quite impressed

18:38 kay__: hat are they

18:39 what*

18:42 semperos: kay__: see the right-hand sidebar of this page for a list of the OSGeo projects: http://www.osgeo.org/

18:42 timvisher: is mmcgrana ever ever on here?

18:43 kay__: nice

18:44 technomancy: timvisher: he doesn't really do IRC

18:53 timvisher: technomancy: what's the best way to try to get him to look at one of the issues on ring-json-params?

18:56 Sgeo_: You know, this might have been a better illustration

18:56 ,(class (repeat 3))

18:56 clojurebot: clojure.lang.LazySeq

18:56 amalloy: timvisher: break into his house and staple a printout of a screenshot on the ceiling above his bed

18:56 technomancy: timvisher: he's pretty hard to get a hold of, but he's pretty good at delegating to others when he doesn't have the bandwidth. doesn't weavejester mostly handle ring these days?

19:25 timvisher: amalloy, technomancy: makes sense. I wasn't aware that weavejester had taken over. I can open an issue there.

19:25 thanks

19:41 amalloy: well, i never expected "makes sense" as a response to my suggestion

19:50 arrdem: anyone here worked with fnparse?

19:56 timvisher: amalloy: yeah, do you have his address?

19:58 gfredericks: timvisher: I think it would be funny if he said "yeah I'll pm you" and that was all either of you said on the topic

19:59 technomancy: other than "/me writes note to self to restock staples" maybe

20:00 timvisher: gfredericks: I agree. shame he's not playing along ;)

20:01 so turns out that weavejester never forked ring-json-params, sadly

20:01 is it considered an ok practice to upload a custom version of a standard library to clojars?

20:02 brehaut: timvisher: as long as you use your own group id

20:03 technomancy: oh, it's not part of ring proper?

20:03 timvisher: nope

20:03 brehaut: ah, i see that now

20:04 brehaut: arrdem: yes

20:04 arrdem: im pretty sure it hasnt been updated for even clj 1.3

20:05 arrdem: at this point its pretty much abandonware

20:26 timvisher: does anyone think that leaving body in a consumed state is a good idea for wrap-json-params?

20:26 i can't see the reasoning behind it

20:27 seems better to turn it into a string and then try to parse it, so that you can do something sensible with the data rather than having a consumed object in that spot

20:28 arrdem: brehaut: yeah it really is abandonware... I see a couple people who have updated it themselves but there aren't lein packages for the updates. I had a question about writing recursive definitions becuause what I had wasn't working. Then I re-thought my BNF and the light of heaven shown down on me and all was resolved.

20:29 technomancy: timvisher: a consumed reader? yeah that seems silly but I don't see why it would hurt

20:29 brehaut: arrdem: ok cool

20:34 timvisher: technomancy: basically, if you're trying to be nice to your clients and give them plenty of data back as far as why they're request failed, one of the things I'd want is the body that I sent. But with wrap-json-params consuming body and then throwing an exception, I have no way of getting at it because it's been consumed.

20:34 that seem to make sense?

20:35 so if you're trying to parse json, then assuming you can get it as a string seems to be a good idea

20:35 i guess the problem might be if someone is malicious and sends you a 500 MB movie or something like that and you try to read the whole thing into a string

20:38 emezeske: timvisher: FWIW, I like to enforce POST parameter size limits at the web server layer (e.g. in nginx.conf), and let the webapp itself be oblivious. YMMV, though.

20:46 timvisher: emezeske: interesting option! I hadn't thought of that

20:46 i assume jetty can do similar things

20:53 gfredericks: omg guys logic programming is so much fun.

20:55 llasram: gfredericks: It looks like it! I still haven't found anything cool do with it yet though :-(

20:57 What are you solving with it?

20:57 gfredericks: a few years back I had written a crappy-javascript AI for a game that my sister apparently still plays against and she wanted me to make it easier. So I'm just rewriting it in core.logic.

20:57 llasram: Oh, cool

21:14 muhoo: &(keyword (.toString *ns*) "fubar")

21:14 lazybot: java.lang.SecurityException: You tripped the alarm! class clojure.lang.Namespace is bad!

21:15 gfredericks: muhoo: yes?

21:15 mthvedt__: are there any good docs/tutorials for core.logic

21:15 besides "read the reasoned schemer"

21:16 gfredericks: nothing that compares to that

21:50 muhoo: i'm trying to figure out a way to serialize namespaced keywords to json couch and back again

21:54 adu: muhoo: namespaced?

21:54 muhoo: fully qualified :foo.bar/baz not :baz

21:59 nDuff: muhoo: I'm not sure a fully generalized solution is possible for that, since anything JSON can represent already has a meaning in Clojure

22:01 muhoo: i'm just going to do (keyword (.toString *ns*) foo)

22:11 gfredericks: wait what? what's wrong with {"foo.bar/baz": 12}?

22:12 echo-area: gfredericks: There's an extra colon there

22:13 gfredericks: echo-area: eh? I ment it as JSON

22:24 xeqi: technomancy: ... it worked for me

22:27 argh, refheap middle click

22:28 technomancy: https://www.refheap.com/paste/3115

22:29 heh, wrong chan

22:58 Raynes: xeqi: I'd care more about that if I had a computer that had a mouse that had a middle click and if I actually would use it if I did have one.

22:58 xeqi: I've been hoping somebody would care enough to fix it, since it's all Javascript crap that I'm unfamiliar with in the first place. :\

22:59 xeqi: I'm surprised it hasn't been fixed upstream

23:36 lynaghk: Has anyone used goog.inherits to extend a goog Closure library object in ClojureScript?

23:40 devn: lynaghk: https://bitbucket.org/puffnfresh/cajole/src/efb0ae91bad5/src/cajole/editor.cljs

23:41 lynaghk: devn: sweet, thanks

23:41 devn: lynaghk: thank google ;)

23:41 (my speciality)

23:42 muhoo: is there a more concise form of : (if pred (assoc m :bah "stuff") m) ?

23:42 devn: lynaghk: im curious now

23:42 lynaghk: what does it do?

23:42 muhoo: erm, i dont think so?

23:42 muhoo: kind of an if-assoc, that'll return the map without the assoc if the pred isn't truthy?

23:43 devn: write one. ;)

23:43 lynaghk: devn: I'm trying to put something clickable within an item in a goog.ui.PopupMenu. However, by default onBlur the popup menu will hide

23:43 muhoo: well, sure, but in clojure "there's a function for that!" seems to be common

23:45 devn: muhoo: fair enough, but the list is only so long

23:46 gfredericks: muhoo: I think you want fix from flatland/useful

23:46 devn: muhoo: that seems like a "nice to have which is easily written"

23:46 amalloy: (inc gfredericks)

23:46 lazybot: ⇒ 6

23:47 amalloy: oh man. the karma plugin should keep track of where your karma comes from. that way when they see all my karma comes from clojurebot, they'll know i was just gaming the system

23:47 devn: muhoo: i think you want to probably not pull in useful as a dependency and just add the function yourself

23:48 muhoo: gfredericks: that's hilarious, i was just thinking "hmm, i should see if it's in useful"

23:49 gfredericks: devn: he wants to do that over and over again in each of his projects

23:49 clojurebot: No entiendo

23:49 gfredericks: I guess if everybody used useful that could get complicated though

23:50 dependencies are hard

23:50 we need inline dependencies

23:50 devn: gfredericks: yeah, it just is a lot to swallow. it seems like about 20 different dependecies to me

23:50 dependencies

23:50 muhoo: no SHIT. i'm still dealing with a crazy hairball with jackson

23:50 amalloy: i wonder how many people actually do. the maintenance is sorta cowboyish in places; if like everyone is using it maybe we should figure out a way to be more careful

23:50 muhoo: well, i decided to punt for now, but i will have to deal with it before heroku goes with lein2

23:51 amalloy: but i doubt everyone is, really. that would be a good problem to have

23:51 gfredericks: amalloy: I mostly just constantly wish I was using it

23:51 mumbling to myself about how I could use fix here or there

23:51 amalloy: tbh, for muhoo's case (where pred is a value, not a function of m) fix has some sharp edges

23:52 devn: why not just write the fn yourself?

23:52 it's pretty straightforward, no?

23:52 gfredericks: based on trying to distinguish between values and functions?

23:53 muhoo: i did write, but it's super ugly: https://www.refheap.com/paste/3116

23:53 devn: that's not ugly to me

23:53 amalloy: gfredericks: yes

23:53 gfredericks: oh man devn is flirting with muhoo's function in public

23:53 devn: lol

23:54 muhoo: devn: really? watch amalloy turn it into one line with 5 symbols :-)

23:54 devn: stop golfing, brother.

23:54 amalloy: that's the sort of thing ninjudd likes to do a lot more than i do

23:54 gfredericks: you're prettier than you think you are, little function

23:54 muhoo: devn: fair

23:54 devn: muhoo: golfing is fancy. it's interesting, but clever and fancy. just write the goddamn mother fucking code.

23:55 gfredericks: copy, paste, getirdone

23:55 muhoo: i do plenty of that, for sure.

23:55 devn: lol. i dont want to advocate copy and paste or doing it wrong on purpose for the sake of deadlines or what have you

23:55 muhoo: clojure does impel me towards elegance, even golf, at times.

23:55 devn: but preoccupation with LOC and so on can really kill the spirit

23:55 the shitty code i've written in clojure is better than its imperative mutable equivalent

23:56 i need to remind me of that

23:56 * gfredericks figures that the phrase "elegance, even golf" doesn't come up too much in normal people conversation

23:56 devn: s/me/myself

23:56 gfredericks: lol

23:57 amalloy: any thoughts of splitting up useful into a more modular set of dependencies?

23:58 gfredericks: useful.logic

23:58 useful.jdbc

23:58 useful.match

23:58 useful.php

23:58 devn: i really cringe when i decide ill pull in useful and the kitchen sink and an in-unit dishwasher/lawnmower. I just want seq.clj sometimes. Sure I can require that, but id rather it be spelled out in the project's deps. It feels less dirty.

23:58 lynaghk: devn: that link you sent totally worked. I'm in awe; I've been fighting with this one for hours. thanks again!

23:59 devn: useful.hair-dryer

23:59 amalloy: too much hassle, both to maintain and to use. if it were actually being used as much as old-contrib, it would be worthwhile/necessary

23:59 devn: lynaghk: no problemo

23:59 gfredericks: I think muhoo should fork useful and call it mooseful

23:59 amalloy: the "size" of the dependency is only cognitive load anyway - the jar is not large

23:59 devn: muhoosful

Logging service provided by n01se.net