#clojure log - Sep 18 2012

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

0:00 mpan: ,([1 2] 2)

0:00 clojurebot: #<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException>

0:00 mpan: ,('(1 2) 2)

0:00 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn>

0:03 xeqi: &(map [1 2] [0 1 2])

0:03 lazybot: java.lang.IndexOutOfBoundsException

0:03 xeqi: &(map [1 2] [0 1])

0:03 lazybot: ⇒ (1 2)

0:45 mpan: how can I map a seq of xs to a seq of [index x] according to index in seq?

0:46 is there a shortcut besides generating range and pulling out nth?

0:47 amalloy: &(map list (range) '(a b c))

0:47 lazybot: ⇒ ((0 a) (1 b) (2 c))

0:48 mpan: thank you!

1:13 Sgeo: ,(range)

1:13 clojurebot: (0 1 2 3 4 ...)

1:13 Sgeo: Cool

1:13 &(map vec (range) '(a b c))

1:13 lazybot: clojure.lang.ArityException: Wrong number of args (2) passed to: core$vec

1:13 Sgeo: &(map vector (range) '(a b c))

1:13 lazybot: ⇒ ([0 a] [1 b] [2 c])

1:33 blrandel: Raynes: hey, I was just curious - are there likely to be tutorials/guides for using the 'pinot' libs with Noir at some point?

1:33 would be great to see a sample app that pulls everything together, both client and serverside

1:34 ibdknox: guess I should probably be asking you too :)

1:45 l1x: ,(reduce #(assoc %1 %2 (inc (%1 %2 0))) {} '(a b b c c c))

1:45 clojurebot: {c 3, b 2, a 1}

1:45 l1x: can somebody explain this?

1:48 shoky: l1x: which part troubles you

1:48 l1x: first i dont understand what inc does

1:49 shoky: did you read the docs?

1:49 ,(doc inc)

1:49 clojurebot: "([x]); Returns a number one greater than num. Does not auto-promote longs, will throw on overflow. See also: inc'"

1:49 l1x: i mean in this (inc (%1 %2 0))

1:49 shoky: do you know that maps are functions of their keys?

1:50 %1 is the map supplied to reduce

1:50 er to the reducer function

1:50 l1x: och ok

1:50 %2 comes from the coll?

1:50 shoky: %2 is the current item which also servers as the key in the map being created

1:50 yes

1:50 serves*

1:51 l1x: ok

1:51 shoky: and the 0 is returned if the key is not found, meaning we're adding a new key right now

1:52 raek_: take a look at the function with other variable names: (defn step [m item] (assoc m item (inc (get m item 0))))

1:52 l1x: ,(inc ({2 1} 2 0))

1:52 clojurebot: 2

1:53 l1x: ,(inc ({1 0, 2 0, 3 0} 2 0))

1:53 clojurebot: 1

1:53 raek_: this could also be written as (defn step [m item] (update-in m [item] (fnil inc 0)))

1:54 l1x: shoky: thanks i think i am getting it now

1:54 pretty awesome

1:54 shoky: np

1:54 raek_: (reduce step {} '(a b c)) is the same as (step (step (step {} 'a) 'b) 'c)

1:54 shoky: indeed

1:55 l1x: , (assoc {1 0, 2 0, 3 0} 2 (inc ({1 0, 2 0, 3 0} 2 0)))

1:55 clojurebot: {1 0, 2 1, 3 0}

1:55 l1x: this is what is happening ^

1:56 shoky: there won't be zero values in the map

1:56 because for a new key, we add (inc 0)

1:56 which is 1

1:56 l1x: yeah of course, it is just for me for easier understanding

1:57 thanks a lot

1:57 shoky: kk

1:57 yer welcome. im a clojure noob myself, you're the first person i've helped with a problem. so thanks also ;P

1:59 l1x: heheheheh

1:59 i guess many clojure noobs around, the popularity is increasing sharply

2:00 it was a total accident for me, i have decided to learn lisp just to improve my coding skills and somebody hit me with a clojure book at the very same time

2:00 but this is totally insane

2:00 this language is just perfect

2:01 shoky: ;]

2:09 yankov: damn, anyone knows if clojure group is moderated? posted a long post there and it didn't show up..

2:10 dhofstet: yankov: it's moderated for new members, see https://groups.google.com/group/clojure/about

2:11 yankov: dhofstet: oh, thx. phew..

2:11 tomoj: "Waiting on whether Clojure becomes a JSON superset." wat?

2:11 related to edn?

3:13 mpan: is iterate not tail recursive?

3:15 I'm confused by taking the nth of the result of iterate

3:15 the source doesn't suggest I'd get a stack overflow but I do?

3:16 tomoj: &(nth (iterate inc 0) 1e7)

3:16 lazybot: ⇒ 10000000

3:19 mpan: is there an alternative I could try for "f applied n times to x"?

3:19 just to see if that or something else is the issue?

3:21 * Sgeo should attempt to understand lazy-seq

3:21 mpan: &(reduce (fn [a b] (+ 1 a)) 0 (range 1e7))

3:21 lazybot: ⇒ 10000000

3:22 mpan: wonder if that one would work

3:24 Sgeo: The source for lazy-seq mentions fn* but I can't find it

3:28 Hmm

3:28 So, bound-fn* uses a with-bindings* thing

3:28 This... could be useful in my rethinking of algo.monads

3:31 mpan: switching nth of iterate for the reduce-based thing worked

3:31 but I'm still curious why, because nth seems to discard as it goes along, right?

3:35 Sgeo: with-bindings* could prove... useful to me

4:06 In Hiccup, why is it specified that, "Additionally, the ID must always come first, so div#foo.bar would work, but div.foo#bar would not."

4:07 "Hiccup is intelligent enough to render different HTML elements in different ways, in order to accommodate browser quirks:"

4:07 What happens with elements that Hiccup doesn't recognize

4:09 augustl: Sgeo: probably renders them like normal XML

4:11 kral: nmaste

4:12 clgv: good morning

4:15 callen: but seriously

4:15 what is the fucking deal with parsing xml in Clojure?

4:15 it has the same goddamn semantic structure as S-expressions, it should be ace at this.

4:16 clgv: callen: still struggling with it?

4:16 callen: instead I'm bashing my head into a bloody stump against the walls of clojure.data.zip.xml

4:16 clgv: yes, and raging myself to death.

4:16 I'll refheap it.

4:17 https://www.refheap.com/paste/5129

4:17 clgv: ^^

4:17 zx is clojure.data.zip.xml

4:17 which is what I saw in sie examples.

4:17 * callen returns to cargo-culting code from Google

4:18 clgv: I did not use that lib yet.

4:19 callen: mapcat-chain...cond...text...yes I know some of these words...

4:19 I vaguely remember using mapcat on 4clojure.

4:19 hoeck1: callen: what about: (zx/xml-> zipped first :dwml :version) ?

4:20 callen: zip is generally excellent at navigating throug trees

4:20 callen: java.lang.NullPointerException: null

4:20 hoeck1: nice try sport.

4:20 hoeck1: NPE though.

4:20 testing other "queries" using the same first function, no dice so far.

4:21 incidentally, passing it second instead of first returns () for all queries

4:21 instead of the null pointer exception

4:21 the raw data structure is in that refheap I pasted, you can try it yourself.

4:21 and know my horrors.

4:22 I'm going to rename Clojure to Clothulhu for the raw terror and hatred it has made me experience, but I cannot pry myself from its spell.

4:22 hoeck1: ah, [[:dwml {:version ...}]], so its: (-> .... first second :version)

4:22 callen: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword

4:22 Sgeo: What's the difficulty?

4:22 callen: (I have nrepl open and at the ready)

4:22 tomoj: callen: is that the zipper?

4:22 callen: Sgeo: XML parsing.

4:22 tomoj: is what the zipper? the exception?

4:22 tomoj: the raw data structure in your paste

4:23 callen: post-zipped tree.

4:23 Sgeo: So, each vector's first element names the element, second is attributes, third is contents

4:23 Sorry, not third. rest, I assume

4:23 callen: zipped == (zip/xml-zip (tagsoup/parse-string test_body))

4:23 ^^

4:23 then!

4:23 for my next trick...

4:24 user> (zx/xml-> zipped first :dwml :version)

4:24 NullPointerException clojure.zip/branch? (zip.clj:73)

4:24 walla, no more pencil.

4:24 just a dead henchman.

4:24 riddle me that, bats.

4:24 Sgeo: nil must die.

4:24 That's the riddle.

4:24 Null and nil are horrible and evil

4:24 callen: I'm certainly in the mood to declare the death of things

4:25 but considering you're in the channel for a dynamically typed language, grumbling about nulls, Nones, nils, voids, etc is a bit like chucking a boulder in a glass house.

4:25 the Scala and Haskell fascists are down the hall, and probably more successful at parsing XML than I presently am.

4:25 * Sgeo is coming from the Haskell world, so

4:26 callen: right well uh

4:26 even if wasn't an NPE, it'd be a type-error

4:26 Sgeo: I'm mostly interested in Clojure because of the macros

4:26 callen: which is equally unhelpful at present

4:26 hoeck1: callen: could you please paste a pprint of the (zx/xml-> zipped) call?

4:26 callen: I have been

4:26 repeatedly.

4:26 08:20 < callen> user> (zx/xml-> zipped first :dwml :version)

4:26 08:20 < callen> NullPointerException clojure.zip/branch? (zip.clj:73)

4:26 Sgeo: And the somewhat large community around it

4:26 callen: would you like me to quote myself quoting myself?

4:26 Sgeo: And the niceness of changing code at run-time

4:27 callen: Sgeo: ah yes the siren song of macros.

4:27 Sgeo: once you get past the whole gensym thing, it gets a lot more sane than you might expect.

4:27 which is frankly, a sticking point for Schemers because they're big babies.

4:27 hoeck1: callen: without the trailing :first :dwml :version

4:28 callen: user> (zx/xml-> zipped :dwml :version)

4:28 ()

4:28 Sgeo: I can't say if Scheme macros might be better or easier, because, unlike CL-style macros, I flat out do not understand Scheme macros.

4:28 CL-style macros are conceptually easy.

4:28 callen: hoeck1: bro, I have like, 100 repl lines of getting Unit() tossed at me.

4:28 hoeck1: of a multitude of :blah combinations

4:28 tomoj: how did you create that zipper?

4:28 callen: that's not the answer. trust me.

4:28 I've also pasted that ;_;, h/o

4:28 (def parsed (tagsoup/parse-string test_body))

4:28 (require '[clojure.zip :as zip])

4:28 (def zipped (zip/xml-zip parsed))

4:28 (require '[clojure.data.zip.xml :as zx])

4:28 Sgeo: Although I do want to yell at Hickey for sticking with CL's insane idea for not making a ... "real" version so to speak of ` and ~

4:29 As in, there's no quasiquote and unquote forms... at least that I know of

4:29 hoeck1: callen: zippers are different from clojure datastructures, eg: http://www.exampler.com/blog/2010/09/01/editing-trees-in-clojure-with-clojurezip

4:29 callen: Sgeo: honestly man, the macros in Clojure are more sound than Template Haskell anyway.

4:29 Sgeo: I wouldn't sweat it.

4:29 Sgeo: callen, I'm not sweating anything

4:29 callen: hoeck1: and the...takeaway...is?

4:30 tomoj: ^^ see above?

4:30 tomoj: (z/next z) throws an exception

4:30 ..that shouldn't happen

4:30 hoeck1: callen: so maybe (zx/xml-> zipped zip/down zip/left) et cetera are your friends

4:30 callen: tomoj: now do you know why I've dubbed it clothulhu!?

4:31 hoeck1: yeah uh, I'm not manually traversing the layers of the tree.

4:31 hoeck1: that's fucking stupid.

4:31 tomoj: can you paste the xml? (not in here)

4:32 callen: that's like going herp['derp'][0][0][1].textNODE[1][0][2] willynilly in python

4:32 fuck. that.

4:32 tomoj: yes, h/o

4:32 tomoj: https://www.refheap.com/paste/5130

4:32 Sgeo: I've done code like that in Tcl

4:32 callen: tomoj: that's the clojure string of the http body returned by the REST XML endpoint.

4:32 Sgeo: Tcl people are psychotic.


4:33 Sgeo: Mostly because I couldn't get a sufficiently new version of some XML library into my environment

4:33 callen: Sgeo: I'm seeing a pattern.

4:33 one that deeply horrifies me.

4:33 Sgeo: What, that I've explored a lot of languages?

4:33 callen: no, that XML is a fucking curse in every language.

4:33 who the hell is responsible for that anyway? Tim Bray?

4:34 tomoj: huh

4:34 callen: your huh worries me.

4:34 tomoj: what is tagsoup?

4:34 callen: tomoj: it's gov't generated XML, if that comforts you.

4:34 tomoj: a clojure wrapper?

4:34 I get a very different zipper using clojure.xml/parse

4:34 callen: tomoj: the XML parser I had to use that worked, whereas the clojure.xml parser, I kid you not, choked on this XML and threw an exception.

4:34 when I tried to use clojure.xml/parse it failed.

4:34 tomoj: I get no exception with that xml

4:34 callen: what in the mother...hrm. h/o

4:35 tomoj: clojure.lang.Compiler$CompilerException: java.net.MalformedURLException: no protocol: %3C?xml%20version=%221

4:35 tomoj: that's what I get.

4:35 when I attempt (def newparsed (clojure.xml/parse test_body))

4:35 tomoj: (doc clojure.xml/parse)

4:35 clojurebot: Titim gan éirí ort.

4:35 callen: the bot appears to have demons.

4:36 * Sgeo backs away slowly from clojurebot

4:36 tomoj: if you pass xml/parse a string, it thinks it's a filename

4:36 callen: oh jesus fucking christ

4:36 why can't I pass the dumb bastard a goddamn string?

4:37 Sgeo: I wonder if passing it a data: URI would work? </dumbhacks>

4:37 tomoj: apparently because that's the way the sax interface in java is

4:37 callen: that is horrid. why the hell wouldn't an XML parser take a static string?

4:37 kgjnel;ksgnertgkl;te

4:37 e. fucking. gads.

4:38 * callen cries

4:38 Sgeo: It's Java.

4:38 Don't expect it to make sense

4:38 tomoj: well, how'd you get a string?

4:38 callen: I just...want to pass a string...to a textual function...

4:39 even Haskell got this right by allowing you pass String, Text, ByteString, or run a streaming parser all in the same place.

4:39 tomoj: a URL, but it may not always be a GET

4:39 Sgeo: ByteStrings are not text, don't treat them as such.

4:39 callen: tomoj: in the case where it's not a GET, xml/parse will not work.

4:39 Sgeo: yes yes, I know.

4:39 I need to be able to acquire the string separately and pass it to clojure.xml/parse

4:39 Sgeo: It should be a simple amount of Java interop

4:40 http://stackoverflow.com/questions/837703/how-can-i-get-a-java-io-inputstream-from-a-java-lang-string

4:40 uh

4:40 http://www.koders.com/java/fid0A51E45C950B2B8BD9365C19F2626DE35EC09090.aspx

4:40 That's... a bit much

4:40 tomoj: (clojure.java.io/input-stream (.getBytes "<foo></foo>"))

4:40 callen: you make me hate life.

4:40 or rather, Java makes me hate life.

4:40 tomoj: I don't know what you mean about xml/parse not working with GET

4:40 callen: Sgeo: holy---

4:40 tomoj: invert that statement.

4:40 tomoj: it doesn't work if I need to do a POST with a POST body.

4:41 tomoj: why not?

4:41 callen: I already have it working for the GET, but I'd rather just do the HTTP request separately.

4:41 Sgeo: tomoj, why does that need to be .getBytes?

4:41 ,(clojure.java.io/input-stream "Hello")

4:41 clojurebot: #<SecurityException java.lang.SecurityException: denied>

4:41 Sgeo: &(clojure.java.io/input-stream "Hello")

4:41 lazybot: java.security.AccessControlException: access denied (java.io.FilePermission Hello read)

4:41 Sgeo: oh

4:41 callen: well, it worked.

4:41 tomoj: same reason, basically

4:41 callen: (clojure.xml/parse (clojure.java.io/input-stream (.getBytes test_body)))

4:41 Sgeo: ,(clojure.java.io/input-stream (.getBytes "Hello"))

4:41 clojurebot: #<BufferedInputStream java.io.BufferedInputStream@76e47eb7>

4:41 callen: I'll see if I can extract the data.

4:42 Sgeo: Wait.

4:42 A string is not a series of bytes.

4:42 * Sgeo wtfs

4:42 callen: Sgeo: here's a real mind-twister for you

4:42 Sgeo: Java is UTF-16

4:42 elzibub: UTF-8, no? Only some characters are wide

4:43 tomoj: callen: if you are getting the xml from an http request, you should be able to get an input stream for the body. maybe you already know this, I still don't know what you mean about POST

4:43 callen: elzibub: Java originally used UCS-2, and added UTF-16 supplementary character support in J2SE 5.0.

4:43 tomoj: lets put it aside for now, the getBytes hack is working.

4:43 Sgeo: elzibub, translation: A character is two bytes wide unless it's four bytes.

4:43 callen: tomoj: thank you for your help so far. I'm continuing along.

4:43 Sgeo: thank you for the moral support :)

4:44 Sgeo: :)

4:44 ,(clojure.java.io/input-stream "data:text/text,blah")

4:44 callen: sigh, son of a bitch

4:44 clojurebot: #<SecurityException java.lang.SecurityException: denied>

4:44 callen: the structure is different, but the zipper still isn't working and is throwing NPEs again.

4:46 hey uh, Sgeo tomoj...

4:46 https://github.com/clojure/data.xml you know this has parse-str for XML right?

4:46 and it works fine?

4:47 seemingly?

4:47 (def parsed (clojure.data.xml/parse-str test_body))

4:47 tomoj: cool

4:47 Sgeo: I have not had any need to parse XML in Clojure yet

4:47 callen: despite that, still getting NPEs

4:48 gjn;ekrjsg

4:49 parse-str is what the internal clojure code uses.

4:49 tomoj: (zx/attr z :version)

4:49 callen: I knew I wasn't crazy.

4:50 tomoj: that's the first thing that's returned something.

4:50 tomoj: (zx/xml1-> z :dwml) searches for the inner dwml in "<dwml><dwml></dwml></dwml>"

4:51 you are already there, no need to search

4:52 also (zx/xml1-> z :version) looks for <dwml><version></version></dwml>

4:52 callen: tomoj: what if I want it to search to arbitrary depths and return all tags that have a particular name?

4:52 like <Temperature></Temperature>

4:52 and return a list of everything that had that tag name.

4:52 tag=?

4:53 tomoj: (tag= :foo) is the same as just :foo inside xml->

4:53 callen: doesn't return anything though.

4:54 I think it elided information.

4:54 no wait, I found :temperature

4:54 (#clojure.data.xml.Element{:tag :temperature, :attrs {:type "maximum", :units "Fahrenheit"

4:54 user> (zx/xml-> z :temperature)

4:54 ()

4:55 tomoj: you have to descend

4:55 callen: that's what I asked

4:55 how do I get it to exhaustively search the tree and return all tags matching a name?

4:55 that's what my Python code does, trivially.

4:55 tomoj: sometimes I'll do (zx/xml-> z dz/descendants :temperature)

4:56 dz is clojure.data.zip

4:56 callen: it's not clear to me that it did anythign other than return everything.

4:57 tomoj: that's because it's a zipper, you got a seq of locs back

4:57 if you want the nodes do (zx/xml-> z dz/descendants :temperature z/node)

4:57 callen: tomoj: you do appreciate how much simpler this is in Python, yes?

4:57 tomoj: no. easier, maybe.

4:57 callen: wait, what's z? clojure.zip?

4:58 tomoj: yeah

4:58 callen: that worked.

4:58 augustl: is lazytest still maintained? Nothing seems to have happened since 2012

4:58 2010*

4:59 callen: tomoj: easy is pretty important

4:59 tomoj: having to overcome all this to do what I was able to reproduce in Python in about 2 minutes (not exaggerating) is a bit extreme.

4:59 really have to make my language/technology decisions based almost 100% on time and virtually nothing else.

4:59 so even if Clojure is more elegant, or in your world, simpler, it still leaves me with lost time.

5:00 there's got to be a better way than this.

5:00 augustl: callen: easy is only important when you're new to something :)

5:00 callen: augustl: I was perfectly productive in Common Lisp.

5:00 that's how I came to Python.

5:00 augustl: clojure is pretty different from most other lisps though

5:01 callen: I don't see how that's true.

5:01 augustl: I personally don't find easy to be that important. The phase of getting to know something is finite

5:01 callen: it's at the opposite end of the spectrum of Emacs Lisp.

5:01 augustl: I did like 50 exercises in 4clojure and I'm still strugging here.

5:01 augustl: then I spend the rest of my life knowing it

5:01 callen: struggling.

5:02 augustl: sure, Clojure hard to learn, I've programmed clojure full time for almost 3 months now and I'm still learning new things every day

5:03 callen: 54 exercises in 4Clojure.

5:03 (I just checked)

5:03 augustl: callen: in here we all use this definition of "easy" btw ;) http://www.infoq.com/presentations/Simple-Made-Easy

5:03 callen: still data.

5:03 nada*

5:03 ambrosebs: Has anyone been informed if their Clojure Conj 2012 talk was accepted?

5:03 augustl: ambrosebs: I haven't

5:03 callen: augustl: I'm fully familiar with the reference, that's why I'm all the more contemptuous of it.

5:03 Rich Hickey is a genius, you guys parroting him however smart he may be, isn't.

5:04 if you had come to this conclusion on your own, or were otherwise providing feedback that wasn't a restatement of his talk I'd take you more seriously.

5:04 this is worse than Common Lispers quoting Norvig.

5:04 oi vey.

5:04 augustl: callen: you seem to be quite upset..

5:04 callen: augustl: Actually I just find cargo-cultish engineering behavior upsetting.

5:04 pyrhho: so, only newton is allowed to talk about gravity?

5:05 callen: no, but simply restating the title of his paper on gravity over and over doesn't constitute useful discourse either.

5:05 ambrosebs: augustl: Neither. Would love to know soon ..

5:05 augustl: callen: the use of the word "easy" is very thoughtful on my part at least, not sure what makes you think everyone else here is using it without any thought.

5:05 pyrhho: callen: fair enough

5:05 callen: so can we put the strawmen aside and speak from our own minds?

5:05 augustl: the last 5 minutes?

5:06 augustl: callen: now you're just being "angry person on the internet", this isn't very productive

5:06 callen: augustl: and longer term, just general exposure to the Clojure community bothers me.

5:06 when I first encountered Hickey on here, he was SUPER cool and very helpful

5:06 then you guys trundled in and now all I hear about is SIMPLE MADE EASY and DATOMIC

5:06 meanwhile, back in reality-land, parsing xml takes two separate days of labor to even get results back

5:06 tomoj: I don't find upsetting your refusal to consider anything besides your immediate convenience when making your language/technology decisions (if you can call that "engineering behavior")

5:06 callen: let alone finish the job.

5:07 you speak about immediate convenience as if this is something to be shown derision

5:07 the hell is wrong with you?

5:07 What do you think software and engineering are?

5:07 augustl: callen: I never said that easy is bad, I just said that I generally prefer long-time benefits over immediate ease of use

5:07 callen: It's about saving human time and creating leisure where there was none before.

5:07 it's about sacrificing silicon, and steel, and concrete for the sake of the human mind and soul.

5:07 and you scorn "easy"?

5:08 So toss your dishwasher out the window

5:08 tomoj: ah, I see, you're nuts or trolling :)

5:08 callen: forsake graphical user environments

5:08 tomoj: no, just burnt out and insanely angry with the ridiculousness of what it took to get XML parsing.

5:08 these are legitimate, serious *usability* issues that bear addressing and inspecting.

5:09 instead you scorn them as noobie problems.

5:09 augustl: callen: for what it's worth, I was able to parse xml after about an hour of effort

5:09 callen: totally naive.

5:09 tomoj: I don't have scorn

5:09 callen: augustl: thanks, fuck you. the whole channel pitching in couldn't do it in an hour

5:09 augustl: so you're smarter than their combined intellect.

5:09 augustl: I was here for a couple hours last night, four different people attempted and failed, then tonight (just now)

5:10 augustl: my xml was pretty small, perhaps that's what makes your case more difficult

5:10 callen: nice try, ego-man.

5:20 sunkencityryleh: I

5:26 Whoops. I'm trying to use a java library "[net.sourceforge/barbecue "1.0.6d"]" but no version of it is available in the default maven repos. How can I add extra repos? Would it be possible to add a jarfile to a lein project some other way? Or can I specify extra maven repos somehow?

5:26 tomoj: sunkencityryleh: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L161

5:26 sunkencityryleh: tomoj: thanks!

5:26 clgv: sunkencityryleh: if you do not find that jar in any repository, you can push it to clojars under your private group-id

5:28 sunkencityryleh: clgv: ok tnx!

5:30 augustl: is there a way to create an "else" or "catch all" for a multimethod?

5:32 clgv: augustl: there is dispatch for :default

5:32 augustl: so just (defmethod foo :default ...)?

5:32 clgv: yes.

5:33 augustl: thanks

5:46 tomoj: huh, never noticed nthnext

5:53 mpenet: is there a way to read a string as clojure data from clojurescript (at "runtime"), ex as a response to an ajax request?

6:03 Sgeo: What if I want a two-dimensional zipper?

6:04 mpenet: nevermind there is cljs.reader/read-string, I was induced in error trying to pass it a js Object and not its str representation

6:09 luxbock: wwww.clojuredocs.org looks like a great site for browsing the documentation for a newbie like me, lots of examples

6:09 thanks to whoever runs it

6:18 naeg: luxbock: but it does not feature the the newest version of clojure, 1.4

6:19 luxbock: oh

6:20 naeg: luxbock: you'll have to use this one then: http://clojure.github.com/clojure/ provides all you need, beside the examples :/

6:20 also, see here: https://groups.google.com/forum/?hl=en&fromgroups=#!topic/clojure/d-YF4jnECUQ

6:20 luxbock: examples are what I crave

6:21 clgv: luxbock: you can still use it. examples in 1.3 should work in 1.4 as well

6:21 naeg: luxbock: I'm mostly using the docs on github and whenever I'm not fully understanding something, I use clojuredocs to look at examples of 1.3 (some functions are not present though, like mapv)

6:24 luxbock: I asked about this eariler but couldn't find an answer yet

6:25 I'm using Emacs with nREPL with clojure-mode on

6:26 naeg: luxbock: it's not like i want to advertise it, but have you tried using the lighttable playground? As a newbie it was a lot easier for me to use than emacs. It shows data flow through your functions, etc.

6:26 luxbock: how do I run the clojure-mode buffer in the REPL? I tried C-c C-k but that gives me a load of errors

6:29 yeah I tried it but I prefer Emacs

6:31 casion: luxbock: m-x clojure-mode

6:33 Raynes: luxbock: Yeah, clojuredocs is still plenty relevant for 1.4.

6:33 casion: you can generate your own clojuredocs for 1.4 easily, I have it locally

6:33 Raynes: Nobody cares about mapv.

6:33 ;)

6:33 naeg: :o

6:33 I actually use it quite frequently :P

6:34 luxbock: casion, that just enables clojure-mode doesn't it? I'm trying to get the code I have typed up in the buffer to run in the REPL

6:34 casion: ohh

6:34 naeg: casion: how did you generate your own?

6:34 Raynes: luxbock: Information about those loads would be helpful.

6:34 luxbock: but I'm not sure if I'm using the wrong hotkey or if there's something wrong with my setup

6:35 casion: naeg: I just took https://github.com/jafingerhut/clojure-cheatsheets and ran it locally

6:35 that gives essentially the same info

6:35 minus the contrib-y stuff

6:36 luxbock: if c-c c-k is giving you errors, then you have a top level form that's fubar

6:37 luxbock: sorry, what does that mean?

6:37 casion: the code you're trying to load is bad in some way

6:38 read the error message to get a clue as to what is

6:38 jaedong playing this morning, woo!

6:38 shit, wrong window

6:40 luxbock: I tried running (println "Hello world!")

6:40 and I get the following:

6:40 http://pastebin.com/LNvrXn4y

6:41 casion: that's all you have in the file?

6:42 luxbock: yeah, I tried to make it as simple as possible to make sure the code is valid

6:42 casion: afaik, that error usually means a misplaced parens somewhere

6:42 does it work in the repl?

6:42 luxbock: yes

6:43 it's only when I try to run it from the core.clj file that things go wrong

6:43 casion: can you paste the core.clj

6:43 to refheap

6:43 (I get yelled at when I use pastebin)

6:43 mpan: is there a strategy to keep track of and verify the format of complex arguments to a function?

6:43 luxbock: it's just one line

6:44 mpan: few times now I've lost major time because I was passing my functions something structurally really wrong

6:45 luxbock: there's nothing else besides: (println "Hello world!")

6:46 must be something wrong with my Emacs configuration

6:49 casion: luxbock: seems to be an issue with your project

6:49 did you remove the (ns …) line?

6:50 luxbock: from the core.clj file? I never had one there

6:50 casion: how did you make the project?

6:50 luxbock: with leiningen

6:51 casion: uh.. hmm

6:51 lein new project-name ?

6:51 luxbock: yup

6:51 casion: that's odd

6:52 luxbock: do I need to declare (ns ) somewhere for it to work?

6:52 casion: try again, you should have something like https://www.refheap.com/paste/5135

6:53 ^ first try of rayne's refheap.el :D

6:53 luxbock: still run into the same problem

6:54 casion: is core.clj empty still?

6:55 luxbock: well it has the code that you gave me in it

6:56 casion: I have to go for an hour, I'll try and help more when I get back

6:56 I'm sure someone more competent can step in anyway :)

6:56 luxbock: thanks!

6:56 I'm cheering for Jaedong as well

6:56 casion: you watching code A atm?

6:56 luxbock: yeah

6:56 casion: hot damn

6:56 cousin just showed up to watch it with me ;)

6:56 those roro games were awesome

6:56 clgv: "code A"?

6:56 casion: anyway, I'll be back when it's done :)

6:57 luxbock: I just opened up the stream when you mentioned Jaedong, had forgot that he was playing today

6:57 casion: clgv: starcraft 2 tournament in korea

6:57 gomtv.net

6:57 clgv: ah ok

6:57 luxbock: alright thanks for trying. I think there's a chance it could be something really silly as I'm a complete newbie with both Emacs and Clojure

6:59 clgv: luxbock: does it work from "lein repl"?

6:59 luxbock: if I just type it in the repl rather than running the file?

7:00 clgv: luxbock: no. on commandline in your project, start up a repl via "lein repl" and then load the namespace and try toexecute the function

7:01 if that works you can be sure that it's the emacs setup, I think

7:02 luxbock: yeah that works

7:02 or actually

7:03 clgv: so you gotta find a tutorial to setup emacs properly or someone here that knows how to do that

7:03 luxbock: plaintest.core=> (foo "Blah")

7:03 CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in t

7:03 his context, compiling:(NO_SOURCE_PATH:1)

7:04 clgv: can you paste the complete file, e.g. on refheap.com?

7:04 luxbock: sure

7:04 clgv: with path and filename in the project please

7:06 luxbock: https://www.refheap.com/paste/5136

7:07 clgv: well your namespace does not fit to your path+file - similar to java in clojure namespace my.project.core has to be in file src/my/project/core.clj

7:08 luxbock: seems you need some clojure basics: tutorial or book - your choice ;)

7:08 luxbock: I tried changing it to (ns helloworld.core) but that didn't work either

7:08 yeah I'm going through a book at the moment, but I guess I haven't got to the right chapter yet

7:09 clgv: luxbock: jump ahead if there is a chapter on leiningen ^^

7:09 luxbock: alright

7:09 what should my (ns ) be saying?

7:10 clgv: what is your filepath? src/helloworld/core.clj?

7:10 luxbock: yeah

7:11 I'm going through Programming Clojure, doesn't appear he talks about Leiningen

7:11 clgv: "src/helloworld/core.clj" => (ns helloworld.core)

7:11 luxbock: edition 2?

7:11 luxbock: no, this is the first one

7:11 clgv: yeah. there is no leiningen chapter.

7:11 luxbock: makes sense, there's a chapter on namespace but I haven't got to that yet

7:12 clgv: but namspace name and file path correspondence is a plain clojure thing anyway

7:14 luxbock: alright, I'll get back to reading

7:14 thanks for the help

7:16 clgv: luxbock: be careful, there is a bunch of outdated stuff in the first edition of that book as well, e.g. #^String for type hinting a string, and some more

7:17 luxbock: but for learning the basics it serves well, I think

7:18 luxbock: ok

7:23 aib: how is :dependencies in defproject in lein resolved? I see an element like [org.clojure/clojure "1.4.0"] - how does this tell lein what to download?

7:25 clgv: aib: it's using that info to search the given repositories (without configuration maven.org and clojars.org)

7:26 aib: I see. thanks

7:26 clgv: the format means [groupid/artifactid version]

7:27 aib: bah, now I'm more confused because there are 3 "lwjgl"s in clojars... and that's just the groupid, I think

7:28 clgv: aib: what does the libs website tell you as official groupid?

7:29 aib: nothing :/

7:30 arkx: aib: http://www.lwjgl.org/wiki/index.php?title=LWJGL_use_in_Maven

7:30 clgv: aib: I'd take that one: http://search.maven.org/#artifactdetails|org.lwjgl.lwjgl|lwjgl|2.8.4|jar

7:30 aib: ah, maven. I'd searched for "Clojure"

7:30 clgv: [org.lwjgl.lwjgl/lwjgl "2.8.4"]

7:40 mindbender1: A crazy thought came to me that all functions are object-oriented

7:40 naeg: in what sense?

7:41 mindbender1: they woek on particular kinds of objects

7:41 *work

7:41 naeg: e.g. a number is not (necessarily) an object

7:42 at least not an object in the sense of OOP

7:42 mindbender1: then what is a number

7:42 naeg: a primitive value

7:42 mindbender1: *value*

7:43 an object is a *value* too

7:43 naeg: but not a primitive one

7:43 mindbender1: to me a value is an object

7:43 naeg: I think there are programming languages out there which treat numbers as objects

7:43 not in the sense of OOP

7:44 yeah, Ruby is one of them

7:44 mindbender1: a number has a type

7:44 so it is an object

7:46 you can take a function that's meant for a specific type number and apply it to another

7:46 *can't

7:46 naeg: an object is in OOP refers to an instance of a class. hence, when integers are not class (unlike in e.g. ruby), a simple number is no object

7:47 hughfdjackson: i'm not sure that i buy that

7:47 instance of a class, i mean

7:47 mindbender1: hughfdjackson: which one

7:47 ok

7:47 cos I don't too

7:47 hughfdjackson: i know people argue about OOP and its definition all the time, but .. take JS for instance

7:47 naeg: yeah, there it's about prototyping

7:47 mindbender1: prototyping is just an implementation detail

7:47 hughfdjackson: :p i always lose a lot of my day when i try to find a satisfactory definition

7:48 mindbender1: just like mixin is

7:48 hughfdjackson: mindbender1: well, when the prototypal inheritance is object-to-object, then you lose classes :p so you can't define OOP by classes

7:48 naeg: but I guess the "historical OOP" invented by alan kay, is about classes (I'm not sure though)

7:48 mindbender1: hughfdjackson: I don't

7:48 hughfdjackson: maybe :) i think the unifying part of OO is sharing data and behaviour in the same namespace

7:49 and that that gets passed around as the main unit of information *and* manipulation

7:49 mindbender1: my point is programming is mostly about thhe same thing

7:49 hughfdjackson: packaged together

7:49 naeg: what primitive values like numbers, do not in clojure and most other languages

7:49 hughfdjackson: mindbender1: you're right, there's lots of parallels

7:49 and trying to unpick the *real* differences is really fun and informative n.n

7:50 mindbender1: even when I read heavily jargonized text I keep focus on the object

7:50 naeg: http://c2.com/cgi/wiki?AlanKaysDefinitionOfObjectOriented => "Every object is an instance of a class (which must be an object)."

7:51 mindbender1: I certainly don't have to agree with whatever that link has to say

7:51 hughfdjackson: naeg: :D well, that's very interesting

7:51 mindbender1: because time and again experts have been proven to be wrong

7:51 naeg: that's just the "historical OOP" I was talking about before

7:51 hughfdjackson: mindbender1: i'm not sure you can prove someone wrong on this ground

7:52 mindbender1: I'm not trying to

7:52 hughfdjackson: i mean.. you can assign a term to anything you like; if that's what he wants to assign it to..

7:52 naeg: alan kay was the person who "invented" oop. but it changed A LOT since then. alan even said that what most "oop languages" are today is not what he actually meant

7:52 hughfdjackson: :D however, i'd contend it's no longer the most useful definition, given the plethora of similar languages that take a different approach to create their objects

7:52 mindbender1: I'm just saying that functions are object oriented

7:52 hughfdjackson: given my personal definition of that, i don't think i can agree

7:52 mindbender1: because they still have to deal with instances

7:52 naeg: mindbender1: then what does object oriented mean in this context? it's not about OOP then

7:53 mindbender1: naeg: ^^

7:53 hughfdjackson: because functions live in a seperate namespace to the data that's passed around to manipulate

7:53 mindbender1: even according to your definition

7:53 hughfdjackson: :p although clojure may do some things differently in this regard at its roots

7:54 naeg: hughfdjackson's definition before seems to fit most OOP languages today (but is not what alan kay intended)

7:55 hughfdjackson: i'd happily rename my definition to 'objecty' if there's objection ;)

7:55 it seems to be the most important difference between functional and OOP to me

7:55 could well be wrong!

7:56 can't hang about to find out though, i've got a job to go to

7:56 :) ciao

7:56 naeg: cu

7:56 mindbender1: I think the idea of functional programming was one of reducing complexity

7:57 in that the number of types are drastically reduced

7:57 because we mostly have associative types

7:57 andd a few others

7:57 xak466: hi, im writing some code that validates input from a form, and saves it to the database if the input is valid. at the moment, i am doing it like this

7:57 (if (validate-title params) (if (validate-url params) (save-to-database params) (validate-url params)) (validate-title params))

7:57 naeg: I'm not sure whether you are right here, quite new to clojure/FP

7:58 mindbender1: xak466: try it at a repl

7:59 clgv: xak466: you dont like that layout?

7:59 xak466: (if (validate-title params) (validate-title params) (if (validate-url params) (validate-url params) (save-to-database params)))

7:59 sorry, mistype

7:59 so the validate-* functions return nil if it passes

7:59 clgv: xak466: what is the question/problem?

7:59 xak466: and returns {:error "bad url"} if it fails

7:59 my question is, is there a nicer way to do it

8:00 rather than nesting (if's

8:00 clgv: xak466: you could do (keep #(% params) [validate-title, validate-url ...])

8:01 casion: luxbock: :(

8:01 aib: do I need to do something extra to get :native-dependencies working in command line lein or CCW?

8:02 xak466: clgv: thanks. just reading up on (keep

8:03 clgv: will (keep evaluate the whole list or stop once the first non-nil value is returned?

8:03 clgv: aib: there was something with a special format for native jars. you have to consult the leiningen docs.

8:04 casion: luxbock: any luck in the interim?

8:04 clgv: xak466: keep = (remove nil? (map ...))

8:05 aib: clgv: they're hard to consult. though I just remembered there's #leiningen and I don't need to bother people here

8:05 clgv: right ^^

8:05 aib: sorry, this is all very new for me

8:09 xak466: clgv: i think i found what i was looking for. (first (drop-while #(= nil (% params)) [validate-title validate-url save-to-database]))

8:09 clgv: xak466: ah. I would have separated the save-to-database from the validity checks

8:10 xak466: that way you can report all errors and communicate semantics

8:11 xak466: clgv: ahh.. i see what you're getting at

8:11 clgv: in that case, the keep would be more sensible

8:12 clgv: as you can see, i was trying to abort at the first error encountered

8:12 clgv: but i think your solution is better

8:13 clgv: xak466: "report all" or "report first" depends on your use case. but I would not mix save-to-database in there

8:14 xak466: clgv: yup that too

8:16 dhofstet: is it good coding style to use many forward declarations?

8:17 clgv: dhofstet: I doubt that. as far as I have seen you only use them when they are really needed

8:19 dhofstet: clgv: thanks, seems I'm still too used to read source files from top to bottom ;-)

8:53 aib: how do I call a function in another file? (ns project.core) (defn foo "foo" [x] (+ x 1)) - (ns other.file) (project.core.foo 5) ?

8:54 ro_st: you need to require it in your ns decl

8:54 aib: (:require project.core) ?

8:55 gfredericks: (ns other.file (:require [project.core :as core])) (core/foo 5)

8:55 ro_st: (ns other.file (:require [project.core :as core]) (core/foo 5)

8:55 +)

8:55 :)

8:55 aib: also, clojurebook.com or http://java.ociweb.com/mark/clojure/article.html

8:56 mpenet: ibdknox: ping

8:56 ro_st: this is a language that rewards experimentation, but you do need to do your homework too

8:59 Hodapp: I find it rather interesting how in Lisp-ish languages, a lot of the standard practice is that one will generate and pass around functions as readily and as easily one might do something like a branch or a variable initialization in another language

8:59 chouser: That's the original meaning of "functional programming"

9:00 Hodapp: Is it? I thought it varied a bit from that

9:00 casion: that's pretty much the only thing people seem to agree on in the varying definitions of 'functional programming'

9:01 madsy: Hodapp: In Lisp dialects like Scheme, lambda functions are used to build more high level constructs. It's one of the main building blocks

9:02 Hodapp: Well, it does also seem to also apply to languages like Ocaml and Scala that are very non-Lispy, but are functional

9:02 madsy: I've not worked with Scheme much but I did get this idea, and likewise for Scala which I've worked with a bit

9:03 madsy: Hodapp: SICP is a great book if you want som aha-moments.

9:03 Hodapp: like it's not a "feature" or even a design pattern, it's just how you do things

9:03 madsy: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-4.html#%_toc_start

9:03 chouser: "Functional programming" has come to imply more than that, such as pure functions, immutable collections, and even pattern matching. But at the very least you have to be able to create and pass around functions.

9:03 Hodapp: I do need to get through SICP. I'd like to get some folks to watch the Sussman lectures on it.

9:04 aib: ro_st: sorry, it's just hard to sift through all these tutorials looking for Clojure-only stuff

9:04 Hodapp: The Android APIs do make ready use of anonymous functions and closures, but only to the extent that clunky Java allows it

9:04 so it ends up as an approximation with interfaces that are instantiated on-the-fly as inner classes

9:05 ro_st: aib: no need for apology. i'm just trying to give you the best path to happy clojurin'

9:05 Hodapp: chouser: I do have to say, Scala's pattern matching is kind of magical.

9:06 chouser: I don't know anything about writing parsers, but once I read a little bit about BNF and looked at Scala's parser combinators, I found it amazingly simple to put together a fairly complex parser with it.

9:06 chouser: pattern matching can be quite nice. It seems odd to call it "functional programming", but whatever. Clojure has core.match which works quite nicely.

9:07 Hodapp: I'll have to check that out.

9:09 I just find it interesting, after working too much at a jorb where imperative object-oriented programming is the norm, to see how many of those structures just collapse and go away when I employ something like Clojure, even not knowing it too well.

9:10 chouser: functional languages love parsers -- clean data in and out, pure functions operating on it, trees that beg recursion...

9:10 Hodapp: chouser: indeed.

9:11 chouser: At some point I came to the realization that I'd basically replaced an existing C++ parser, 5K-6K lines long, with about 100 lines of Scala.

9:11 casion: Hodapp: the tradeoff is that if you're not careful you can end up with incredibly 'powerful' functions that take you hours to reinterpret when you go to look at the code later

9:12 somewhat analgous to ending up with 20 generations of inheritance in a large c++ project

9:13 Hodapp: hmm, yeah

9:13 casion: I've already ended up confusing myself with the clever 3 liners that do an equivalent of 40 lines of java code which are so tempting to write

9:13 Hodapp: I've tried to keep things pretty clear

9:14 casion: perhaps I'm more disposed to that from writing low-level C stuff usually

9:14 where I usually can interpret my cleverness later ;)

9:14 Hodapp: hah, yeah

9:14 I still write plenty of low-level C

9:14 probably more once my TI Stellaris Launchpad boards arrive

9:15 casion: I'm waiting for my next project to try the stellaris boards

9:15 I'm still waiting for a turkey arm board that I can use

9:15 rolling your own is such a massive pain

9:16 Hodapp: I used a Procyon for awhile from Teho Labs

9:16 ejackson: where does nrepl in emacs send exception/assertion messages ?

9:16 Hodapp: just uses StellarisWare & CodeSourcery

9:16 the Raspberry Pi also is quite nice, though you can't really treat it the same as a lot of ARM boards

9:17 casion: I got a PI and I hate it

9:17 the documentation is worse than awful

9:17 it's one thing to have lacking documentation, but half the pi docs are just wrong

9:18 Hodapp: I've rather liked mine for what I'm doing; it replaced that Stellaris board, a JTAG controller, an FTDI Basic, and a separate PC for talking to the Stellaris board

9:18 mwcampbell: Apologies for posting the same thing twice on the Google Group. I didn't mean to be obnoxious; I thought my first post had been silently ignored.

9:18 Hodapp: but that's a fairly narrow area

9:19 casion: I don't know enough about linux to figure out the pi on my own

9:19 I just want docs with correct info

9:19 not a bunch of "It worked like this in the alpha… but it doesn't do that anymore, so ignore all this info, kthxkai"

9:20 Hodapp: this is part of what annoys me about things like this

9:20 so much of what goes on is documented in spotty message boards, not websites or even Wikis

9:20 casion: well AVR is documented super well, mostly because of arduino

9:21 Hodapp: I had the same complaint about some Android custom ROMs

9:21 casion: and if you're going to design your own board and write your own firmware, arm is great...

9:21 but once you have and OS forced on you, everything seems to goto shit

9:22 Hodapp: hmmmm

9:22 and all the alternative OSes - RISC OS, WebOS, possibly Android and FirefoxOS - are all quite alpha right now

9:24 casion: meh, I just use my own

9:24 Hodapp: for my Procyon board I didn't have any OS; for the RPi project I did, I benefitted from having Linux there and just hacking on the low-level parts I needed

9:25 casion: it's nearly invariably easier for me to just write my own firmware and a basic OS than spend time learning something that has 500 features I don't need, and doesn't implement what I do need

9:26 Hodapp: but Linux did get in my way. On the Procyon I could time down into 20-30 ns with no trouble; on the RPi trying to delay reliably resulted in a minimum of about 130 usec

9:27 casion: that is terrible

9:27 Hodapp: luckily it was just SPI that I needed (had to bit-bang it, spidev didn't do what I needed because my device wasn't speaking proper SPI but something SPI-like) so I didn't need reliable clocking

9:27 just had to be able to drive my data line and my clock line in sequence

9:28 casion: couldn't you write your own interrupt delay on the pi?

9:28 or is that somehow not possible

9:28 Hodapp: I was trying to do this mainly in userspace

9:29 uvtc: Made some updates to the colorized irc logs at http://www.unexpected-vortices.com/clojure/irc-logs/index.html . Now repeated messages by the same user don't show the nick over and over. Also other style improvements. Note though, it only gets updated when I need to read logs. :)

9:29 casion: you should easily be able to get 2-3ns delay with that chip

9:29 130usec is just… D:

9:30 yeah, 3ns, 2 clocks minimum

9:30 chouser: uvtc: nice. You're aware of the logs I maintain?

9:31 uvtc: chouser: At http://clojure-log.n01se.net/ ? Yes.

9:31 chouser: ok, just checking. Yours look good.

9:31 ro_st: (assoc chouser :irc-logs (css uvtc))

9:31 uvtc: chouser: Actually, looking at those made me realize I was repeating the same username over and over for messages by the same nick.

9:32 ro_st: looks great! very readable

9:32 uvtc: Cool, thanks, ro_st.

9:33 ro_st: no disrespect to chouser, of course :-)

9:34 uvtc: chouser's are no doubt more up to date. Mine currently aren't being updated automatically --- only when I go to read irc logs. :)

9:35 ro_st: then he does have a distinct advantage, yes

9:36 babilen: uvtc: You should at least indicate which timezone you use or use a standard one such as UTC (which would make the most sense IMHO)

9:37 uvtc: babilen: I'm grabbing the logs from http://www.raynes.me/logs/irc.freenode.net/clojure/ . He seems to be 2 hours ahead of me...

9:38 Wait, no, behind.

9:38 babilen: uvtc: (That is exactly what I mean -- There are also people from other places than (location Raynes) in this channel, so :)

9:38 )

9:39 uvtc: Ok, lessee, what timezone is that...

9:40 Hodapp: casion: you could readily get delays of that sort if you don't have normal Linux in the way

9:40 babilen: uvtc: I still think that the best way to deal with this would be to normalise timestamps to UTC, but meh ...

9:40 casion: exactly ;)

9:40 Hodapp: casion: some folks recommend Linux with realtime patches, but meh

9:43 uvtc: babilen: oh, yuck. Me no like daylight savings time...

9:46 babilen: uvtc: UTC is always UTC

9:56 fckw: Hi there.

9:57 I am currently learning Clojure and got a simple question.

9:57 casion: and then...

9:57 chouser: fckw: go for it

9:59 fckw: I have a very simple, single-threaded program including a variable "book" which is supposed to hold a seq of books.

9:59 (def books ())

9:59 I have a function "create-book" taking title, author etc. and returns a new book (basically a struct-map).

10:00 Then I simply want to store the new book in books. I used the cons function.

10:00 But after having it called, books is still empty.

10:00 cshell: what are you cons'ing it to?

10:00 chouser: cons returns a new list

10:01 fckw: Oh, dear. Maybe that's the problem.

10:01 chouser: if you want to store that new list back in books, you have to explicitly ask for that

10:01 clgv: fckw: you have to use an atom for books if you really want to store them in that global variable

10:01 casion: cons returns a new seq, it doesn't mutate it

10:01 madsy: fckw: Remember, data in Clojure is immutable. Either return the new copy, or use an atom or similar.

10:01 fckw: So, if I don't want to use an atom or a ref, how would I do it?

10:01 chouser: fckw: yes, an atom or altering the var will work, but you are right to explore another path.

10:02 fckw: What exactly do you mean by "altering the var"?

10:02 chouser: it is easy when learning clojure to fall back on mutable refs instead of doing the hard work of thinking how to do things immutably

10:02 madsy: fckw: You need to use a ref or atom *somewhere* if you want to alter states. Or else all you have is "let", which is constant once set.

10:03 chouser: fckw: I mean using the alter-var-root function. But if you want to *learn*, don't do that (at least not yet)

10:03 madsy: fckw: The tricky part is to figure out what the minimum amount of mutability you need is.

10:03 fckw: At the moment it's all single threaded.

10:03 madsy: fckw: (almost) Always make functions pure if you can.

10:03 fckw: So really no need for atoms and refs.

10:03 chouser: fckw: instead of having the goal of changing "book", think about what you want to do with that new list you created with cons, and just do that next step.

10:03 casion: fckw: that's not why they're suggesting it

10:04 fckw: Well, what I want to do in the future is writing the new books to a database.

10:04 But until this is set up, I'd like to keep them in some sort of global var.

10:05 Where I also can delete them again.

10:05 chouser: hm. mutable state.

10:05 casion: are there steps in between adding the books that disallow you from holding on to the books seq?

10:05 cshell: fckw: I think if you follow chouser's advice and try to work with it in an immutable way, you'll learn much mroe

10:06 fckw: rather than do it the java way

10:06 fckw: ;) @cshell: That's what I'm trying to figure out.

10:06 I'm just a little confused at the moment.

10:06 casion: fckw: you could post your code

10:06 fckw: Ok, wait a sec.

10:06 > (def books ())

10:06 madsy: fckw: Remember, you can use "let" as much as you want

10:07 fckw: (defstruct book

10:07 chouser: fckw: embrace that feeling of confusion. The transition from imperative to functional programming causes confusion for a while, so if you're feeling that, you're on the right path. :-)

10:07 fckw: > (defn create-book

10:07 > (defn save-book [coll book]

10:07 cshell: fckw: try pastebin or refheap :)

10:07 casion: use refheap :)

10:08 ejackson: i'm attempting to change the function called for the #inst reader macro

10:08 fckw: @chouser: I've done some Haskell years ago.

10:08 ejackson: but I'm hitting brick walls to left and right

10:08 chouser: fckw: oh, well then you'll be fine! Clojure's much easier.

10:08 fckw: I love Clojure just right now, it's so much cooler than Java and Haskell.

10:08 But I still am confused right now.

10:09 fogus: ejackson: Did you trying to rebind the *data-readers* map with binding?

10:09 ejackson: I've tried dynamically rebinding *data-readers*, data_readers.clj etc. I can get the reader working in the repl, but when I make a call to sql, what is passed back up to me seems to use the default

10:09 fogus: :-)

10:10 ejackson: hehe, yeah, and in the repl its fine

10:10 a la: (binding [*data-readers* {'inst #'clj-time.coerce/to-date-time}] (read-string "#inst \"2012-01-01\""))

10:11 but if I wrap the binding around a function that goes off and gets data from the db, I get back #inst " ..... "

10:11 Bahman: Hi all!

10:11 fogus: ejackson: what is the type that you're returning?

10:12 fckw: @madsy: let is only valid during method call, no?

10:12 But I would like to change "books" (like a closure).

10:13 ejackson: fogus: what I'm getting back is map, one of the keys of which reports a type of java.sql.Timestamp and is printed like #inst "2012-01-02T13:54:08.000000000-00:00"

10:13 Bahman: I have several modules which deal with database queries and such. I want to seamlessly and without changing the existing code, add exception handling and logging to the functions. Is it possible?

10:13 Perhaps redefining defn?

10:13 ejackson: so I think whatever came back from SQL just went through the default reader

10:14 fogus: ejackson: Clojure provides a default print-method for j.sql.TimeStamp that prints #inst "..."

10:14 fckw: chouser: If cons creates a new list, then I obviously can reassign it to the existing books variable.

10:14 And overwrite it.

10:14 fogus: ejackson: https://github.com/clojure/clojure/blob/master/src/clj/clojure/instant.clj#L227

10:15 clgv: fckw: that's "redefining" then ;)

10:15 chouser: fckw: you can, but that's an imperative style.

10:15 fckw: chouser: So what'd be better instead?

10:16 chouser: fckw: pass that new list to a function that does whatever needs to be done next.

10:16 fckw: chouser: I understand. But how do I then write for instance a test case which requires a state?

10:16 fogus: ejackson: You could also bind the inst reader to clojure.instant/read-instant-timestamp

10:16 ejackson: fogus: Yes. But what is it a Timestamp ? I'm expecting it to be a joda Datetime.

10:17 sorry, "why is it a Timestamp"

10:17 fckw: chouser: Do I really HAVE to fall back on refs and atoms, although the test case would be single threaded?

10:17 chouser: fckw: why would a test case require state?

10:17 fckw: but in short, yes.

10:18 fckw: Clojure doesn't provide much by way of thread-unsafe mutation

10:18 ejackson: fogus: i thought (binding [*data-readers* {'inst #'clj-time.coerce/to-date-time}] ....) would do that for me

10:18 fogus: ejackson: The default Clojure inst reader would return a j.u.Date, so maybe something else is happening

10:18 ejackson: fogus: aaaaah.

10:18 chouser: fckw: but using an atom isn't hard, you're just finding this channel reluctant to give you answers in that direction, thinking we're doing this for your own good. :-)

10:19 ejackson: fogus: nice catch, thank you. The function goes through CQL, so perhaps its playing silly games inside there.

10:19 fogus: Could be

10:19 ejackson: thanks for that.

10:19 fogus: np. Let me know what you find

10:20 fckw: chouser: I just think there is some important insight that I haven't got yet.

10:20 chouser: So either passing the var books along the function arguments, or make it a ref/atom then?

10:21 chouser: yes, almost: either pass the *value* books along as a function argument, or make it a ref/atom.

10:21 fckw: chouser: It cannot be done in a "closure" style, like changing a global somewhere in my functions (as for instance in JavaScript)?

10:22 casion: fogus, chouser: since you're both here, tjoc has been a huge help to me more so than any other source. part 3 has been a massive breakthrough for me. Thanks for writing it :)

10:22 chouser: fckw: yes, you can use a closure, but the things you close over are still immutable so no "changing"

10:23 fckw: keep asking yourself why you want to change a thing, and try to do something else instead.

10:23 fckw: chouser: Thanks. I'll try some stuff. Maybe come back to it.

10:23 chouser: fckw: if your project really is centered around a classic database, this kind of thinking will probably more difficult.

10:25 fckw: if you're using a var to simulate a mutable database until such time as you put a real database there, that may be reasonable. In which case you just need (def book (atom ())) (swap! book cons :new-book)

10:25 fckw: chouser: That's exactly my purpose here. All other vars are local only inside functions.

10:26 chouser: I'll try it with ref/atom then.

10:27 chouser: fckw: but if you're trying to learn the Clojure way of doing things, you might find the problems on 4clojure.com to be more helpful. A CRUD db app is almost inherently imperative.

10:27 casion: thanks, that's very kind.

10:28 fckw: chouser: In the end I want to write a Web-App. I want to use Clojure less because of the FP capabilities, but more because of the DSLs.

10:28 chouser: And I am aware that using a DB inherently means having state and thus losing the full strength of FP.

10:29 chouser: fckw: come for the macros, stay for the immutability. You wouldn't be the first. :-)

10:29 fckw: chouser: But also using map and reduce are great things I really miss in Java.

10:30 chouser: I also looked into Scala a bit, but was not really satisfied. It just did not feel as clean as Clojure.

10:30 fogus: casion: Thanks!

10:30 chouser: fckw: consider datomic to extend the FP further into the database.

10:31 ejackson: fogus: Its confirmed - I'm a pinhead. The value never goes through the reader as a string, so reader literals just don't apply. Of course, if I were to spin the map through some a (comp read-string pr-srt) I could force the issue in a silly way :D

10:31 fckw: chouser: Thanks for the hint. I'll have a look into datomic. My original goal is to follow this approach: http://www.hackers-with-attitude.com/search/label/programming

10:32 chouser: See the presentations on that page. They use Google Closure, FP-style Javascript on the client and Clojure DSLs on the Server. All data handled is JSON. No XML or the like.

10:33 chouser: And as a DB they use Google Key-Value-Stores.

10:33 chouser: Nice design, I think.

10:36 chouser: interesting.

10:39 fckw: Ok, I'll be gone for some time. Maybe be back later. Thanks, guys.

10:44 rabbler: So, I've tried to figure it out, but I just can't seem to find any docs on how to connect a Lein REPL to a nRepl server. I have the server up and waiting, but what do I need to do something like "lein nrepl localhost:8888". Are there any URLs you can point me to? Is it possible to do this?

10:46 andrewmcveigh: rabbler: lein repl :connect hostname:8888

10:47 rabbler: I've tried that and I just realized that I have 1.7 of lien.

10:47 lein.

10:47 hah!

10:48 andrewmcveigh: rabbler: Ah, I can't say I've tried it on < lein 2.

10:49 rabbler: I think it only works on 2, as per the nrepl statement. hah.

11:14 Frozenlock: What would be the best 'functional' way to simulate a system? Is there some example available?

11:17 bsbutler: Frozenlock: I assume by system you mean a physical system?

11:17 Frozenlock: Yeah sorry for my lack of precision. Let's say I'm trying to represent a simple spring (F= -kx)

11:19 Or a ball falling in a vacuum. Surely there's some example of that?

11:20 bsbutler: Frozenlock: https://github.com/giorgidze/Hydra perhaps?

11:20 I would think some mixture of Dataflow and Constraint/Logic programming but I'm far from my expertise re: simulation

11:21 Frozenlock: It's not in clojure :-/

11:22 But I'll take a look anyway, thanks.

11:23 pandeiro: i would like to build a webapp that is a collection of a few small independent http services; my concern is having to use a JVM instance for each of these. is there any way around this?

11:24 clgv: pandeiro: huh, why would you? if you implement these services as libs you should be able to set them up in a single jvm

11:25 pandeiro: clgv: i guess i am not seeing how to organize the project and deploy it very clearly

11:26 Hodapp: clgv: indeed, is this not the basis of servlets and the like?

11:26 pandeiro: i guess i need to finally learn what servlets are

11:26 so far i have been using jetty with everything i do

11:27 and it is one webapp : one jetty instance

11:27 but the current thing i am working on has several parts that i thought could be broken into their own services, rather than one monolithic webapp

11:27 clgv: pandeiro: organization depends if you want to explicitly wire those services in the main programm or if you want to have some plugin like behavior with implicit automatic setup

11:28 joegallo_: long story short: a servlet is a function that takes an http request and http response and uses data in the one to bang on the other. but, of course, since it's java there can't just be a function, so it's an interface and an abstract super class and all that jazz.

11:29 pandeiro: joegallo_: i like jazz but not that kind of jazz

11:29 Hodapp: joegallo_: It can't be a single function; it has several points of entry.

11:29 clgv: pandeiro: I do not think that you have to learn servlets for that

11:29 joegallo_: sure sure, there's an init and a destroy and all that, but in the end it boils down to doService.

11:29 pandeiro: what i really want is for each component of the app to be its own mini compojure app

11:29 joegallo_: iirc

11:30 pandeiro: i have even thought about going with node instead for these components b/c i feel like the node processes would be very cheap compared to jvm+jetty instances

11:30 clgv: pandeiro: well then you probably should go for a plugin like approach. this way you get reusable "main program" that loads the plugins and sets up the routes

11:30 Hodapp: pandeiro: you should only need one JVM though

11:30 weavejester: pandeiro: What do you mean? A normal Compojure app is effectively a collection of smaller apps...

11:31 pandeiro: weavejester: Hodapp: clgv: right i think i am just confusing myself here

11:31 i can manage each 'service' as a diff project

11:31 and then have one app project using them as libs

11:31 clgv: yep

11:32 weavejester: Yes, or put them in the same project under different namespaces, depending on how different they are.

11:32 pandeiro: sure ok

11:32 but then the tradeoff is saving resources but creating a single point of failure

11:32 i meant to phrase that as a question but failed

11:32 clgv: any link to a description how to do ssl communication between two processes painlessly in java or clojure (even better)???

11:32 lazybot: clgv: Oh, absolutely.

11:33 weavejester: Well… how you divide an application up depends on the application.

11:33 Hodapp: clgv: In Java it should Just Work(tm)

11:33 if your certs check out okay

11:33 weavejester: But so long as each part is separated, it's easy to turn a single app into several.

11:33 clgv: Hodapp: how? what classes to use?

11:33 pandeiro: weavejester: right. it is hard when you lack the experience you would need to make that decision well. :)

11:34 weavejester: meaning break it out into multiple jvm instances if need be?

11:34 weavejester: pandeiro: How else would you remove a single point of failure?

11:35 pandeiro: weavejester: sure, i get it

11:35 weavejester: pandeiro: The more you divide up your application the more robust it becomes. Start with namespaces, then projects, then processes, then machines, then regions.

11:36 Hodapp: weavejester: That's not automatically true, and frequently it's blatantly false.

11:36 pandeiro: weavejester: great, thanks. by namespaces, you been top-level?

11:36 weavejester: e.g. a really robust app would be distributed across several processes on several machines in several different data centers (i.e. regions to use the AWS terminology)

11:37 pandeiro: s/been/mean

11:37 weavejester: Hodapp: Obviously you can have a distributed app that is still fragile

11:37 Hodapp: But you can't have a robust app that isn't distributed.

11:38 Hodapp: weavejester: This doesn't mean that dividing it up automatically makes it more robust.

11:38 pandeiro: otoh, can a smallish linode instance handle several jvm instances?

11:38 Hodapp: pandeiro: I'd say yes.

11:39 weavejester: Hodapp: No, but it's something you need to do if you want a robust process. Depending on how "robust" you need it to be.

11:39 Hodapp: My guess is that most apps could make do with a couple of servers behind a load balancer.

11:39 Hodapp: Maybe less.

11:40 clgv: Hodapp: so where to start for learning how ssl communication in java is done?

11:40 weavejester: pandeiro: By namespaces, I just mean that the different parts of the app should be loosely linked. The most connections between them, the harder it will be to separate them out later on.

11:41 Hodapp: weavejester: Loose coupling also can enforce overabstraction and necessitate communications channels, which is not automatically a good thing.

11:41 weavejester: Hodapp: In what way?

11:42 Hodapp: weavejester: Every layer of abstraction is another point of failure. Every layer is another possible hindrance to understanding of the whole.

11:43 jro_: (reduce or [nil "a"]) Can't take value of a macro: #'clojure.core/or: are there other ways to solve this than (reduce #(or %1 %2) ...)

11:43 Hodapp: weavejester: N.B. Alan Perlis's epigram #20: "Wherever there is modularity there is the potential for misunderstanding: Hiding information implies a need to check communication."

11:44 jkkramer: jro_: (some identity [nil "a"])

11:45 weavejester: Hodapp: I'm not really talking about layers of abstraction here, any more than functions could be considered layers.

11:45 cshell_: Is there something similar to extend-protocol for extending a Java Interface?

11:45 weavejester: Hodapp: It's more a horizontal separation; each web service stands alone as a useful tool.

11:46 jkkramer: weavejester: hey, I'm having trouble getting codox to include defmultis. do you know off-hand whether it's known to (not?) work with them?

11:46 ejackson: cshell: i think it will work on interfaces actually

11:46 jkkramer: weavejester: they definitely have :doc metadata, and show up in ns-publics called from the repl

11:46 cshell_: ejackson: that's what I was thinking but I'm getting an error that it's not a protocol

11:46 weavejester: jkkramer: I can't recall offhand. I know it needs some work done on protocols and methods. I haven't had the time to sort it out.

11:46 ejackson: cshell_ must be wrong then :)

11:47 cshell_: ejackson: thanks though :)

11:47 jkkramer: weavejester: k thanks. I'll send a pull request if I figure it out

11:48 jro_: jkkramer, thanks. But, can I pass a macro as a function somehow, without writing an anonymous function?

11:48 ejackson: cshell_: if i read http://clojure.org/protocols right then you can use extend to extend an interface to a protocol

11:48 jkkramer: jro_: nope

11:49 ejackson: cshell: right at the bottom

11:49 jkkramer: jro_: macros operate at compile time. trying to pass them around at runtime doesn't make sense

11:50 Hodapp: weavejester: Fair enough. I just take issues with principles that result in horrible horrible horrible lasagna code when applied dogmatically in OOP, but this does look a bit different.

11:50 cshell_: ejackson: I believe that means that I can extend a protocol to a java interface

11:51 weavejester: Hodapp: Definitely :) - web services should be split up (if possible) in a way that minimizes connections, not create more of them

11:51 cshell_: ejackson: I'm trying to pass a Java interface in to the first argument to extend-protocol

11:51 weavejester: Hodapp: Ideally you should be able to split out a web service without creating any more connections. Just change a local call for a remote one.

11:52 Hodapp: More difficult than it sounds, of course

11:52 Hodapp: weavejester: Ideally, but at least two research papers have demonstrated why this only goes so far.

11:53 ejackson: cshell: i'm not sure how that would work, but I'm java-ignorant :)

11:53 weavejester: Hodapp: How so?

11:53 Hodapp: weavejester: One, I think from Sun Microsystems, talked about how the notion resurfaces every decade or so that if you just define some kind of interface, you can just do RPC and it all will magically work remotely just as well as locally.

11:54 weavejester: Hodapp: Right, but I think in Clojure we have an advantage over other languages in that regard. Most languages maintain the fiction that accessing data is instantaneous, but Clojure has the idea of derefing

11:55 cshell_: ejackson: I'm not sure either :)

11:55 weavejester: Hodapp: When you deref something in Clojure, the implication is that it's only correct for a particular instance in time.

11:55 Hodapp: Same principle applies to remote calls - a HTTP GET is effectively a deref with higher latency.

12:02 Hodapp: weavejester: Two papers to check out that discuss this:

12:02 http://hodapple.com/files/papers/Critique%20of%20RPC%20Paradigm%20-%20AST.pdf from Andy Tanenbaum of Linux-sucks fame

12:02 http://hodapple.com/files/papers/Note%20on%20Distributed%20Computing%20-%20Waldo_%20Wyant_%20Wollrath.pdf from Sun

12:03 weavejester: Hodapp: Those look like they're criticizing the RPC model (at least the first one does by the first few paragraphs), but I'm talking about about something a little different

12:06 nkoza: there also an RPC critique from Steve Vinoski, of CORBA fame

12:06 Hodapp: nkoza: haven't read that one

12:07 These papers, though, apply to a great many cases where it's not called RPC or seen as such

12:07 nkoza: Hodapp: for example, http://www.infoq.com/presentations/vinoski-rpc-convenient-but-flawed

12:08 weavejester: Hodapp: It seems to me as if there's a fundemental difference between the RPC-based approach and a resource-based approach.

12:09 RPC is about remotely calling a function

12:09 Resources are about getting the past value of a remote identity.

12:11 Hodapp: weavejester: Why I sent these was what you said with "Just change a local call for a remote one." and I spoke of papers that said this approach only goes so far.

12:11 weavejester: Hodapp: I mispoke. Or didn't explain myself very well.

12:12 Hodapp: nkoza: Have you watched it? Should I?

12:12 jro_: Why primitive operations like or and and are macros instead of functions?

12:13 nkoza: Hodapp: I have read some documents from Steve Vinoski but that was the first link I found, google for "steve vinoski rpc"

12:13 weavejester: Hodapp: I mean more that you can replace a local identity with a remote identity.

12:13 Hodapp: jro_: For one thing, because otherwise, short-circuit evaluation isn't possible.

12:13 jro_: A macro does not evaluate its arguments

12:13 weavejester: Hodapp: I didn't mean call a remote function, but admit I kinda made it sound that way :)

12:15 jro_: I see. And in a form (defn f [& rest] ...) rest is not lazy?

12:17 weavejester: jro_: It could be lazy, I believe.

12:19 jkkramer: ,(apply (fn [& args] (take 3 args)) (repeat :foo))

12:19 clojurebot: (:foo :foo :foo)

12:31 jro_: ,(and false (repeat true))

12:31 clojurebot: false

12:31 cheezey: lol

12:32 jro_: I got it :-)

12:41 octagon: hi, is there a function f in clj such that (f [g h ...] [x y ...]) => [(g x) (h y) ...]?

12:42 aniero: ,(map + [1 2 3] [4 5 6])

12:42 clojurebot: (5 7 9)

12:42 aniero: oh, i misread. hm.

12:43 cgag: ((juxt g h ...) [x y ...]) is [(g x) (h y) ...] isn't it?

12:43 Bronsa: 4no

12:43 cshell_: Isn't it just x?

12:43 no y?

12:43 octagon: ((juxt f g ...) x) => [(g x) (h x) ..]

12:44 cgag: aah sorry

12:44 cshell_: yeah

12:44 Bronsa: it's [(g [x y ..]) (h [x y ..]) ..)

12:44 ]

12:44 octagon: oh right

12:44 aniero: hmm, what about (map apply [x y..] [g h...])

12:44 octagon: https://gist.github.com/3743782 is what i have so far

12:45 aniero: ,(map apply [+ -] [1 1] [1 1])

12:45 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

12:46 octagon: it works, i was just thinking that there must be something in the API that already does that

12:46 aniero: aw.

12:46 cvkem: sound like (vect (map #(%1 %2)) [ g h ..] [x y z]))

12:46 octagon: cvkem: i want it to be variadic

12:46 technomancy: you would want to map funcall, but clojure doesn't have funcall

12:47 octagon: technomancy: (partial apply apply) is suspect :)

12:47 technomancy: ,(let [funcall (fn [f & args] (apply f args))] (map funcall [+ -] [1 1] [1 1]))

12:47 clojurebot: (2 0)

12:47 technomancy:

12:47 heh

12:47 octagon: technomancy: that's interesting actually

12:48 technomancy: that's better than my spec, seems like you have (defn zip-apply [fns & argvecs] ...)

12:49 where (zip-apply [f g ...] [r s ...] [t u ...] ...) => [(f r t ...) (g s u ...) ...]

12:50 technomancy: funcall is weird. I always feel like I shouldn't want it, but sometimes I do.

12:51 octagon: i think it's totally legit

12:52 cvkem: does anyone now whether (eval ...) just interprets a tokenized list, or does it actually compile? (I guess it doesn't)

12:52 technomancy: yeah I always just associate it with gross lisp-2-isms

12:52 guilt by association I guess

12:52 cvkem: clojure doesn't have an interpreter

12:53 cvkem: but taking the same string and passing is to (eval ...) or to (load-string ...) sometimes results in a diffent outcome. .... which puzzles me.

12:54 technomancy: cvkem: load-string is completely different

12:54 load-string invokes the reader

12:55 eval just compiles a given form

12:55 cvkem: technomancy: that is correct. In order to use (eval .. ) you have to first tokenize the sting with a push-back-reader.

12:56 technomancy: cvkem: well, there's different ways to do it. the point is eval takes a form.

12:56 cvkem: If they both should give the same result then I guess I skrewed up my tokenizer. ... that explains the difference

12:56 Correct. I pass in a single form.

12:56 technomancy: load-string is probably just (comp eval read-string)

12:57 well except read-string assumes a single form

12:57 cvkem: However, if the load-string solution is the better (and certainly more compact solution) I'll take tat one.

12:57 That is correct. I had to split in separate forms and eval each of them individually. ... I'll throw out my old code.

12:58 TimMc: cvkem: What are you using it for?

12:58 cvkem: TimMc: I'm developing a pentaho bi-server plugin that allows me to program my data-processing directly in clojure.

12:58 ... and mix the code with sql-code for data access.

13:02 octagon: technomancy: thanks for your help, check it out: https://gist.github.com/3743782

13:02 technomancy: fancy =)

13:42 lotia: greetings all. when declaring a future, can I set the timeout when declaring the future? or does it have to be done when derefing the future?

13:44 cemerick: lotia: futures and other dereferenceables don't have timeouts; they all have their own semantics as to what and when a blocking deref call will return

13:44 The timeout you can provide to deref is local to that fn call, and doesn't impact the reference that you're deref-ing.

13:58 duck11232: lotia: if you're looking for something like timeouts for futures, lamina has wait-for-result that'll do pretty much what you want

14:10 weavejester: I've written a blog post on routing in Compojure

14:10 http://www.booleanknot.com/blog/2012/09/18/routing-in-compojure.html

14:10 Does anyone think it's worth publisizing?

14:13 duck11232: weavejester: nice little guide. Seems like that should be in the compojure wiki

14:14 weavejester: duck11232: I'll link it from the wiki. How's that? :)

14:14 jcromartie: the ONE mistake I make more than anything else: def instead of defn

14:14 duck11232: that works. I can see a lot of ring newbies getting a lot of help from that

14:15 jcromartie: recursive conversion of XML DOM node to Clojure map? nailed it… except for the defn

14:15 duck11232: jcromartie: it's always something like that, isn't it. Akin to the missing semicolon

14:16 weavejester: jcromartie: You could change your highlighting to have defn and def look different? :)

14:43 abalone: i wrote a cljs lib. and i have some js that uses it. is there a way i can get an optimized version of the cljs lib that has the fns i want to call? that is, how do i tell the optimizing step about my regular js file?

14:43 TimMc: externs, I think...

14:43 Err, wait -- that's the opposite.

14:43 ohpauleez: abalone: You want to ^:export your cljs functions if you want to use them unmunged in JS code.

14:44 abalone: ah

14:44 ohpauleez: if you want to use the JS functions in your CLJS code, you need to create and externs file for them

14:44 amalloy: well, the closure guys would tell you to include your js file in the optimizing-compiler step, probably. then you don't need externs

14:45 ohpauleez: abalone: An example: https://github.com/shoreleave/demo-shoreleave-solr/blob/master/src/findit/client/main.cljs#L17

14:45 abalone: amalloy: how do i do that? and do you mean externs? or export?

14:45 ohpauleez: amalloy: He wants to go in the other direction

14:47 abalone: the js part is a codemirror keymap for my bastardization of paredit and the cljs part is where i do the scanning for what i want

14:47 amalloy: ohpauleez: it should be possible to run the closure compiler on both the generated js and his by-hand js, right? i don't think it's necessarily wrong to go in "this direction"

14:48 you don't need exports if you can get closure to munge both sides at the same time

14:49 ohpauleez: In the past, I haven't had positive experiences with the closure compiler and non-closurized JS code

14:50 but yes, if you pulled both into the same project, you could avoid the need to export. That said, export is a great way to get third-party interop in the direction we're talking about

14:51 abalone: silly question: would that mean i compile all of codemirror with amalloy's suggestion? that can't be what he means

14:51 I think i'll export

14:51 amalloy: right, export is probably easier; i don't have a lot of experience and didn't think it through. but it should be possible without afaik

14:51 octagon: technomancy: final version: (def zip-apply (partial partial map #(apply %1 %&)))

14:55 patchwork: Hey #clojure, I have a lengthy question that I chose to type into stackoverflow rather than type it all here: http://stackoverflow.com/questions/12483083/clojure-ring-how-can-i-integrate-my-clojure-app-with-a-java-build-process-that

14:55 cvkem: How do I check a variable exists but does not have a root binding?

14:55 The sniplet (= #"Unbound: #'user/X" (str X)) works but is far from elegant.

14:55 abalone: cvkem: is it bound?

14:55 patchwork: Basically I am trying to integrate a ring app with a maven build process that is out of my control

14:55 and wondering where to start with that

14:55 abalone: cvkem: i mean ,(doc bound?)

14:56 patchwork: Has anyone built ring apps directly with maven that would have insight into this?

14:56 abalone: ~(doc bound?)

14:56 clojurebot: gitdoc is http://github.com/Lau-of-DK/gitdoc/tree/master

14:56 weavejester: patchwork: Lein doesn't use Maven under the hood except for managing dependencies (and then only a few functions AFAIK)

14:56 cvkem: abalone: that needs to be it.

14:57 hiredman: (doc bound?)

14:57 clojurebot: "([& vars]); Returns true if all of the vars provided as arguments have any bound value, root or thread-local. Implies that deref'ing the provided vars will succeed. Returns true if no vars are provided."

14:58 patchwork: weavejester: Aha, so is this a hopeless endeavor then?

14:58 weavejester: patchwork: My guess is that your best approach would be to add Leiningen as a development or build dependency and call it directly.

14:58 michaelr`: hello

14:58 weavejester: patchwork: Presumably Maven has a way for running a Java class with a main method?

14:58 patchwork: weavejester: That would be great

14:58 weavejester: I assume so, possibly as a plugin

14:59 I don't know much about maven at the moment, taking a kind of crash-course approach at the moment

14:59 Sgeo: weavejester, may I ask why, in Hiccup, when determining id and class from a symbol's name, you require the id to come before classes?

15:00 weavejester: patchwork: Perhaps http://mojo.codehaus.org/exec-maven-plugin/usage.html

15:00 technomancy: patchwork: I think you can get a pom out of lein that will use clojure-maven-plugin but I don't know the details.

15:00 hugod might know

15:00 weavejester: Sgeo: Because it was easier to write a regex given that constraint, and I never got around to correcting it

15:01 Sgeo: Ah

15:01 patchwork: technomancy: That sounds perfect. If I could generate the right pom it could all just be taken care of.

15:01 So there is a maven plugin for clojure, thanks

15:11 duck11232: https://github.com/talios/clojure-maven-plugin

15:20 jcromartie: I added :dev-dependencies [[ring-serve "0.1.1"]]

15:20 and then ran: lein deps

15:20 but it never downloads ring-serve

15:21 weavejester: jcromartie: Are you using Lein 2 by any chance?

15:21 jcromartie: I'd imagine

15:21 weavejester: jcromartie: Check with "lein version"

15:21 jcromartie: yes

15:21 lein 2.0.0-preview10

15:23 weavejester: In Lein 2 :dev-dependencies was removed in favor of profiles and plugins

15:23 Dependencies for your project you only want in dev mode now look like:

15:23 :profiles {:dev {:dependencies [[ring-serve "0.1.1"]]}}

15:24 Plugins (i.e. anything that extends Leiningen itself) are under :plugins

15:24 e.g.

15:24 :plugins [[lein-ring "0.7.5"]]

15:24 jcromartie: or should I install an older version of Leiningen

15:25 I guess I'll stick with 2

15:27 I like profiles/plugins

15:30 patchwork: Hmm… I tried using the lein :pom-addition directive, but my additions are not being output in the pom. Has that directive not been released yet?

15:31 Possibly I can build a cutting edge version of lein

15:32 ro_st: ohpauleez: any luck?

15:32 ohpauleez: ro_st: Haven't started on it yet, but I'll get to it within an hour or so

15:32 ro_st: ohpauleez: no pressure, btw. just curious :-)

15:33 xeqi: patchwork: I think that came out in -preview8 or -preview9

15:33 ohpauleez: no problem! Thanks for reporting the bug

15:33 ro_st: got -plenty- to do before i need to be testing in those browsers

15:33 ohpauleez: no idea it even existed

15:33 ro_st: don't use Safari? :-)

15:33 or Opera

15:33 jcromartie: weavejester: tell me: what version string should I use for ring-jetty-adapter… I tried to go off of ring's own project.clj but 1.2.0 does not exist

15:33 ro_st: i only managed to get rid of goog-jar today :-|

15:33 finally.

15:34 patchwork: xeqi: Is there a standard way to install a preview release?

15:34 ro_st: only preview releases are available for lein2

15:34 jcromartie: 1.1.5 works

15:34 ro_st: https://github.com/technomancy/leiningen#installation

15:34 jcromartie: I guess 1.2.0 is internal?

15:39 amalloy: (do (do (do x) (do y) (do z))) ;; my macros like to hum while they work

15:42 jcromartie: so ring-serve is incompatible with the latest ring-jetty-adapter I guess

15:52 no7hing: that awkward moment after you dismantled the engine looking for a problem and it actually was the steering wheel

15:53 anybody else had stark performance problems when using compojure contexts (and matching for a number) ?

15:53 urls look like /(numerical user id)/action

15:54 warn-on-reflection is on but only for my own code -.-

15:55 ro_st: tried replacing the id with a static default and comparing?

15:55 ./34/:action vs /:id/action

15:55 erk

15:55 ./34/:action vs /:id/:action

15:56 no7hing: not yet

15:56 i had i benchmarking handler at the end of the handler list

15:56 apparently it took quite a while to arrive there

15:58 weavejester: jcromartie: The latest is 1.1.5. You can find out by looking at the README or in Clojars.

15:58 no7hing: like so https://www.refheap.com/paste/5148

15:59 i was cleaning up code, moved the benchmarking handler from "/" to it's own route and to the bottom of the handlers

15:59 weavejester: no7hing: There shouldn't be any performance problems… The strings are pre-compiled into regexes

15:59 ro_st: no7hing: using aleph? for websockets?

15:59 weavejester: no7hing: So it should be pretty fast

15:59 no7hing: @ro_st: no web sockets; just SSE

16:00 @weavejester: as soon as i comment out the context block it goes from 10k rps to 22 k rps

16:00 ro_st: sse?

16:00 clojurebot: to be fair I dunno that I've ever had code out right rejected, it just sits in jira or assembla or where ever, or if I ask if there is any interest (before writing any code) I get told to go write alioth benchmarks

16:01 no7hing: server sent events, basically chunked transfer

16:01 ro_st: oh, ok

16:01 no7hing: to have a push-(only) channel to the client

16:01 that works through firewalls

16:01 weavejester: no7hing: Well, the context is altering the request map, while the other routes just match against it.

16:01 ro_st: i'm dead keen to do websocket stuff with clj

16:01 no7hing: oh

16:01 weavejester: no7hing: Compare a couple of map gets and a regex compare against the additional overhead of updating a request map...

16:01 no7hing: maybe it's aleph who doesn't like that

16:02 weavejester: no7hing: I can see it taking twice as long

16:02 no7hing: can/can't ?

16:02 weavejester: Can

16:02 ro_st: short answer: don't use contexts

16:02 weavejester: Updating the request map probably takes as long as matching the URI and request method

16:02 ro_st: Um, well, not really...

16:02 ro_st: un-DRY your route definitions

16:02 no7hing: i arrived at the same conclusion just right now :D

16:03 damn

16:03 :)

16:03 weavejester: You can always unroll to improve performance

16:03 But it's a tradeoff

16:03 ro_st: sorry, i should have contextualised (hah) that, weavejester: if you want the performance gain

16:03 weavejester: ro_st: Okay, then I agree with you :)

16:04 jkkramer: weavejester: looks like defmultis not showing up in codox is a clojure bug. Calling defmulti more than once obliterates the metadata on the var, which seems to happen by the time codox gets ahold of it

16:04 no7hing: definitely want that performance

16:04 weavejester: context adds a :context and :path-info key to the request, and I'd guess that takes as much time as a map read and regex over a short string

16:04 no7hing: having a friendly competition with workmates & their jruby server

16:04 weavejester: In theory a static routing table would be even faster.

16:04 casion: isn't jruby fairly slow?

16:05 weavejester: jruby's meant to be faster than c ruby in some cases

16:05 no7hing: yes, that's why i left my weapon of choice in the closet: erlang

16:05 i can feel it's smugness staring at my back :D

16:06 casion: last I looked at benchmarks, jruby was on average an 10-15x slower than clojure

16:06 weavejester: Personally performance of web servers doesn't worry me too much :)

16:06 no7hing: it *kind* of matters for us

16:06 but not the overall benchmark

16:07 ro_st: the bottleneck is usually in the app <-> db roundtrip

16:07 no7hing: that's actually operations & development speed

16:07 ha, we're stateful

16:07 hence erlang

16:07 casion: cbg still has clojure being way faster than jruby… which isn't saying much, but it's something

16:07 weavejester: You could probably speed things up further by removing any middleware you don't need.

16:07 casion: median 19x faster

16:07 aperiodic: no7hing: grammar pedantry: it's is a contraction of "it is"; the possessive form is "its"

16:08 no7hing: dammit

16:08 i thought i wouldn't make those mistakes

16:08 weavejester: The compojure.handler/site function adds a lot of middleware you might not need.

16:08 So manually adding the middleware you want could speed things up further.

16:08 ro_st: aperiodic: if i want to say that this case has a fault, is it this case's fault or this cases fault?

16:08 naeg: I'm trying to do conways game of life in core.logic - how could I "iterate" over all the given cells (to determine for each cell whether it's alive in the next generation)

16:08 casion: case's

16:09 aperiodic: ro_st: the former. it inverts the usual rule, which is why it's so easy to get wrong

16:09 ro_st: no wonder i feel uncomfortable all the time.

16:09 no7hing: @weavejester: only adding favicon bouncer, json params and error handling

16:09 casion: though if you have more than 1 case, it's the cases' fault

16:09 weavejester: no7hing: That's pretty minimal.

16:09 naeg: oh, nevermind my question

16:10 aperiodic: weavejester: how would i get a site handler with *no* middleware?

16:10 no7hing: plus resources & not found, but that doesn't count

16:10 weavejester: aperiodic: Just don't use compojure.handler/site

16:11 no7hing: i want a t-shirt with "Un-DRY your routes!" on it

16:11 weavejester: aperiodic: (defn handler [req] {:status 200, :headers {}, :body "Foo"}) is the simplest handler

16:11 no7hing: Hearing that makes me wince :/

16:11 no7hing: haha sry

16:11 weavejester: It's okay

16:12 I think that's made up my mind about Hiccup anyway

16:12 aperiodic: weavejester: so can i just use the routes i defined with defroutes as a handler?

16:12 ro_st: for or against?

16:12 hiccup.

16:12 weavejester: For Hiccup 2.0 I'm going to make return a clojure.xml DOM, which will be slower than strings, but more flexible.

16:12 aperiodic: Right. That's all they are after all.

16:12 ro_st: so for, then :-)

16:14 hiccup is clj only, right? no cljs?

16:14 weavejester: aperiodic: I put together a blog article on Compojure routing today, as it happens: http://www.booleanknot.com/blog/2012/09/18/routing-in-compojure.html

16:14 ro_st: Yes, but there's an equivalent project with the same syntax called Crate I think

16:14 emezeske: ro_st: There is a semi-decent port of hiccup to cljs called crate

16:14 ro_st: And a few others ports that are less than semi-decent

16:14 ro_st: oh, awesome

16:15 i'm using enfocus / enlive but sometimes you don't want to go through the .html hopscotch

16:15 hiccup is awesome for 'quick n easy'

16:15 aperiodic: weavejester: i saw that; it was very helpful to me, as someone who only started using compojure this past weekend

16:15 weavejester: aperiodic: Awesome

16:16 ro_st: looks like a great article on clojure, actually.

16:16 weavejester: aperiodic: Really, compojure.handler/site should be called something like wrap-default-site-middleware

16:16 ro_st: how to use it well

16:16 * no7hing reading weave jester's blog post

16:16 weavejester: A lot of Compojure functions I might rename if I could start again.

16:16 Like routes might be cascade

16:16 And I'd probably get rid of defroutes...

16:16 jcromartie: weavejester: yeah, I never use defroutes

16:16 aperiodic: weavejester: yeah, i will cop to just copying that out of the example because i didn't know what it did but it was important-seeming

16:17 ro_st: +1 for less macros

16:17 hate not being able to (apply) sometimes

16:17 no7hing: i'm using defroutes; something absurdly wrong with it?

16:17 weavejester: A lot of the functions in Compojure were named four years ago, and since then I've gotten a little better :)

16:18 no7hing: Nope

16:18 no7hing: But (defroutes x y z) is just (def x (routes y z))

16:18 amalloy: i like defroutes, personally, and i generally don't like defx macros. but maybe that's just because i found out about it before i knew about routes

16:18 weavejester: no7hing: In retrospect, the macro isn't really needed. It obscures the functionality a little for not much gain in conciseness.

16:19 no7hing: ah ok

16:20 emezeske: weavejester: It saves some indentation, which can be nice

16:20 weavejester: emezeske: That's true :)

16:20 I might also have called the "routes" function "cascade" instead

16:20 ro_st: also, defroutes hilights differently, which helps to draw attention to the fact that something particular is happening

16:21 amalloy: ugh. if (def x (routes x y z)) is too indented, your routes are probably not very well abstracted/named

16:21 weavejester: Because "routes" is really a very general function

16:22 emezeske: I just hate any extra indentation. I despise the idiomatic Clojure indentation rules.

16:22 ro_st: -irks amalloy- weavejester: it's the maybe monad!

16:23 weavejester: (defn routes [& rs] (fn [req] (some #(% req) rs))

16:23 (defn cascade [& fns] (fn [& xs] (some #(apply % xs) fns)))

16:23 amalloy: ro_st: no it isn't

16:23 ro_st: phew. i was worried i got that right by accident

16:24 casion: every time someone says monad in this channel, I die a little inside

16:24 Sgeo: A lot of things aren't the Maybe monad. Including the thing that clojure.algo.monads calls maybe-m, as in the Maybe monad.

16:24 casion: sgeo should show up soon now

16:24 amalloy: casion: for me it's just when Sgeo says it

16:24 casion: oh.. there he is

16:24 lol

16:25 Sgeo: amalloy, :( sorry, what am I doing wrong?

16:25 amalloy: Sgeo: saying the same thing about monads over and over: you're complaining about them and not trying to fix them. if you don't like them, file a bug report (as i understand you have), and either fix them or don't use them

16:28 abalone: oh. is there a way for cljs to return a complex value like [1 2] such that regular js can take it apart *if the cljs has been minified* ? my concern is that the js would not be able to say cljs.core.nth since that will be munged and that's cljs that i don't have control over (and can't export)

16:29 duck11232: abalone: could you return a standard js array?

16:29 abalone: i could if i knew how :)

16:29 do you know how?

16:29 amalloy: abalone: dnolen has some lib that exports versions of the common cljs functions to js

16:30 https://github.com/swannodette/mori

16:30 abalone: amalloy et al: thanks! will look into it

16:30 duck11232: (array 1 2) returns a js array

16:30 dnolen: abalone: it's pretty simple and you can do this yourself w/ ^:export. pull requests to mori welcome too if you see something missing.

16:31 cark: sgeo check this approach out : https://gist.github.com/3745638

16:32 ro_st: duck1123: 4 months of cljs and i only learn that now

16:32 cark: Sgeo: lots of macro work to put on top of that

16:32 duck11232: I do a lot of js interop. My code is littered with js-obj and array calls

16:34 abalone: duck11232: so array works out of the box without mori?

16:34 Sgeo: cark, cool

16:35 Although I didn't look at it that closely yet, I think I don't quite understand deftype as well as I should

16:35 duck11232: abalone: yep. It's nice because it emits a standard literal array, no excess calls

16:36 Sgeo: Ah, so return knows what to do because it's passed what it needs as an argument

16:36 cark: Sgeo: that's where you need some macro magic akin to what's in algo.mona

16:36 d

16:39 Sgeo: How do Functors and Applicatives fit into this model?

16:40 ticking: am I correct taht there is no def- ?

16:40 cark: they could be additional protocols that you add to your deftypes

16:41 dnolen: ticking: yes

16:41 ticking: dnolen, hm any Idea why not? When creating functions with partial this seems pretty usefull, or am I missing a idiomatic concept there?

16:41 cark: Sgeo: don't make me do it, i just made this because it was tickling me. I really don't have the time =)

16:41 Sgeo: In principle though, all monads should be functors, although I guess the macros could take care of that

16:42 Ah, ok

16:42 abalone: duck11232: if i want to check equality on something that returned (array 1 2) in cljs, (= (array 1 2) (myfn args)) doesn't seem to work. should it? if not what should i say instead?

16:42 cark: Sgeo: feel free to take this code and do something with

16:42 Sgeo: or take a different approach entirely

16:43 dnolen: ticking: ^:private is useful for documentation - it's really ns that controls visibility.

16:43 antares_: Welle 1.3.1 is released with a pretty nasty bug fixed: http://blog.clojurewerkz.org/blog/2012/09/19/welle-1-dot-3-1/

16:45 ticking: dnolen, ah k, but yeah thats pretty mutch what I used it for so far, signalling helper functions you're not supposed to call ^^

16:46 weavejester: In principle, do people think bad user data should be handled by an exception, or a return value of some kind?

16:47 cark: Sgeo: you can do functors by defining a protocol for it with a fmap method (fmap [self f])

16:48 Sgeo: then add it to the Just and Nothing deftypes

16:48 ro_st: arent' exceptions bad for performance?

16:48 Sgeo: cark, sure, but I shouldn't need to add it to Just and Nothing manually

16:48 weavejester: I'm more interested in correctness than performance.

16:48 no7hing: weavejester: inside the app we throw an exception, but the client get's a 200 back with an error in the body

16:48 the/our apps

16:48 cark: Sgeo: yes you do, how do you think haskell does it ?

16:49 weavejester: no7hing: That sounds kinda un-RESTful :)

16:49 no7hing: flash clients :p

16:49 weavejester: Ah :)

16:49 no7hing: but i like the concept

16:49 weavejester: I was thinking about how to abstract a http resource

16:49 cark: Sgeo: there must be some place with an instance declaration : instance Function (Maybe a) where ..

16:49 Functor*

16:49 Sgeo: cark, Haskell doesn't support what I want, but in theory it should be doable from just knowing the monad definition

16:50 cark: you got it backwards

16:50 weavejester: I don't hugely like the approach taken by Liberator.

16:50 cark: it's because Maybe is a functor that it can also be a monad, not the other way around

16:50 Sgeo: fmap f a = do x <- a; return (f x)

16:51 no7hing: i made the mistake and googled for liberatpr


16:51 liberator

16:51 weavejester: no7hing: https://github.com/clojure-liberator/liberator

16:51 no7hing: interesting first result

16:51 http://www.liberator.com/

16:51 nsfw

16:52 Sgeo: cark, yes, all monads are functors, but for all monads, each monad can be described as a functor in the same way

16:52 S11001001: Sgeo: also liftM

16:53 weavejester: I was thinking about the minimum set of functions required to define a RESTful resource…

16:53 Cheiron: is it stable enough to use for production?

16:53 I mean https://github.com/clojure-liberator/liberator

16:53 weavejester: deref / put! … maybe validate as well for checking the data

16:53 Cheiron: is it stable enough to use for production?

16:54 weavejester: Cheiron: It seems to be fairly stable. It depends on how critical your production is I guess.

16:54 cark: Sgeo: anyways who cares how you need to define stuff manually, that's not like you'll be creating 20 monads for every project

16:55 Cheiron: what is its selling points over bishop?

16:58 duck11232: abalone: You'll have to use one of the methods for testing js array equality. http://stackoverflow.com/questions/3115982/how-to-check-javascript-array-equals

16:59 js arrays are simple, hence not as cool

17:00 weavejester: Cheiron: Not sure :)

17:00 Cheiron: fair enough :)

17:00 abalone: http://stackoverflow.com/questions/3115982/how-to-check-javas

17:00 cript-array-equals

17:00 oops

17:00 thanks!

17:01 duck11232: (defn arr= [a b] (not (or (< a b) (> a b))))

17:01 abalone: hm. ok

17:01 Cheiron: any new web framework that I might missed? (I know about Noir, compojure, moustache, conjure)

17:01 weavejester: Cheiron: Only Noir and Conjure are really web frameworks

17:01 abalone: didn't know arrays could be sorted/compared like that

17:02 duck11232: That seems rather dirty, but seems to work

17:02 abalone: (> work dirty)

17:02 Cheiron: clojurebot: para que la vida

17:02 clojurebot: Clojure ranked #21 on 8/14/2009

17:11 duck11232: abalone: if you read all the comments on that SO question, there are some issues with that solution.

17:12 (defn arr=2 [a b] (= (seq a) (seq b)))

17:13 abalone: duck11232: ok. thanks again!

17:13 hiredman: ,(pl (↕map (replicate 3 (↕apply vector $ (↕map range $ 10 inc · inc · inc) call · ⌽* $ 10 · call · (⌽+ -2) map)) shuffle))

17:13 clojurebot: ([20 50 40 80 70 ...] [50 10 30 100 70 ...] [70 80 10 20 40 ...])

17:14 hiredman: I recalled it's been a while since I ran pl in here

17:14 blrandel: hiredman: are you enjoying your time on earth so far? (what was that? O.o)

17:15 hiredman: pl is a macro I wrote years ago that does rewriting of expressions based mostly on unicode prefixes

17:16 blrandel: based on APL?

17:17 hiredman: ,(macroexpand '(pl λx x))

17:17 clojurebot: (do (fn [x] x))

17:17 hiredman: not really based on anything

17:17 blrandel: neat

17:21 hiredman: https://github.com/hiredman/odds-and-ends/blob/master/functional.clj

17:22 jcromartie: I guess the only way to talk XML and JSON in an HTTP API backed by an XML document is to have an intermediate format

17:22 like, my database is literally an XML document

17:22 and queried via XPath

17:22 but I might as well parse things into records and leverage cheshire for JSON, and something more custom for XML

17:22 but there's nothing as smooth as JAXB

17:23 I say "smooth", of course

17:25 duck11231: jcromartie: Are you, by any chance, using eXist for your db?

17:25 jcromartie: no, it's literally an XML file

17:26 a single XML file with a simple list of items

17:26 duck11231: ahh. I used to use eXist quite a bit, but I never tried using it from Clojure

17:28 jcromartie: I think the answer is to parse the XML into an intermediate format before sending it back as either JSON or XML (again?)

17:28 or I dunno

17:28 no

17:32 patchwork: Hmm… can I use :pom-addition to nest some xml inside of the build section, or is it only for project level additions?

17:41 blrandel: is anyone aware of any good lightweight alternatives to Drools for decision/rule engines?

17:42 would imagine core.logic would be useful for implementing something along those lines

17:44 gtrak`: anyone ever use yguard to shrink a bunch of AOT stuff? is it a viable option?

17:49 aib: what's the idiomatic way for a game/processing loop? (when (not [complicated set of quit conditions]) [loop code]) or is (def runLoop true) (when runLoop ...) ok?

17:50 or perhaps (defn run-loop? ...) ?

17:54 aperiodic: aib: i'd define a should-quit? predicate that takes the current game state, which is i think what you mean by your last option

17:56 aib: aperiodic: yep, thanks. and the game state would be in a global symbol? (something defined with def?) this is my first attempt at doing anything substantial in an "impure" functional language

17:57 oh, nope since when can pass it the game state. sorry

17:57 gfredericks: blrandel: core.logic is pretty specific/focused; I'd be very hesitant about using it for something like business rules

17:58 antares_: ohpauleez: hey

17:58 ohpauleez: antares_: How's it going! I still have all the notes from our last conversation. I just got swamped with day job work

17:59 antares_: ohpauleez: I wanted to ask if there is any progress on this. There are more and more people who give up: https://twitter.com/ieure/status/248165536985403392

18:00 and I had to file issues what really should have been a clojure-dev post, but I cannot post there

18:00 thorbjornDX: is there a way to do type coersion in a let statement? i.e. (let [[a (int b) c] myvec] [a b c])

18:01 aperiodic: aib: all the game logic and everything should be pure; you should only need to bring in state (in an atom or some refs) when you're writing the frontend code that interacts with the user to run an instance of the game

18:02 blrandel: gfredericks: ok, will keep that in mind.. I'm just looking for an alternative to drools/jess really, to build a clinical inference engine

18:02 ohpauleez: antares_: Looking over all of this now. I think everyone agrees the system could be better and that it's not answering all the possible needs.

18:02 antares_: ohpauleez: "could be better" is a very polite way to put it

18:03 ohpauleez: ok, nevermind, I see there were not discussion with The Elders

18:04 ivan: so, what's the deal with negative indices?

18:04 ohpauleez: antares_: I'll post the notes from our talk as soon as I get a second (sometime this week)

18:04 and we can get the ball rolling on taking the first steps to something better

18:04 antares_: ivan: that's the problem, nobody really says, the person who submitted the patch has been working on getting it in for over 1 month

18:04 ivan: is there a design evil with numbers below 0, or just interop stuff, or consistency stuff?

18:05 antares_: only to hear some mumbling back and give up

18:08 ohpauleez: antares_: We're just growing out of the old system, that's all. This happens on nearly every open source project.

18:08 We'll get to a new system, with new approaches to evolving the core and the ecosystem

18:08 technomancy: except I submitted this same enhancement over 2 years ago

18:09 antares_: ohpauleez: you, sir, is probably a hopeless optimist

18:09 aperiodic: i've had a bug report regarding an outright lie in the gen-class docstring open for nearly two months now, and there's been absolutely no activity on it

18:10 ohpauleez: antares_: I don't think so. I believe in proactively working towards something better and I have a lot of larger open source project experience under my belt

18:11 Clojure has an amazing community

18:11 and a process that hurts good ideas, innovation, and improvements

18:12 antares_: ohpauleez: the phrase you are looking for is "alienating the most active contributors"

18:12 ohpauleez: It needs adjusting and through the power of community and patience, it'll get there

18:12 it should have happened probably a year or more ago

18:12 antares_: ohpauleez: yeah, if something is broken is The Elders don't care, call for patience

18:12 ohpauleez: antares_: The solution will not come about from needlessly negative comments. That I can tell you with certainty

18:13 antares_: And you are hurting the cause by continuing that line

18:14 antares_: ohpauleez: yeah, only cheerleading works when everybody around is giving up :)

18:14 dnolen: gfredericks: not sure I agree but I haven't looked closely enough at Prolog-style rules solutions to say much more.

18:15 antares_: ohpauleez: sorry for wasting your time, I now have a comlpete picture of how hopeless the situation is

18:15 dnolen: blrandel: it something worth trying - would appreciate feedback along those lines.

18:15 ohpauleez: So please refrain from such language. No one, not even "The Elders" disagree with you. But to date, no one has put together ideas down, and created a plan. The only progress took place when Andy Fingerhut stood up to take responsibility for focusing screening efforts.

18:15 antares_: The situation isn't hopeless and you're certainly not wasting my time

18:17 blrandel: dnolen: datalog looked like it might support my use-case, but I need to investigate more

18:18 ohpauleez: We can continue to all say, "This process is broken. I'm leaving" or be more proactive and say. "This process is preventing X from happening. How can we successfully make X happen, and prevent this from happening in the future"

18:19 antares_: The notes from the last conversation are the start. I'm currently dropping the ball by not posting them. I will. I think they're good ideas. But continuing to be negative isn't going to change anything

18:20 antares_: ohpauleez: are you seriously expecting people who spend 1 month trying to get an obvious patch in to say that?

18:20 technomancy: well, it could help the overall ecosystem if people start contributing to places where their efforts actually make a difference

18:20 antares_: that's hopeless optimism I was referring to

18:21 ohpauleez: people will say "fuck clojure/core, I will stop using clojure" or "I will work on projects where my contributions are at least considered"

18:21 blrandel: what in your opinion are some of those places technomancy?

18:21 cgag: technomancy: I want to start contributing, where is that?

18:21 dnolen: blrandel: definitely - though if you're talking about the contrib datalog there hasn't been much development activity on that for a long time. it's relatively slow last I checked.

18:21 blrandel: right :/

18:21 ohpauleez: technomancy: I think they do that already and I think the community is responding to that.

18:21 dnolen: blrandel: but there's also datomic and that's quite zippy

18:22 blrandel: hmm, wasn't aware of that, will check that out dnolen thanks

18:22 clojurebot: thanks for your suggestion, but as usual it is irrelevant

18:22 antares_: ohpauleez: and maybe that's wrong and all, but you cannot change people. Clojure already has the reputation of alienating contributors, over and over.

18:22 ohpauleez: I'd love to see a clojure-incubation led by the community

18:22 blrandel: dnolen: wait, the database engine?

18:22 dnolen: blrandel: yes

18:22 Cheiron: cmiles74: Hi, here?

18:22 cgag: clojure-incubation?

18:22 aib: aperiodic: how does this look? https://gist.github.com/3746298

18:23 technomancy: blrandel: at the risk of sounding self-serving: https://github.com/technomancy/leiningen/issues?labels=Newbie&milestone=&page=1&state=open

18:23 dnolen: blrandel: but the datalog query system can work on in memory collections, so that might be enough for you.

18:23 ohpauleez: antares_: Again, that's not optimism, that's just the desire to see things get better. People are discouraged, yes. Some core people who have been here a long time are getting discouraged. My point still holds - no one has proposed a concrete set of ideas and potential first steps

18:23 blrandel: huh, I hadn't even considered an approach like that

18:23 technomancy: blrandel, cgag: clojars is another good one; maybe clojuresphere too if you like graph problems

18:23 antares_: ohpauleez: eh? everybody is saying at least 2 things that are the same

18:24 accept CAs over email

18:24 move to github

18:24 end of story

18:25 cgag: leiningen was on my list, i figured even if i didn't contribute it's such a core part of the ecosystem i want to understand the internals a bit

18:25 antares_: then everybody will be able to post to clojure-dev to ask questions and it won't be so irritating to iterate on small changes like in the ticket above

18:25 maybe people won;t get so angry as the result

18:25 technomancy: clj-http/cheshire are really good about accepting patches too

18:25 antares_: and will be able to get answers about why their patch has been rejected

18:26 I think about 7 or 8 clojurewerkz.org projects have contributors beyond the core team

18:26 people just showed up with issues or pull requests

18:26 some were rejected, most were merged

18:26 I don't know a single person who was angry in the end

18:27 people added entire features for us

18:27 xeqi: I started contributing to lein cause technomancy was known to accept patches, there was a clear goal of replacing maven-ant-tasks, and there were tests to tell me if I broke stuff

18:27 aperiodic: aib: how does should-quit? work? the fact that it doesn't take an arg makes me nervous

18:28 antares_: all because we are not requiring to mail a piece of paper, submit a patch to JIRA and then ignoring it for months

18:28 ohpauleez: antares_: I love the ClojureWerkz stuff, but the scope and impact of those projects is very different than that of Clojure

18:28 aib: aperiodic: oh yeah, I haven't started with the game state yet. it only checks for Display/isCloseRequested (lwjgl magic) and Keyboard/isKeyDown

18:28 antares_: ohpauleez: it does not matter, contributors come or go for the same reasons

18:29 aperiodic: aib: other than that, though, looks like a solid start (though i'd switch the (if (not ...))) to an (if-not ...)

18:29 antares_: ohpauleez: data.json and so on are definitely comparable to clojurewerkz, yet contributing to them is not any easier

18:29 aperiodic: aib: on the general topic of writing games in clojure, i'd highly recommend checking out steve losh's caves of clojure series, if you haven't already

18:29 dnolen: technomancy: not to belittle lein, it rocks - but comparing a 1600 LOC Clojure project to Clojure itself - a codebase of pretty intense complexity @ 50K LOC Java + Clojure doesn't make much sense.

18:29 technomancy: dnolen: some parts of clojure are more complicated than others

18:30 antares_: dnolen: why does LOC count matter?

18:30 aib: aperiodic: huh, didn't even know about if-not :) I was more worried about loop-let-recur, haven't used any of them before :)

18:30 dnolen: technomancy: antares_: scope + impact

18:30 technomancy: you want to explain why it should be so difficult to change clojure.test when rich himself says he doesn't even write tests?

18:30 dnolen: as was already well said by ohpauleez

18:30 antares_: dnolen: did you see the issue above?

18:30 dnolen: its scope is 20 lines of code + 30 lines of tests

18:30 technomancy: how many people use clojure.test outside leiningen?

18:30 aib: aperiodic: oh yeah, I've been (read-only) through that. for now I just want framerate-independent movement. in fact, this won't be a game but an infinite animation

18:30 ohpauleez: agreed, if we want to draw comparisons, we should look at Scala project management, perhaps Python management

18:30 dnolen: antares_: rhickey doesn't want negative indices for subs as far as I can tell - there's an older ticket for that.

18:31 antares_: dnolen: yet he has been asked to update it for 1 month, then rejected w/o clear explanation

18:31 dnolen: antares_: pre-existing rejected ticket

18:31 ohpauleez: Scala has a core team, and a single creator. A large community and a separate build tool. They are further down the road than us. How did they cope?

18:31 technomancy: dnolen: I'm all for a high bar for things like the persistent data structures implementation, but applying it across the board is nonsense

18:31 aperiodic: aib: hmmm... have you taken a look at quil?

18:31 antares_: dnolen: well, there still was no explanation

18:31 dnolen: technomancy: well there's always Common Lisp ;)

18:32 Cheiron: how to check the mime type of a file in clojure?

18:32 ivan: "Or, if you insist, I'll just reject it now because a) IMO it's goofy, b) you can make your own function that works that way c) we don't get a free ride from j.l.String, d) it begs the question of negative indices elsewhere..."

18:32 antares_: Cheiron: google for pantomime

18:32 ohpauleez: technomancy: I agree with that. In Linux, I was a Janitor (cleaned code, fixed docs, etc) - that path was low barrier and there was a separated gate-keeper for that whole project

18:33 Cheiron: antares_: thanks!

18:33 ohpauleez: We already have a few set of actions items from the last talk. We have to spend some time (as a community) looking at comparable projects (Python, Scala) and refine those ideas

18:33 ivan: previously http://dev.clojure.org/jira/browse/CLJ-688

18:34 aib: aperiodic: nope. I've seen penumbra, but I'm deliberately reinventing the wheel here, to experience a genuine need for macros and other trickery. then I'll look at libraries such as quil and penumbra and see how simpler they've solved all my problems

18:34 ohpauleez: Also note the process isn't working poorly across the board

18:34 I think CLJS development is awesome. Changes into the contribs are also awesome

18:34 XCommeXorglub: So

18:35 from what I have been told TCO pretty much isn't compatibile with the JVM permision model

18:35 As in, it'll most likely never be in the JVM, is this true?

18:35 casion: have there been any language projects as large as clojure that have outright failed, or just faded away?

18:35 technomancy: the only contrib I've had an easy time with is nrepl, and that's because I bug cemerick about it on IRC directly instead of going through jira

18:35 also because I ask for features and he just implements them rather than me needing to submit a patch =D

18:36 gtrak`: casion: did we hit critical mass?

18:36 cemerick: technomancy: I hear JIRA is a 40-man in the next release. Better suit up. :-P

18:36 casion: XCommeXorglub: java 8 is supposed to have TCO, it's about 80% done it seems

18:37 ohpauleez: technomancy: Right, there's a key example and a full story of a better experience

18:37 What's working there?

18:37 gtrak`: how many folks used smalltalk?

18:37 XCommeXorglub: casion, scweet, gimme links

18:37 ohpauleez: I'd say having a dedicated gatekeeper/owner for that section

18:37 I think that helps a lot

18:37 casion: XCommeXorglub: https://blogs.oracle.com/jrose/entry/tail_calls_in_the_vm http://openjdk.java.net/projects/mlvm/subprojects.html

18:37 technomancy: ohpauleez: what's working is it totally bypasses the contribution pipeline

18:38 antares_: Cheiron: apparently, "pantomime" returns a lot of irrelevant results. here it is: https://github.com/michaelklishin/pantomime, take a look at http://clojurewerkz.org for a few more useful libs.

18:38 cemerick: Apparently the weekly CA/contrib convo hit early this week? :-P

18:39 ohpauleez: technomancy: We need to me introspective than that. What is it about THAT specific experience that makes it work. How it is working? How is it working better than something else? Can that model be uniformly applied to all areas of CLojure

18:39 cemerick: yes, yes it did

18:39 blrandel: oh cemerick, just bought a copy of Clojure Programming for my kindle, really enjoying it, thank you.

18:39 cemerick: blrandel: And thank you, glad you're enjoying it. :-) Make sure to leave a review when you have a chance.

18:40 blrandel: sure thing :)

18:40 casion: gtrak`: did smalltalk 'die' ? it was standardized I thought

18:40 ohpauleez: technomancy: I think part of it is having an owner that's trusted with a section/piece/lib - that works great in other cases as well (not to put dnolen on the spot, but CLJS and core.logic)

18:40 XCommeXorglub: casion, schweet

18:40 Cheiron: antares_: thanks :)

18:40 antares_: ohpauleez: if you are all about productive actiosn, how can I post my thoughts on the process w/o having access to clojure-dev?

18:40 casion: schweet?

18:40 XCommeXorglub: One more thing though ##(symbol? (symbol "I worship his shadow"))

18:40 lazybot: ⇒ true

18:40 ivan: huh "On the other hand, IBM's JVM for version 1.3 purrs along without a problem, indicating that it does transform the code [do TCO] in this way."

18:40 blrandel: casion: not if you ask my son, he really enjoys programming in Scratch, which runs in a Squeek VM afaik

18:40 XCommeXorglub: ==

18:40 gtrak`: casion: ah, I guess that doesn't count then

18:40 XCommeXorglub: Someone file that bug report.

18:40 ohpauleez: antares_: you can post them on the standard mailing list

18:41 hiredman: https://twitter.com/fakerichhickey/status/248093894208786433 speaking of dnolen

18:41 casion: blrandel: I use supercollider and objc everyday almost, as far as I'm concerned smalltalk is alive and well :)

18:42 blrandel: casion: I've been meaning to have a play with Overtone

18:42 antares_: ohpauleez: I don't see any contribution discussions there but ok

18:43 casion: blrandel: I couldn't get into overtone :( it seemed neat until I started to realize I was learning an implementation of a language that I'm learning on a platform that has a designated language that I already know well

18:44 ohpauleez: antares_: You're going to catch more flies with honey - if you want my notes to post, I'll email them to you. But no one is going to get very far (or get this off on the right foot) with a heated, negative post

18:44 blrandel: yeah, I'd imagine if you were already familiar with supercollider it wouldn't provide that much value

18:45 casion: supercollider is already rather functional, so I've yet to see much benefit in making a clojure-based language for scsynth

18:45 antares_: ohpauleez: at this point, I don't really care, it's just sad to see really good developers give up. If I end up posting anything, I almost certainly will try to be reasonably polite.

18:45 casion: and I like the syntax, but maybe that's a draw for some people

18:46 ohpauleez: antares_: I will post by Friday. If you prefer, I can post in the standard mailing list (or cross-post)

18:46 cemerick: oh no, is the process thing on HN again?

18:46 Cheiron: I'm unable to download bishop and pantomime, is it because I'm using lein 1.x ?

18:46 gtrak`: casion: I think from what I've seen, the benefits are from the embedding... use other libs at the same time, not just supercollider

18:47 cemerick: oh, old thread. Whew.

18:47 antares_: ohpauleez: I am sure there will be many people interested in reading your proposal

18:47 casion: gtrak`: that would be neat, I never noticed any examples of that when I looked

18:47 do you know of anything specific off hand?

18:47 gtrak`: there were some neat visuals at clojure/west using javafx

18:47 aperiodic: quil + overtone is pretty sweet

18:48 gtrak`: maybe it was quil, actually

18:48 or say you want to generate notes with a core.logic program

18:48 ohpauleez: antares_: I'll post on the standard mailing list then, so we can open it up for comment. Let's just try to police ourselves and keep things civil :) I also want to dig up relevant history on Python and Scala as well as break down how each of their processes work

18:50 ivan: the Python process is all about killing Python 2 and wasting everyone millions of dollars

18:50 Clojure is doing much better than that

18:50 gtrak`: oh god, is anyone using python 3 yet?

18:50 aperiodic: casion: https://github.com/overtone/mini-beast

18:50 thorbjornDX: print("Django isn't")

18:50 ivan: the next release of Ubuntu ships only with Python 3 and Canonical is funding some ports

18:51 gtrak`: aperiodic: wow

18:51 casion: aperiodic: hmm, I didn't realize you could use overtone like this

18:52 I wonder if I can use clojure-vst with it

18:52 that'd be a bit interesting, if not completely useless

18:52 aperiodic: clojure-vst?

18:52 casion: https://github.com/dwu/ClojureVST

18:52 gtrak`: if only SC had a clojure eval...

18:53 casion: wait, I think that's the wrong project..

18:53 no, that's correct it seems

18:54 aib: aperiodic: one last thing. what data type would you recommend my game state be? I could simply use a []-list (vector?) but being used to strong typing (not to mention Herculean typing, a la Haskell) I'm bound to make mistakes. I could start with named members, e.g. gstate.player.velocity

18:55 cemerick: Just in case anyone's lurking and spooked by the dustup: I actually think things are at a pretty decent equilibrium w.r.t. Clojure's dev process, etc. Not that I think that everything's roses, but there's certainly no disastrous descent or anything either.

18:55 aperiodic: aib: in general, the answer to 'what data type would you recommend' is 'a map'

18:55 aib: I was going to use {:a 1 :b 2} until I came across defrecord and deftype by chance

18:56 emezeske: aib: Instead of gstate.player.velocity you might use (get-in gstate [:player :velocity])

18:56 antares_: aib: records are maps

18:56 aib: with a few exceptions, that is

18:56 emezeske: aib: You almost certainly want to start with the map, and only use defrecord if there's some very good reason that the map isn't good enough

18:56 antares_: aib: so you can start with just maps and use a record once you settle on some state model

18:57 aib: I see. well, get-in looks friendly enough

18:58 cark: and its friend update-in, don't forget about it !

19:03 blrandel: thorbjornDX: Django 1.5 is shipping with experimental python 3 support

19:05 thorbjornDX: blrandel: ah, yeah I've heard about preliminary support. Django was one of the real 2->3 hangups for many people

19:06 blrandel: thorbjornDX: absolutely, yeah

19:13 wow, mini-beast looks, well, beast.

19:14 and has reminded me that I really need to get off my arse and fix my juno-106.

19:23 thorbjornDX: whoops, I accidentally had an infinite sequence in my list comprehension, and I tried to pprint it

19:23 ivan: hopefully your REPL supporting interrupting

19:23 supported

19:24 thorbjornDX: ivan: it did, I'm using vimclojure and I just c-c'd the terminal with the fg process

19:25 tomoj: would it be very difficult to give cljs locals clearing?

19:50 mebaran151: I'm writing a quick webapp in clojure and clojurescript and have finished almost all the pieces; the last part is securing most of it with SSL; I have successfully gotten the server to load my ssl cert but now all my noir routes return 404 for ssl. Is there something I have to fix to make the routes from defpage match SSL routes?

19:53 xeqi: mebaran151: did you add :jetty-options {:ssl? true} to your noir.server/start call?

19:53 mebaran151: xeqi: yep and I have the ssl working

19:54 the only thing left is to get my defpage routes to run

19:54 right now if I hit a route via https, it returns 404, whereas if I hit it via http, it works

19:54 hiredman: noir may not register the handler for ssl correctly

19:54 technomancy: often ssl is easier to handle with an nginx frontend

19:55 it's certainly better-documented

19:55 mebaran151: for the next app, I'll probably write it on top of compojure directly, but for now, I'd like to see if I can get it to register the routes properly

19:55 technomancy: I'd use nginx, but I'm required to deploy to windows :(, which is actually great for Jetty

19:55 technomancy: gotcha

19:55 mebaran151: but I got all the ssl stuff working (java keystore, etc, etc, etc,)

19:56 I just need to get my noir apps to register under ssl too

19:56 *noir routes

19:57 hiredman: mebaran151: have you restarted your repl recently?

19:59 mebaran151: I think so

20:01 hiredman: looks like the noir code should pass the options right through and the jetty adapter shoudl pick them up

20:01 mebaran151: I jus tkilled all my java processes; but it doesn't look like it worked

20:24 Sgeo: deftype is good for situations where I want to have a ... sentinal type that gets treated specially by some function, right?

20:25 And things that aren't it just get treated, say, passed through normally

20:26 Certainly makes more sense to me than a map with a certain key, since user code could easily accidentally make such a map... I think

20:27 mebaran151: woot; https is working, I had some middleware that returned nil on https which seems to have triggered the 404

20:27 cark: deftype is like creating a class in java, but you only can add methods from a protocol to it

20:27 deftype is *actually* creating a java class

20:27 tomoj: Sgeo: if all you need is a sentinel, you can just use (Object.)

20:28 mebaran151: Sgeo: the lispy way to put together a sentinel would be using a gensym

20:28 Sgeo: Well, my sentinal type may need to wrap another value

20:28 * Sgeo still needs to think this through a LOT more.

20:29 tomoj: ah, right, then like Reduced

20:30 in clojurescript that is (deftype Reduced [val] IDeref (-deref [o] val))

20:33 Hodapp: hmm, so if I do, (defstruct foo :a :b :c), and I also have (defn bar [arg1 arg2 {:keys [a b c]}] (blahblahblah)), is there any way I can combine these two definitions so that the function is expecting keyword arguments defined in 'foo'?

20:34 hmm, I guess I don't actually need a struct

20:34 dnolen: Hodapp: and defstruct is deprecated

20:34 Hodapp: it is?

20:35 cark: dnolen: supposedly

20:35 dnolen: Hodapp: use deftype/record

20:36 cark: (defn bar [arg1 arg2 & {:keys [a b c}]) is real keyword arguments

20:37 Hodapp: cark: what's what I put? optional args?

20:37 cark: you call it like so : (bar 1 2 :a 12 :b 25 :c 32)

20:39 Hodapp: cark: if I do it like that, can I also pass in a map in place of all those keywords?

20:39 cark: nope, that's why not many people use it this way

20:40 Hodapp: ahh, so only the way that I gave (non-keyword args, whatever it's called) lets me pass in a map that way?

20:40 Sgeo: There's no way to apply it?

20:40 ,(identity 1 2)

20:40 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core$identity>

20:40 cark: it is possible to pass a map with apply

20:41 Hodapp: well, this is more for ease of use than anything

20:41 so perhaps I'll just stick with optional args

20:41 cark: domething like (apply bar 1 2 (concat my-map)) ; untested

20:41 Sgeo: ,(apply (fn [& {:keys [a b c]}] a) {:a 5})

20:41 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: [:a 5]>

20:41 cark: ,(concat {:a 1 :b 2})

20:41 clojurebot: ([:a 1] [:b 2])

20:41 cark: hum nope

20:41 ,(apply concat {:a 1 :b 2})

20:41 clojurebot: (:a 1 :b 2)

20:42 Sgeo: ,(apply (fn [& {:keys [a b c]}] a) (apply concat {:a 5}))

20:42 clojurebot: 5

20:42 Sgeo: ,(doc concat)

20:42 clojurebot: "([] [x] [x y] [x y & zs]); Returns a lazy seq representing the concatenation of the elements in the supplied colls."

20:42 cark: (apply bar 1 2 (apply concat my-map))

20:42 that's rather ugly and pretty slow

20:43 Sgeo: ,(apply (fn [& {:keys [a b c]}] a) (seq {:a 5}))

20:43 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: [:a 5]>

20:43 gfredericks: TimMc I think always argues for mapply

20:44 cark: ,(doc mapply)

20:44 clojurebot: I don't understand.

20:44 cark: ,(clojure.repl/doc mapply)

20:44 clojurebot: Cool story bro.

20:44 gfredericks: he argues because it doesn't exist :)

20:44 cark: oh ok =)

20:44 gfredericks: but he wants it to

20:44 cark: gfredericks: still would be slow

20:44 gfredericks: ah sure

20:45 it's more from a code-friendliness perspective than a perf one

20:46 cark: i find that it's often not what i want tho

20:46 sometimes you want to pass that map to some other sub-function

20:47 then you're annoyed

20:47 same thiong with update-in kind of functions

20:47 thing*

20:53 TimMc: ,mapply

20:53 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: mapply in this context, compiling:(NO_SOURCE_PATH:0)>

20:53 TimMc: urgh

20:54 gfredericks: clojurebot: mapply?

20:54 clojurebot: You could (defn mapply [f & args] (apply f (apply concat (butlast args) (last args))))

20:54 TimMc: ~mapply

20:54 clojurebot: You could (defn mapply [f & args] (apply f (apply concat (butlast args) (last args))))

20:54 Frozenlock: I want to play a little with local storage. Is there some clojurescript example?

20:54 TimMc: Sorry, I'm apparently about 5 lightseconds away over here.

20:55 dnolen: Frozenlock: no but the api is prette simple (.setItem js/localStorage ...) (.getItem js/localStorage ...) etc

20:55 Frozenlock: dnolen: yet again you show me the path, thank you very much :)

20:56 hiredman: google closure has some local storage wrapper stuff, which annoyingly doesn't include storage events

20:56 mpan: hey guys, I have an algorithm that relies on evaluating a function against a data set and making some decisions, but when I swap the function out to something simpler, the overall runtime takes 10x+

20:57 (it's a genetic algorithm and I'm swapping out the fitness function for one of a similar form)

20:57 hiredman: how many times are you calling it?

20:57 mpan: same as before

20:57 casion: can you post the functions?

20:57 hiredman: most likely you are swapping in un-jitted code for jitted code

20:58 (or the "simpler" function isn't)

20:59 mpan: http://pastie.org/4750865 I swap out obj-euclid (euclidean distance) for obj-min-horiz (x component distance)

20:59 hiredman: that also depends on how you are "switching"

20:59 mpan: I pass the obj-fn in along with the code; should I paste the code that runs it?

21:03 hiredman: *shrug* if you really want to know, use a profiler, but this code will most likely be slower than it could be due to various bits of allocation (boxing/unboxing/generating seqs)

21:03 mpan: I suppose I have my results, so I'll save my profiling for after the assignment deadline

21:03 any recommendations on which?

21:04 reducing the params a lot made it run in less time than the deadline

21:04 Sgeo: ,((fn [^String x] x) 5)

21:04 clojurebot: 5

21:04 hiredman: which profiler?

21:04 Sgeo: Uh

21:04 mpan: sure, or which such tool

21:04 Sgeo: ,((fn [^Int x] x) "Foo")

21:04 clojurebot: #<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: Int, compiling:(NO_SOURCE_PATH:0)>

21:04 emezeske: mpan: Are you sure that the different distance function doesn't affect how the algorithm runs, e.g. ultimately causing more work to be done?

21:04 hiredman: visualvm (or jvisualvm) works

21:04 Sgeo: ,((fn [^Integer x] x) "Foo")

21:04 clojurebot: "Foo"

21:05 Sgeo: Um.

21:05 Why is Clojure acting a little bit special here?

21:05 </offensive-comments>

21:05 mpan: emezeske: that's what I keep suspecting, except the design of the alg is that it only operates on the relative rankings of vals returned by the fitness fn

21:06 dnolen: Sgeo: type hints are only for optimization - not enforcement.

21:06 mpan: so very soon after I calc the fitness, I lose it, and I get back to my previous case of just some permutation of [1, n)

21:06 casion: they are called type hints, not type directives after all

21:06 hiredman: pt1 and pt2 seem to be 2 element vectors, and you'll be boxing and unboxing everytime you pull numbers out, do math, and put numbers back in

21:06 mpan: they are, and is there an alternative to that?

21:06 Sgeo: dnolen, but some things, such as choosing which function to use in certain cases, uses type hints

21:06 casion: hiredman: both functions will unbox the same though

21:07 hiredman: casion: sure

21:07 casion: I am speaking broadly about all the code

21:07 emezeske: mpan: Can you measure the number of e.g. iterations in some tight loop of the algorithm to rule that out?

21:07 dnolen: Sgeo: what cases are you thinking about?

21:08 mpan: I precalculate the #iterations, and it's the same calc for either objective

21:08 casion: mpan: try a manual abs and see what happens

21:08 I suspect it will be faster

21:09 mpan: the other one does have a sqrt, though

21:09 Sgeo: dnolen, um, hmm. I think with reify? I don't remember

21:09 hiredman: mpan: you can do something like (long (pt1 0)) which will make all your math go faster

21:09 mpan: hiredman: I'd lose my data that way though

21:09 casion: hiredman: sqrt is always cast to double anyway

21:09 hiredman: oh, these are doubles

21:09 well (double ...)

21:09 casion: it doesn't cast

21:09 casion: and for magnitudes over a certain size, Math/abs does some really weird shit

21:09 hiredman: yes, bad term

21:10 mpan: wait, they're already doubles?

21:10 dnolen: Sgeo: not true. In the case of reify / deftype / defrecord those aren't type hints - but marking protocols or JVM interface implementations.

21:10 mpan: what does calling explicit (double... ) change?

21:10 ZULTiNATOR: Clojure does not support multiple value continuations except packaging them in some container does it?

21:10 hiredman: mpan: yes, but putting (double ...) around it lets the compiler know the value you are getting out is a double

21:11 mpan: ah, the hinting?

21:12 hiredman: you may be able to do something with a custom type and protocol, I forget if you can hint a deftype's fields as primitives

21:12 mpan: I need to move the output data away and then I'll test this

21:13 hiredman: (defprotocol Doubles (^long a [_]) (^long b [_])) (deftype DoublePair [^long one ^long two] Doubles (a [_] one) (b [_] two))

21:14 using a vector-of :double would be nice, but I think accessing the value would still box

21:16 mpan: is this the type of case that warning on reflection solves? someone mentioned previously that was a part of achieving performance

21:16 casion: I'm testing it here and euclidian distance is running faster by about 33%

21:17 blergh

21:17 ugh, too late.

21:17 hiredman: mpan: no, it won't

21:17 casion: euc distance is slower by 33%

21:17 hiredman: for this case I doubt you would get any warnings

21:21 casion: mpan: in obj-min-horiz, do you need to use that 0.0?

21:22 mpan: casion: not sure, but the elements I'm reducing over are going to be double-valued

21:23 aib: is there a more beautiful syntax for multiple nested update-in statements to change multiple things at once?

21:23 casion: are the values in the pairs doubles already?

21:23 gfredericks: aib: I'd think -> could compose those nicely?

21:23 casion: if they're ints, you could reduce with 0, and wrap it with double

21:23 that would be significantly faster

21:24 mpan: they're definitely doubles

21:24 gfredericks: ,(-> {:a {:b 4} :c {:d 3}} (update-in [:a :b] inc) (update-in [:c :d] dec))

21:24 clojurebot: {:a {:b 5}, :c {:d 2}}

21:25 aib: ah, didn't know clojure had ->

21:26 what's it called?

21:26 gfredericks: threading macro I think

21:26 also see ->>

21:26 aperiodic: thread-first, as opposed to ->>, which is thread-last

21:26 gfredericks: I always pronounce them hrrng and mrrhoo

21:27 aperiodic: gfredericks: in hrrng, the stress is on the r, or the g?

21:27 aib: so it's practically the bind operation for the identity monad?

21:28 gfredericks: aib: well it's all syntactic

21:28 aperiodic: r definitely

21:31 mpan: on that topic, any particular resource you guys would recommend for learning what a monad is and how it is useful?

21:31 Hodapp: decisions, decisions... the input is basically a tree that needs to be transformed, and I'm pondering whether to just have the elements in this tree be functions to transform the tree

21:31 cark: http://www.haskell.org/haskellwiki/Monad_tutorials_timeline

21:32 Hodapp: or to just write something else to handle this and let the tree happily exist on its own

21:32 mpan: all right thanks for that

21:32 amalloy: mpan: i don't think it matters much which tutorials you read; you won't get it until you've spent months, reading one occasionally, and then the last one you read will suddenly make sense and you'll think it's great

21:32 mpan: and thank you guys for helping me with the weird performance issue

21:32 amalloy: I've been told I will eventually reach that point regarding continuations

21:32 hopefully sooner not later

21:34 amalloy: mpan: personally for me, those articles were http://cdsmith.wordpress.com/2012/04/18/why-do-monads-matter/ and to a lesser extent http://www.haskell.org/haskellwiki/Monads_as_Containers - but again, don't assume they'll be the ones that make sense to you

21:34 cgag: i think reading the articles in a hammock is supposed to speed it up

21:34 xeqi: I like http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html

21:38 $google monadic parser combinators

21:38 lazybot: [Monadic Parser Combinators - Nottingham ePrints - University of ...] http://eprints.nottingham.ac.uk/237/1/monparsing.pdf

21:39 xeqi: also my go to paper for showing how they might be useful ^

21:40 amalloy: parser combinators are pretty deep - i wouldn't start anywhere near there

21:40 mpan: the other side of the question I'm wondering is, how do other languages deal with the use-cases that some language might use monads for?

21:43 aib: mpan: extensive if checks for the Maybe monad seems to be a standard in C

21:44 xeqi: they don't have the same strongly typed + purely functional attributes as say haskell, so they don't have to. also the patterns monads can hide can seem normal, so alot of times they just don't try

21:46 I've heard Linq is similiar, but never done c#

21:48 Sgeo: $join ro_st Sorry, my explanation may have been inaccurate. join alone isn't sufficient, you also need fmap (think map) and still need return. I think.

21:48 lazybot: Sgeo: It is not the case that you don't not unhave insufficient privileges to do this.

21:49 Sgeo: $mail ro_st Sorry, my explanation may have been inaccurate. join alone isn't sufficient, you also need fmap (think map) and still need return. I think.

21:49 lazybot: Message saved.

21:57 aib: is there a shorthand for (fn [_] 42) ?

21:57 Sgeo: constantly

21:57 ,((constantly 42) "Hi there")

21:57 clojurebot: 42

21:57 Sgeo: ,(doc constantly)

21:57 clojurebot: "([x]); Returns a function that takes any number of arguments and returns x."

21:58 aib: nice, thanks

21:58 Sgeo: You're welcome

22:09 qubit[01]: sorry for the dumb question, whats the clojure package manager called ?

22:09 if i wanted to search for a clojure csv lib for example

22:11 also does anyway use counterclockwise with leinengen ?

22:11 Hodapp: I currently am, but I only have for a few days

22:12 xeqi: qubit[01]: if you are using lein, `lein search` might help; or visit clojars.org or search.maven.org

22:13 qubit[01]: clojars thats what I was looking for, does lein search clojars ? I couldnt find anything for csv stuff

22:13 winterfroststrom: whois winterfroststrom

22:14 xeqi: yes, though I'm not surprised about not finding anything, I'd just use one of the java libraries

22:17 Sgeo: I searched Maven, there's a Clojure thing

22:17 https://github.com/clojure/data.csv

22:18 "Reads CSV-data from input (String or java.io.Reader) into a lazy

22:18 sequence of vectors."

22:19 Uh, isn't it typically a bad idea to form lazy structures on the back of I/O?

22:19 Unless forcing it won't in fact cause I/O

22:22 biscarch: can anyone help me out with this monger/noir code?

22:22 https://www.refheap.com/paste/5152

22:22 seems to be a bson/json encoding issue

22:23 java.lang.Exception: Cannot generate { "_id" : { "$oid" : "4fa9b58da8c93381147a160a"}

22:25 qubit[01]: more stupid questions , following https://github.com/clojure/data.csv , I run lein deps, then lein run, I get Could not locate clojure/data/csv__init.class or clojure/data/csv.clj on classpath: , compiling:(foo.clj:1) -- what am I missing ?

22:26 biscarch, good to know youre working with mongo, thats my next step :)

22:26 Urthwhyte: Super generic question I'm sure you're sick of, but what's a good starting off point for web dev with Clojure?

22:26 xeqi: qubit[01]: whats your project.clj look like?

22:26 biscarch: Urthwhyte: I'm using noir

22:27 qubit[01]: xeqi, http://pastebin.com/f7zcPaZJ

22:27 xeqi, doh, I see it

22:27 biscarch: qubit: hah, I'll try to gain some experience for ya then ;)

22:27 xeqi: Urthwhyte: compojure or noir for routing, hiccup or stencil for templating

22:27 Urthwhyte: xeqi: Any preference one way or the other? I've seen more about noir

22:27 and more positive things, it seems!

22:28 xeqi: I prefer compojure, less magic

22:28 Urthwhyte: oh?

22:28 xeqi: or really.. less global variables and easier to use middleware; if your just starting noir will be fine for awhile

22:28 Urthwhyte: I thought compojure was more in the vein of Rails and Noir closer to sinatra?

22:29 I really haven't done much more than keep my eye on this channel though

22:29 xeqi: compojure is close to sinatra; noir is kinda inbetween. I think there was a project called conjure that was suppose to be rails like, but died

22:30 Sgeo: ,(Integer/parseInt "abc")

22:30 clojurebot: #<NumberFormatException java.lang.NumberFormatException: For input string: "abc">

22:30 Urthwhyte: OK, I'll check out noir and see how I get on

22:30 Cheers

22:30 Still have plenty of "Programming Clojure" to read through before I really dive in anyhow

22:34 and VimClojure works with terminal vim as well as MacVim/GVim, correct?

22:34 xeqi: I've seen it work through tmux

22:35 cgag: i've only ever tried to use it through terminal

22:35 Sgeo: Am I allowed to have more opinions about Monads?

22:36 cgag: just tried it with gvim and it seems to work fine

22:36 Sgeo: I don't think Maybe is actually that useful in Clojure. In a dynamically typed language, Either could easily fill that role, since if you don't want information about the error, you could just give a Left with nil

22:36 qubit[01]: Urthwhyte, is that the new clojure book ?

22:36 Urthwhyte: qubit[01]: yup

22:37 Figured I'd try the newest book I could find and then run through SICP

22:37 if I was still having trouble

22:37 * Khaz is reading Clojure Programming

22:37 Sgeo: SICP is written for Scheme

22:37 Urthwhyte: I'm aware

22:38 I've done it before, in Scheme. Problems are still easily done in Clojure

22:38 Sgeo: Ah

22:38 I really should get around to running through it at some pont

22:38 point

22:40 Urthwhyte: It's great :)

22:40 Highly recommended

22:41 biscarch: These autodocs are sweet

22:43 Khaz: contains? is just ...

22:44 xeqi: ~contains

22:44 clojurebot: contains is gotcha

22:44 xeqi: ~contains?

22:44 clojurebot: contains is gotcha

22:44 xeqi: hmm, I thought it had something to say about that

22:44 Khaz: and he said

22:44 it's a gotcha

22:45 Sgeo: ,(doc contains?)

22:45 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'."

22:45 Sgeo: Ah

22:45 Khaz: ,(contains? [:foo :bar] :foo)

22:45 clojurebot: false

22:46 Khaz: ,(contains? [:foo :bar] 0)

22:46 clojurebot: true

22:46 Khaz: :P

22:46 Sgeo: ,(doc fund)

22:46 clojurebot: No entiendo

22:46 Sgeo: ,(doc find)

22:46 clojurebot: "([map key]); Returns the map entry for key, or nil if key not present."

22:47 Sgeo: ,((comp not empty?) (filter #(= % :foo) [:foo :bar])

22:47 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

22:47 Sgeo: ,((comp not empty?) (filter #(= % :foo) [:foo :bar]))

22:47 clojurebot: true

22:47 Sgeo: ,((comp not empty?) (filter #(= % :baz) [:foo :bar]))

22:47 clojurebot: false

22:47 Sgeo: I'm sure there's an easier way

22:48 And I do know that compliment exists, I just didn't feel like using it

22:48 xeqi: &(some #{:foo} [:foo :bar])

22:48 lazybot: ⇒ :foo

22:48 xeqi: &(some #{:wha} [:foo :bar])

22:48 lazybot: ⇒ nil

22:48 Sgeo: ,(doc some)

22:48 clojurebot: "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"

22:48 Khaz: Sgeo: you mean an easier way to check if a coll is empty ?

22:49 Sgeo: An easier way to see if a collection contained an item

22:53 Khaz: ;(contains? (set [:foo :bar]) :bar)

22:53 tos9: Why does lein repl take so long to start up in a fresh dir without a project.clj or anything? I assume it's going out and downloading clojure, but can I get it to spew some progress info while it does so?

22:53 metellus: ,(contains? (set [:foo :bar]) :bar)

22:53 clojurebot: true

22:53 xeqi: tos9: how long is long?

22:54 Khaz: ,(contains? (set [:foo :bar]) :foo)

22:54 clojurebot: true

22:54 tos9: xeqi: user=> 4.74 real 5.37 user 0.90 sys

22:54 Khaz: ,(contains? (set [:foo :bar]) :qux)

22:54 clojurebot: false

22:54 Hodapp: hmm, perhaps I should not even be trying, but I'm seemingly unable to pair :as and :or in a function's argument list

22:57 xeqi: &(let [{:keys [a b c] :or {:a 0 :b 1} :as point} {}] [[a b c] point])

22:57 lazybot: ⇒ [[nil nil nil] {}]

22:57 amalloy: xeqi: :or {a 0 b 1}

22:58 xeqi: &(let [{:keys [a b c] :or {a 0 b 1} :as point} {}] [[a b c] point])

22:58 lazybot: ⇒ [[0 1 nil] {}]

22:58 xeqi: amalloy: thanks

22:58 Hodapp: ^ though notice the :or part does not end up in the :as part

22:58 need a merge for that

23:00 Hodapp: I was trying to accomplish something along the lines of default values for what goes into the symbol which :as points to

23:01 I suppose 'merge' is of great use there

23:01 xeqi: &(let [{:keys [a b c] :as point} (merge {:a 0 :b 1} {:a 3}) ] [[a b c] point])

23:01 lazybot: ⇒ [[3 1 nil] {:a 3, :b 1}]

23:44 loliveira: how do I do Integer.class in clojure?

23:48 tomoj: dnolen`: think we can do locals clearing in cljs?

23:49 loliveira: use it?

23:49 you mean, refer to it?

23:50 &(class Integer)

23:50 lazybot: ⇒ java.lang.Class

23:53 loliveira: tomoj: yes. i'd like to call the following restfb function: facebookClient.fetchConnection("me/friends", User.class)

23:54 the 2nd parameter is generic

23:54 i'm getting: java.lang.IllegalArgumentException: No matching method found: fetchConnection for class com.restfb.DefaultFacebookClient

23:55 but fetchConnection exists.

23:55 http://restfb.com/javadoc/com/restfb/FacebookClient.html

23:57 that is the way i'm trying to call it: (.fetchConnection fb "boobs" (class Post))

Logging service provided by n01se.net