#clojure log - May 02 2011

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

1:26 amalloy: raek: i think i'm a sinner. i've written (map #(update-in % [0] some-fn) (map first coll)) and i think it looks clearer than the equivalent for-expr

1:29 which, for those keeping score at home, is: (for [[[x & xs]] coll] (vec (cons (some-fn x) xs)))

1:57 technomancy: ping?

4:26 Ian_Corne: Anyone know why clojure stuck on 1.1 in the ubuntu archives?

4:33 fliebel: Can I use a project with only a pom.xml with leiningen?

4:34 raek: Ian_Corne: in the most widely used ways of doing development (using a tool like lein, cake or maven) you fetch required jars (inlcuding clojure) from maven repos, so the system packages are not used at all.

4:35 Ian_Corne: I also think that this ubuntu package predates Leiningen itself (the first build tool specifically for clojure)

4:35 Ian_Corne: ok

4:38 I guess the plugin for eclipse just works like it should?

4:41 fliebel: ah, mvn clojure:repl

4:59 thorwil: (models/slugs) on the repl delivers stuff like ("foo" "bar" )

4:59 i need to turn that into a string with quoted names and , inbetween (to be read as JS array later on)

5:00 this works: (interleave (map #(str \" % \") (models/slugs)) (repeat \,))

5:00 but is there a simpler way?

5:02 almost works, that is. need to get rid of a trailing comma

5:12 (butlast (mapcat #(str \" % "\",") (models/slugs)))

5:12 raek: thorwil: why nod use a json library?

5:12 *not

5:13 then you get proper escaping inside strings too

5:14 thorwil: raek: i'm uneasy about introducing 2 new things at once. also seems overkill for this

5:18 raek: thorwil: use interpose

5:19 ,(apply str (interpose \, (map #(str \" % \") ["foo" "bar"])))

5:19 clojurebot: "\"foo\",\"bar\""

5:21 raek: thorwil: if you can prove that the strings will never contain characters that need to be escaped or non-ascii characters, then I guess rolling your own is fine

5:22 always assume that users will enter any possible characters :-)

5:23 thorwil: the content are url slugs, guaranteed to contain nothing more fancy than - or _ :)

5:53 fliebel: $mail dnolen How is it possible that in Logos… core.logic adding a relation produces more results? http://paste.pocoo.org/show/381488/

5:53 sexpbot: Message saved.

6:16 lukaszek: hi guys, what open source web app do you suggest to look into the code for person who is learning clojure. you know - just to get idea how clojure should be used for web apps?

6:21 thorwil: lukaszek: have a look at http://cleancode.se/2011/01/04/getting-started-with-moustache-and-enlive.html

6:22 lukaszek: thorwil: thx

6:26 thorwil: lukaszek: enlive is great in allowing you to work with plain html templates with no special syntax or marks in them at all. but if you prefer to generate html, look athttps://github.com/weavejester/hiccup

6:29 lukaszek: and this, linked from the Moustache site should also be enlightening: https://gist.github.com/109955

7:00 fortxun: $seen rhickey

7:00 sexpbot: rhickey was last seen quitting 2 days and 15 hours ago.

7:33 fliebel: Does anyone know of a clean and idiomatic selection sort in Clojure?

8:04 mec: is there a way to extend protocols on array types

8:46 gfrlog: is there a standard way that clojure projects handle environmental configuration, like database connections and such?

8:54 chouser: mec: yes, you just need to pass in the appropriate kind of Class object to defprotocol

8:56 mec: like: (extend-protocol my-proto (class (long-array nil)) (my-method [x] ...))

8:57 mec: chouser: any way for all array types at once?

8:58 chouser: they don't have a common base class that uniquely identifies them as arrays

8:59 mec: I was afraid of that

8:59 chouser: but there are only a handful of array types. primitives and Object

8:59 gfrlog: nested arrays?

9:00 chouser: Objects

9:00 gfrlog: good.

9:00 chouser: hm

9:00 wait, maybe not

9:01 gfrlog: bad.

9:05 chouser: nope, I was totally wrong

9:06 An array knows the type of thing (primitive or Object-subtype) that it holds, and its dimentions.

9:06 There appears to be no inheritence relationships between any of them

9:07 so no way I can see to extend a protocol to all arrays regardless of their actual type

9:34 gfrlog: $findfn "thomas" #"thomas"

9:34 sexpbot: []

9:34 gfrlog: $findfn "thomas" #"^thomas$"

9:34 sexpbot: []

9:37 gfrlog: $findfn "bad sexpbot" "bad sexpbot"

9:37 sexpbot: [clojure.string/trim clojure.string/lower-case clojure.string/join clojure.string/trimr clojure.string/triml clojure.string/trim-newline clojure.set/union clojure.set/intersection clojure.set/difference clojure.core/format clojure.core/time clojure.core/dosync clojur... http://gist.github.com/951621

9:37 gfrlog: man clojure has a lot of functions that do that

9:39 manutter: ,(re-pattern "thomas")

9:39 clojurebot: #"thomas"

9:39 gfrlog: sexpbot: you've got some explaining to do

9:39 manutter: thanks

9:40 manutter: :)

9:40 gfrlog: $findfn #"thomas" "#\"thomas\""

9:40 sexpbot: [clojure.core/print-str clojure.core/pr-str]

9:41 gfrlog: oh hmm: ##(re-pattern "..")

9:41 sexpbot: ⟹ #".."

9:41 gfrlog: $findfn ".." #"\.\."

9:41 sexpbot: []

9:44 gfrlog: ,(re-pattern (java.util.regex.Pattern/quote ".."))

9:44 clojurebot: #"\Q..\E"

9:50 gfrlog: $findfn {:foo "bar"} :foo "bar"

9:50 sexpbot: [clojure.core/deliver clojure.core/->> clojure.core/-> clojure.core/get clojure.core/trampoline]

9:52 manutter: ,(doc escape)

9:52 clojurebot: Gabh mo leithscéal?

9:52 gfrlog: manutter: escape?

9:52 manutter: hmm

9:53 ,(doc clojure.string/escape)

9:53 clojurebot: "([s cmap]); Return a new string, using cmap to escape each character ch from s as follows: If (cmap ch) is nil, append ch to the new string. If (cmap ch) is non-nil, append (str (cmap ch)) instead."

9:53 manutter: http://clojuredocs.org/

9:54 gfrlog: manutter: you're suggesting that to use instead of java.util.regex.Pattern/quote?

9:54 manutter: just playing around

9:55 gfrlog: kay

9:55 manutter: quote will work too

9:55 gfrlog: ,(clojure.string/escape "prison")

9:55 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (1) passed to: string$escape

9:55 manutter: "Curses, Pinky, we'll have to try another plot."

10:12 dnolen: mec: chouser: re, arrays. You learn something new everyday. mec, thought, I suppose one work around is to change seqable? to seqable?*, and make a plain seqable? fn that calls that. wrap in try/catch, if catch something which does not extend ISeqable, extend the type of newly encountered array type to ISeqable and try again. it'll be slow only the very first time a unknown array type is encountered.

10:15 fliebel: if sorto uses conde you're going to see more results.

10:17 chouser: Well, there is (Class/isArray ...)

10:18 fliebel: dnolen: :-\ But, these results would not uninfy with the results of permutationo, would they?

10:18 chouser: I suppose you could extend your protocol to Object and check isArray there. Perhaps then extending to that particular type as dnolen was suggesting?

10:20 fliebel: Or, they do obviously...

10:35 whidden__: What's the canonical way to test for non nil?

10:37 ejackson: whidden__: if ?

10:38 whidden__: hmmm, i think i out thought myself. thanks

10:38 ejackson: or nil?

10:38 that will reject false too

10:39 whidden__: no, (if foo) is what i needed.

10:47 milkpost: so is there a way to speed this up by typing this in a way that doesn't box the integers in range?

10:49 https://gist.github.com/950827

10:50 whoops lol

10:52 gfrlog: googling for "clojure parse html" has not been exciting thus far...

10:53 manutter: gfrlog: can you use xml processing? or is it the wrong kind of html for that?

10:53 milkpost: so basically in clojure, if I have a range, an integer is going to get boxed as an Integer type? It seems weird that a simple filter would be so much slower than a java "for (...) { if (..) ...}" call

10:53 gfrlog: it's output from compojure. But clojure.xml/parse won't take it

10:54 manutter: hrm, hrm, that's surprising

10:54 gfrlog: yeah, I was surprised

10:55 trying to figure out if Enlive does something like that

10:55 have not used enlive before

10:55 manutter: It's got a bit of a learning curve, but I think it's worth learning

10:55 I'm doing trivial stuff with it right now, hope to build it up some soon

10:55 Kerris: just like Clojure ;-)

10:56 raek: gfrlog: html-resource in enlive outputs a tree of the same format as clojure.xml/parse

10:56 manutter: Might not help in your case though, I think it's using xml/parse under the hood

10:57 gfrlog: we'll find out shortly

10:57 manutter: compojure output *should* parse, maybe you'd be better off figuring out that angle?

10:58 gfrlog: oh wait

10:58 raek: enlive uses tagsoup under the hood. you can use tagsoup with clojure.xml directly: https://github.com/raek/klouzher/blob/master/src/se/raek/html.clj

10:58 gfrlog: ^

10:59 gfrlog: I think I may have only tried it on the clojure documentation page, actually. My goal is to use it on compojure output :)

10:59 important distinction

11:00 raek: thanks. I might be able to make further use of enlive though

11:00 raek: a web page will only work though clojure.xml/parse if it is error-free xhtml

11:00 gfrlog: right. We were thinking that compojure output oughta be error-free

11:01 and I've now confirmed that the compojure output does NOT parse

11:01 java.net.MalformedURLException: no protocol:

11:03 looks like compojure doesn't handle the voodoo-header tags automatically

11:03 manutter: voodoo-header tags?

11:03 gfrlog: all that stuff that goes before <html>

11:03 ,(clojure.xml/parse "<html><head></head><body></body></html>")

11:03 clojurebot: java.security.AccessControlException: access denied (java.io.FilePermission /<html><head></head><body></body></html> read)

11:04 gfrlog: huh

11:04 * gfrlog is slowly dawned on that maybe he's using clojure.xml/parse totally wrong

11:04 gfrlog: k I'm a dummy

11:05 pardon my noise

11:05 manutter: np :)

11:05 raek: gfrlog: to parse a web page given its URL: https://github.com/raek/lcug-examples/blob/master/bot/src/se/raek/lcug/titlebot.clj#L9

11:06 gfrlog: raek: I have an html string. So I'm gonna ramble through some of the IO namespaces to figure out how to get an input stream from a string

11:07 raek: ,(java.io.StringReader "foo")

11:07 clojurebot: java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn

11:07 raek: ,(java.io.StringReader. "foo")

11:07 clojurebot: #<StringReader java.io.StringReader@18d303>

11:07 raek: gfrlog: ^

11:07 gfrlog: raek: yessir :) thanks

11:07 raek: I don't think there's a convenience function for that in clojure.java.io

11:07 gfrlog: then you have saved me some time indeed

11:10 raek: gfrlog: also check out html-snippet

11:11 gfrlog: oh that just made everything better

11:11 raek: it reads html from a string (but is made for the case when the string represents a snippet *inside* a html document, so it doesn't add html and body if those are missing)

11:12 so to parse complete pages, (-> content-as-a-string java.io.StringReader. html-resource) might still be preferred

11:14 gfrlog: hmmm. I'm fine with the snippet output. But I'll try that there too.

11:23 dnolen: fliebel: sorry had to run earlier what do you mean?

11:30 fliebel: dnolen: Well, if the first statement returns all valid values, how can an additional statement add values to that without failing?

11:34 dnolen: fliebel: first statement returns all valid values, and then the next statement operates on those values, generating more values.

11:36 fliebel: hm… okay. I expected that because q is bound to any of these initial values, anything in the second run that is not in the first would be a failure,

11:37 dnolen: So first I bind q tp [1 2 3 4], and later I bind it to [1] and that works?

11:37 dnolen: fliebel: a link to what this code will look like?

11:38 fliebel: dnolen: http://paste.pocoo.org/show/381601/

11:39 dnolen: I'm having a hard time playing with logos now that it's core.unify, mainly because it no longer uses lein. ANd, since hen did you start dropping the hyphens in conde?

11:40 dnolen: fliebel: it's pushed to clojars.

11:41 fliebel: I changed the hyphens bit a while back, that was a hold over from following jim duey's style, I decided to stick the actual miniKanren style.

11:41 fliebel: oh, I thought contrib projects where built on the clojure server.

11:42 dnolen: fliebel: they are, but a lot of people use lein, so I have a private project.clj branch that I use to keep clojars versions in sync.

11:43 fliebel: it's not clear to what I should be looking for in that paste.

11:43 raek: http://repo2.maven.org/maven2/org/clojure/ <-- strange that core.unify isn't here

11:44 dnolen: raek: I think they just have gotten around to setting up the hudson build process for core.logic.

11:44 haven't I mean.

11:46 fliebel: dnolen: Well, permutationo generates all permutations for a seq, and sorto basically says that every item is more or equal to the previous item.

11:47 dnolen: fliebel: but it's not clear to me what the question is.

11:47 fliebel: all those relations use conde, so stringing them together will always generate more results.

11:48 fliebel: hm…

11:54 dnolen: (run* [q] (conde ((== [1 2 3] q)) ((== [3 2 1] q))) (conde ((== [1] q)) ((== [2] q)))) ; ()

11:54 dnolen: fliebel: because [1 2 3] can never unify with [1] or [2], same for [3 2 1]

11:55 fliebel: that program expresses 4 failures.

11:55 fliebel: dnolen: Yes, so that is what I think I was doing with my code. But apparently I'm doing something different there?

11:56 dnolen: fliebel: you have to be careful with conso

11:57 fliebel: sorry looking more closely at your code, even if (== s [f]) fails, because it's a conde, it will try the other clause.

11:58 if the moment it fails you want to stop searching, you need to use conda.

11:58 fliebel: true...

11:58 :)

12:02 dnolen: uhm, that got me *only* single results. I'm going back to the drawing board :)

12:03 dnolen: fliebel: heh, what exactly is that supposed to do? give only the sorted permutations?

12:04 fliebel: dnolen: Yea, I was trying to see if Logos can sort, just for fun :)

12:04 dnolen: fliebel: well I don't want to spoil your fun, but it would be trivial to transliterate an existing Prolog quicksort to core.logic.

12:04 fliebel: dnolen: But I'm having more fun now writing lazy sorts, thanks to ejackson.

12:05 dnolen: I had no idea prolog actually did that. I'm googling now...

12:05 dnolen: fliebel: http://www.cp.eng.chula.ac.th/~piak/teaching/dsys/quick-prolog.htm

12:06 fliebel: and I would use defne to keep it as short as the Prolog version.

12:07 fliebel: dnolen: I will try, but I havn't much experience with that one.

12:07 dnolen: fliebel: on the core.logic landing page I should how to go from Prolog append to core.logic appendo, that should make it clear.

12:08 fliebel: dnolen: I'll have a look.

12:10 ejackson: fliebel: I'm sure I warned you off tumbling down rabbit holes :)

12:11 fliebel: ejackson: You did :) This is cmpletely my own fault.

12:12 Kerris: dnolen: that is nice code

12:14 fliebel: In Dutch we have a saying that says one will not walk in seven ditches at the same time. Apparently one can tumble down 7 rabbit holes in parallel.

12:14 dnolen: Kerris: the Prolog?

12:14 Kerris: dnolen: oh yes

12:15 dnolen: Kerris: yeah, Prolog is neato.

12:15 fliebel: Kerris: Check this one: http://boss-level.com/?p=92

12:15 Kerris: Prolog is something I've always wanted to grok. I kinda "get" ML family languages, Lisp/Scheme less so, but Prolog is just utterly alien.

12:16 Alien but familiar. Which makes it more alien, somehow.

12:18 dnolen: Kerris: spending some time on Prolog is certainly worthwhile. operations on data structures w/o binding to concrete values is eye-opening.

12:18 ejackson: dnolen: what support is there is Logos for numerical relations. For instance finding all instances in a seq of numbers where there say n consequetively increasing numbers. I remember discussing the treatment in TRS with you before, is that current ?

12:18 dnolen: ejackson: the arithmetic stuff in TRS is mostly interesting as thought experiment, I didn't include any of that stuff because it's not really useful.

12:19 ejackson: in Prolog, arithmetic is not relational, it's also not relational in core.logic.

12:21 ejackson: dnolen: ok, but can you define such statements in core.logic ?

12:22 dnolen: ejackson: yeah you could definitely implement the TRS arithmetic stuff, and in a lot less code now that it has pattern matching via defne and matche.

12:23 fliebel: dnolen: I noticed you made < and > and such, but not actual arithmetic. Why? I also thing you could use a template for these functions, since the only varying part is the fn used.

12:24 ejackson: hmm.... I'm in agreement that the TRS arithmetic is a bit nutty, I gave up before going any further though

12:24 dnolen: fliebel: because < > etc are relations we can check, with + = etc you need some notion of var creation and assignment, I would have to write a macro to handle the transformation.

12:24 fliebel: I'd be willing to take a patch of course, but project handles arithmetic and many other cases.

12:26 fliebel: I see…

12:36 dnolen: ejackson: what the TRS arithmetic stuff is good for is understanding how to write very complex relations in a purely declarative way, some insightful stuff that can be applied elsewhere. some other good examples in Byrd's dissertation.

12:37 ejackson: dnolen: yes, I took it to be good mental gymnastics.

12:38 fliebel: quicksort has a really bad worst case for sorted stuff, or is it just my implementation?

12:40 Hun`: fliebel: depends on how you choose your pivot

12:40 randomized quicksort works quite nice. introsort, too

12:40 fliebel: Hun`: Just the first item, so… yea.

12:42 amalloy: fliebel: yeah, don't use the first element

13:46 technomancy: ataggart: any plans to extend the Log protocol to changing levels?

13:47 ataggart: not until someone suggests a good way of doing it. "changing the level" is more complex than one might think.

13:47 technomancy: ataggart: it can't be supported across all the backends?

13:48 we've got something that seems to work fine with log4j

13:48 ataggart: that's one issue. most java logging apis are meant to be configured, and not used in an interactive way.

13:48 the deeper issue is what it means to change the level

13:48 for example, what you have working with log4j

13:49 what happens to the subordinate namespaces?

13:49 TimMc: ataggart: I want to use command line arguments to my program to specify what logging level is to be used. Is that interactive?

13:49 technomancy: well hierarchy in namespaces is mostly an illusion; I wouldn't expect it to have an effect.

13:49 ataggart: TimMc: ah no, I'd say that's configuration. You just need to do whatever the underlying logging lib requires

13:50 TimMc: I ended up writing my own logger. :-/

13:50 ataggart: technomancy: illusion or not, the question is what one expects to happen. Further, which logging output should be affected when changing the level?

13:50 some systems, e.g. j.u.logging, support multiple outlets, each with possibly a separately configurable level

13:51 as for log4j, the inheritance is automatic, unless a subordinate package has its own configuration, then a runtime change wouyldn't apply

13:51 it's messy

13:51 but as Rich likes to say, "patches welcome"

13:51 technomancy: gotcha

13:52 well we can continue using our one-off if that's the case; just wanted to get your take on it.

13:53 are there actual features in slf4j or commons-logging that make people choose it over log4j, or is it mostly just "we'll use this because some other component in our stack needs it"?

13:53 ataggart: Since mechanism and meaning behind setting the level is necessarily tightly coupled with the underlying implementation, a one-off is probably best

13:53 technomancy: good to know

13:54 ataggart: technomancy: as for other impls, I think commons-logging was intended for library authors who wouldn't know what logging a consuming app was using, nor wanted to prescribe one.

13:55 sl4j is a rewrite of log4j by the same guy, iirc

13:56 TimMc: have you plugged your logger into c.c.logging?

13:57 technomamcy: what's the context of your set-level usage?

13:57 just repl output?

13:57 technomancy: ataggart: no, it's a long-running server that gets jobs off rabbit queues

13:58 sometimes you want to debug without pulling out ye olde cdt. =)

13:58 raek: technomancy: btw, has (read-line) always worked in lein repl, or is this something new?

13:58 technomancy: raek: it works when ant is not involved. standalone repls run in the same process as leiningen, so no subprocess is started.

14:00 ataggart: technomancy: does your one off do anything more than call .setLevel on the current Logger instance?

14:00 raek: technomancy: standalone = outside project?

14:01 technomancy: ataggart: I don't think so

14:01 raek: ya

14:01 raek: ...but it works for me in a project lein repl :/

14:02 technomancy: raek: oh, I see... yeah, because *in* is rebound

14:02 it won't work from a thread or future because the root of *in* is useless

14:05 basically, this ant bug means "lein repl" has to set up a socket-repl (and client), which is a neat feature, but should be totally unnecessary for simple usage.

14:07 afekz: wow lotsa people

14:07 is there a FAQ for #clojure the channel?

14:09 technomancy: clojurebot: contains?

14:10 clojurebot: contains? is for checking whether a collection has a value for a given key. If you want to find out whether a value exists in a Collection (in linear time!), use clojure.core/some or the java method .contains

14:11 technomancy: ^ that's the most frequently-asked question in here.

14:11 afekz: I've got a scenario where I know I'm missing something. I'm trying to launch to fn's in parallel, each of which runs remote TCP queries against a web service and then stores the results in a SQL db.

14:11 amalloy: haha

14:11 technomancy: pcalls?

14:11 afekz: I've tried pcalls, but unless I println the results of the pcall, the SQL doesn't actually execute (no new records in DB)

14:12 technomancy: amalloy: anyone who masters contains? is in the top bracket of Clojure newbies!

14:12 afekz: if I println the results of the pcall, then it blocks as it forces the resolution.

14:12 amalloy: technomancy: i used contains? the other day. turned out i didn't want it, but i didn't want some either

14:12 fliebel: afekz: doall/drun?

14:12 afekz: I'm guessing (real guess here, I'm no expert) that there's some laziness interaction

14:12 fliebel: I'll check with dorun - think I've tried doall

14:13 amalloy: i really wanted to give update-in a function that handled nil the way i wanted :P

14:13 fliebel: afekz: Same thing, except it just throws away the result.

14:13 mec: How can RT call ArraySeq/createFromObject if it is not public?

14:13 technomancy: hmm... yeah, that would be something like pdoseq that doesn't block on the long-runningest. I don't think it's in core.

14:13 afekz: fliebel: *nod* I'm flailing :)

14:14 amalloy: mec: they're in the same package

14:14 ataggart: ,(doc fnil)

14:14 clojurebot: "([f x] [f x y] [f x y z]); Takes a function f, and returns a function that calls f, replacing a nil first argument to f with the supplied value x. Higher arity versions can replace arguments in the second and third positions (y, z). Note that the function f can take any number of arguments, not just the one(s) being nil-patched."

14:14 ataggart: amalloy: ^

14:14 amalloy: ataggart: yeah yeah, i know

14:14 ataggart: heh

14:14 raek: afekz: it is probably cause by a 'map' or 'for' expression. consider replacing thos with 'doseq' instead (which has the same syntax as 'for')

14:14 amalloy: it was a 4clojure problem to reimplement merge-with

14:15 fliebel: amalloy: reimplement merge-with? wow, the problems I looked at where more like _ + 1 = 2

14:15 ataggart: mec: absence of a visibility keyword defaults to package-private

14:15 amalloy: fliebel: you didn't get far enough

14:16 ataggart: mec: so anything in the same package can call it

14:16 * fliebel needs to look again.

14:16 amalloy: we have offerings for everyone, fliebel!

14:17 try sorting by #solved and picking the lowest number

14:17 fliebel: amalloy: Can you throw me a link of something complicated?

14:17 Oh, I'll try

14:18 amalloy: https://www.4clojure.com/problem/53

14:18 also the most recent one, https://www.4clojure.com/problem/73

14:18 fliebel: amalloy: Who writes these problems?

14:19 amalloy: fliebel: mostly dbyrne, a few from me, a few user-contributed

14:19 fliebel: amalloy: Are there hidden tests, or can everything be solved with a big cond clause?

14:19 amalloy: cond is cool if you don't mind being lame. didn't i respond to your tweet about that?

14:20 fliebel: I don;t think so… anyway, that is lame indeed, but with hidden checks, you could prevent that.

14:20 amalloy: we had hidden tests, but they confused genuine users, and we don't really care if you want to skip all the fun by "cheating"

14:20 fliebel: okay

14:21 amalloy: fliebel: https://twitter.com/#!/alanmalloy/status/62229881773232129

14:21 fliebel: amalloy: Oh, must have missed that. *blames his Twitter client*

14:21 amalloy: *chuckle*

14:22 we're working on a way for experienced users to submit problems without having to fork the GH repo, which should speed things up for us

14:23 fliebel: amalloy: Sorting does not look right at all. This are more or less ordered, but… not really.

14:23 amalloy: yep. it's kinda a mess for sure

14:23 fliebel: amalloy: Oh, it's an ui thing btw, I was clicking the tags box :P

14:24 amalloy: they're in insertion order by default. feel free to fork and work on https://github.com/dbyrne/4clojure/issues/59 :P

14:24 fliebel: amalloy: haha, nooo, not another rabbit hole :P

14:27 amalloy: fliebel: c'mon, if you finish that issue we'll let you post "write a good implementation of seque and email it to fliebel" as a problem

14:28 fliebel: amalloy: have you seen my most recent one? But, I admit it's… oh, lost a word. enticing?

14:28 clojurebot: excusez-moi

14:28 amalloy: enticing sounds fine. appealing?

14:29 fliebel: amalloy: Is use of sockets allowed in 4clojure? Otherwise it'd be hard to send the email.

14:29 amalloy: haha

14:31 fliebel: Anyway, I'll add a kludgy chat-history mark, so I can keep you to your promise and find the issue later: ****

14:35 amalloy: Oh, and if you're interested, I made something that goes well together with your fold-the-other-way I call treeduce or fold-middle, which is like a balanced binary tree version of reduce. line 36 https://gist.github.com/951553

14:36 amalloy: fliebel: (fn [[x y]] (f x y)) is (partial apply f)

14:36 unless you want to grab exactly the first two items from a longer list, i suppose

14:37 fliebel: amalloy: the difference is how you handle and odd list.

14:37 #(partition-all 2 [1 2 3])

14:37 &(partition-all 2 [1 2 3])

14:37 sexpbot: ⟹ ((1 2) (3))

14:37 amalloy: so you're just passing nil as the last param

14:38 &(partition 2 2 [nil] [1 2 3])

14:38 sexpbot: ⟹ ((1 2) (3 nil))

14:38 fliebel: so either you have a multi-arrity fn, or you nill-patch it.

14:39 amalloy: i think the "add nil at the end" behavior is clearer if you use [nil] as a pad collection for the partition, rather than implicitly turn [[x]] into [[x nil]] with destructuring

14:40 fliebel: true

14:40 afekz: ADSL problems. Meh. fliebel: dorun neither. Why on earth would the SQL get executed (records get created) if the result of pcalls was passed to println, but not if dorun/doall? peculiar!

14:40 Confuses me sufficiently, not that I'd consider that too difficult in the circumstances.

14:41 amalloy: afekz: println is recursive. dorun applies only to the top-level seq

14:41 &(dorun (repeat 1 (repeatedly #(println 3))))

14:41 sexpbot: ⟹ nil

14:41 afekz: amalloy: thanks - I'll go sort which of the lower level seq's need to have dorun applied.

14:41 amalloy: &(repeat 1 (repeatedly #(println 3)))

14:42 haha oops

14:42 &(repeat 1 (repeatedly 1 #(println 3)))

14:42 sexpbot: ⟹ ((3nil))

14:42 Execution Timed Out!

14:46 amalloy: afekz: i had to force nested side-effects at some point and found (postwalk-replace identity coll) worked, though obviously it's slow

14:47 afekz: amalloy: ta - another possibility, for sure.

15:37 fortxun: $seen rhickey

15:37 sexpbot: rhickey was last seen quitting 3 days ago.

15:40 afekz: amalloy: thanks for that - seems to have solved my problems just fine

15:41 I still don't understand what the issue was, though, as basically if I used println, it'd lag and take around 12s(!) to do something that should've taken +-150ms.

16:36 amalloy: technomancy: i assume it's an eventual goal of yours to allow slamhound to handle :require/:as where the :as doesn't match the last namespace segment?

16:47 technomancy: amalloy: I don't really care either way

16:47 I prefer code where :as matches; I think it's more readable

16:47 but I understand that may be impractical in some situations

16:48 amalloy: technomancy: i dunno, i like to (:require [clojure.string :as s])

16:48 and (require [sandbar.stateful-session :as session]) seems reasonable too

16:48 the code i'd want to look at to add this is in search, i suppose?

16:49 technomancy: the problem is the compiler doesn't always give you the var

16:49 sometimes you just get "no such namespace s"... not a lot you can do with that

16:50 hiredman: need a pluggable compiler

16:50 technomancy: I guess you could look for all substring matches, but that's going to be pretty intense for something like s

16:50 amalloy: technomancy: you keep the old ns-map around already

16:50 if it has require/as pairs you can make a note of it before you get started

16:51 technomancy: amalloy: that's true; if that's supported by fallback-only then that's good enough.

16:51 even if a full search is impractical

18:12 semperos: using incanter with mongodb

18:12 I have a dataset with 800,000+ rows

18:13 when I use incanter.mongodb/fetch-dataset, it only gets two of the rows into the dataset

18:13 using congomongo's fetch fn directly, it pulls all the rows

18:13 so somewhere in this source, I'm missing something: https://github.com/liebke/incanter/blob/077cde547363afe675fd8400de11dda0a4b47952/modules/incanter-mongodb/src/incanter/mongodb.clj#L72

18:13 any thoughts anyone?

18:16 per usual, my own stupidity

18:16 strike question

18:16 Derander: semperos: what was up?

18:17 (just curious)

18:17 semperos: well, may still be an issue

18:17 but I was doing (count) on an incanter dataset, instead of (dim) to get it's dimensions

18:18 for some reason, when I used did (def foo (fetch-dataset :my-data)), and viewed that, I only saw a small portion of my dataset

19:16 carllerche: is there any way to get `lein test` to output the tests being run as they are run?

19:17 zrilak: strace *runs and hides*

19:17 please ignore, that was my cat running across the keyboard.

19:17 technomancy: carllerche: each individual deftest rather than the namespace you mean?

19:18 carllerche: technomancy: yes

19:18 technomancy: carllerche: I played around with a hack to output a . for every passing assertion, but you kinda have to monkeypatch clojure.test's guts

19:18 carllerche: right now, i'm doing a println w/ the name of the test at the top of each deftest :P

19:18 technomancy: there's already too much monkeypatching going on there for test selectors, so I dropped it

19:26 Somelauw: Hey, I suddenly realized I don't need transients, since I can make a vector of atoms.

19:27 mec: that sounds fishy

19:27 technomancy: atoms are meant for a substantially different purpose from transients

19:27 amalloy: mec: it sounds like the four horsemen of apocalypse bearing down on me, personally

19:28 mec: lol

19:30 amalloy: seriously atoms will give you all the pain of mutable state with none of the efficiency improvements that transients give you. don't do it

19:44 Somelauw: I would expect them to be just as efficient as transients, but I am not sure.

19:49 technomancy: clojurebot: transients?

19:49 clojurebot: http://clojure.org/transients

19:50 technomancy: clojurebot: transients are not mutable data structures: http://technomancy.us/132

19:50 clojurebot: http://clojure.org/transients

19:51 technomancy: clojurebot: transients |are| not mutable data structures: http://technomancy.us/132 or at least as far as you're concerned.

19:51 clojurebot: Ik begrijp

19:59 Somelauw: jij begrijp?

20:03 Hmm, that article explains how to use persistance.

20:03 But not how it works.

20:04 I still think a persistent vector is the same as a vector of atoms.

20:04 That gets frozen after a while.

20:04 amalloy: Somelauw: you are entitled to think anything you like, of course

20:07 Somelauw: On the inside.

20:08 hiredman: I am equally entitled to /ignore your nonsense

20:09 Somelauw: I am not trolling. I am just curious about is inner workings.

20:11 anyway, I give up

20:13 mec: The inner workings of a persistent or transient data structure?

20:14 zrilak: if you're an experienced developer learning about Clojure, this should prove to be an excellent source of information https://github.com/richhickey/clojure

20:14 brehaut: zrilak: not the richhickey repo, use the clojure one

20:14 http://github.com/clojure/clojure/

20:15 zrilak: ah, so I was looking at Rich's personal dev branch?

20:15 thanks

20:15 brehaut: nah, you were looking at the old repo

20:15 zrilak: gotcha -- thanks

20:15 brehaut: from before github had organisations

20:28 zrilak: There is no shorter way to declare two or more different-arity methods in a protocol other than listing their signatures, e.g. (defprotocol X (foo [_] [_ one] [_ one two])) -- correct?

20:29 pardon the abuse of terminology

20:29 scgilardi: corect

20:29 :) correct

20:29 zrilak: :)

20:31 amalloy: zrilak: is this conceptually a single thing with default parameters? if so, consider only defining (defprotocol X (foo [_ one two])) and then writing a library wrapper function that operates on any X and supplies default parameters

20:32 zrilak: amalloy: that is *exactly* the thing I was after, thanks!

20:32 or at least a part of it

20:33 amalloy: protocols are, by design, not friendly to treat as user-facing functions. they're minimal bits of functionality, which you're intended to write a library to make conveninent

20:57 zrilak: I put it in a pastie; I don't expect anyone to be idle enough to actually read it through, but if someone does, I would really appreciate any and all leads as to what design misconceptions I am falling prey to http://pastie.org/1858764

20:58 hiredman: no reason for make-power to be a macro

20:59 amalloy: oh hey, i played race for the galaxy a couple times

20:59 hiredman: looks like you are destructuring in the args list of a method implemented in a reify, which you can't do

21:00 amalloy: hiredman: but if he wants to destructure them in a let (which presumably he does), then it needs to be a macro, no?

21:00 zrilak: that sounds reasonable, I did have problems with that

21:00 here's a formatted version: http://pastie.org/1858773

21:01 I just quickly ran some speed tests of using defprotocol/reify vs. plain defn, and reified version was quicker btw.

21:01 I guess that's to be expected

21:01 because of method lookup

21:01 amalloy: zrilak: yeah, things that don't work can do so arbitrarily quickly

21:01 zrilak: hahah

21:02 so make-power needn't be a macro, I can just (defn return a reified protocol), is what you're saying, right?

21:02 my main gripe with this is that I want to act on an effect like so

21:03 (act some-effect state power card)

21:03 at all times

21:03 but I want to be able to define powers as taking [state], [state player] or [state player card], as some powers are global and some require more information

21:05 amalloy: zrilak: if you want to turn a vector into a destructuring form you need a macro. but that macro should look more like `(reify Whatever (foo [argmap#] (let [{:keys ~parameter-keys} argmap#] ~@body)))

21:05 because you can't destructure the arglist of a reify body

21:06 zrilak: ah great

21:07 thanks a ton!

21:07 (now off to grok all those #s and @s)

22:49 dnolen: new blog post, runtime dynamism + performance, http://dosync.posterous.com/51626638.

22:49 mec: covers the seqable? conversation from earlier.

22:49 mec: dnolen: k ill check it out

23:26 How come I cant cast a PersistentVector to Iterable even tho it implements it?

23:27 an nvm

23:32 dnolen: what sort of beefy machine do you have? your 600ms example takes >30s on my comp :x

23:32 dnolen: mec: which version of Clojure, JDK ?

23:33 Clojure 1.3.0 master, 2.66ghz i7, JDK 7 64bit is what I'm running.

23:33 mec: jre 1.7 jdk 1.2.1

23:33 err clojure 1.2.1

23:34 dnolen: it's actually more like 500ms on my machine

23:35 mec: at 30s it sounds like you're hitting some kind of reflection.

23:35 mec: thinks it the 1.2.1?

23:35 dnolen: mec: doubtful.

23:36 double-checking

23:38 same perf.

23:39 mec: WEIRD

23:39 * mec chops off his capslock

23:40 amalloy: mec: set caps as an extra ctl and forget about it forever

23:40 mec: So when I call (seqable? {:a 1 :b 2}) it runs both the Map and Iterable paths, which return type does it use?

23:40 amalloy: I usually set it to | but i've been lazy

23:42 err wow nvm

23:42 i think my brain fell asleep early tonight

23:43 amalloy: for a year or two, before emxacs, i had it completely disabled. better than the built-in behavior

23:53 miwillhite: Absolute beginner here…how do I get a list of files in a directory?

23:53 Google is failing me

23:53 amalloy: &(doc file-seq)

23:53 sexpbot: ⟹ "([dir]); A tree seq on java.io.Files"

23:54 amalloy: miwillhite: i think that recursively lists directories though, if you don't want that

23:55 miwillhite: what does the ampersand do?

23:55 oh nm

23:55 dnolen: (seq (.list (java.io.File. "/foo")))

23:55 miwillhite: ^

23:55 miwillhite: thanks dnolen, that one did it for me

23:57 dnolen: (-> (java.io.File. "/Users/davidnolen") .list seq)

Logging service provided by n01se.net