#clojure log - Jun 11 2011

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

5:34 no_mind: is there a function to escape string before insertion in DB ?

5:35 Vinzent: no_mind, there is escape-html (and its alias h) in hiccup

6:34 mduerksen: how could i do this more elegant: (-> 1 inc ((fn[x] (* x x))) ? i want to assign a name to some intermediate value during the processing of ->

6:35 but i don't like the ((

6:52 void_: mduerksen: at least use short anonymous function: #( ... % ... )

7:20 Cozey: how to check if a symbol is a name of a java class imported to the namespace?

7:26 tomoj: this seems to work? ##(class? (resolve 'Math))

7:26 sexpbot: java.lang.SecurityException: You tripped the alarm! resolve is bad!

7:26 tomoj: right..

7:27 well..

7:28 (class? (resolve 'foo.bar.Baz)) will return true even if Baz isn't imported

7:30 fliebel: I'm looking to play with a GraphDB in Clojure and found tons of Neo4j wrappers. This one seems to be the most recent, but I wonder what you think about the rationale: https://github.com/wagjo/borneo#readme

7:42 Cozey: tomoj: thanks, will check this out

7:52 Dranik: hello guys!

7:52 I have published a small tutorial on how to develop a simple blog using clojure

7:53 it is located here: https://github.com/dbushenko/ClojureBlog

8:05 Vinzent: Dranik, looks good, you should consider posting it on the google group

8:07 btw, I'd rewrite map->soy function in this way: ##(into {} (for [[k v] {:a 1 :b 2}] [(name k) v]))

8:07 sexpbot: ⟹ {"a" 1, "b" 2}

8:25 hoeck: $mail mduerksen (->> 1 inc (repeat 2) (apply *))

8:25 sexpbot: Message saved.

9:35 kephale: ,(clojure.set/map-invert {1 2, 3 2})

9:35 clojurebot: {2 3}

9:35 kephale: : X is there an elegant way to do something like merge-with but map-invert

9:36 oh nvm… always look at the source on the API docs… map-invert is super concise anyway. I'll just write a custom fn

10:24 fliebel: Oh noes! I'm coding some Python project, and I'm stuck in-between Java and Clojure for the design. Cognitive dissonance everywhere.

10:52 Vinzent: What's the best way to split collection into two, where the first will contain elements for those predicate returns true, and the second - all others?

10:53 halfprogrammer: ,(group-by even? (range 10))

10:53 clojurebot: {true [0 2 4 6 8], false [1 3 5 7 9]}

10:54 halfprogrammer: Vinzent: think you are looking for group-by

10:54 Vinzent: halfprogrammer, yes, thanks!

10:59 Scorchin: How can I pass a function to be run multiple times? Currently I'm looking at something like this, but it's not working: (defn times [n op] (for [i (range n)] (op))) and it's being called as (times 5 (println "hello")) which only prints "hello" once

11:00 Vinzent: Scorchin, you should use doseq for side effects

11:00 Scorchin: I think the issue is that the (println "hello") is evaluated before it's passed in, but how do I stop it being evaluated?

11:01 Vinzent: thanks, I'll look into it

11:02 Vinzent: Scorchin, and you should wrap println call in the function, e.g. #(println "hello")

11:02 also, there is built-in dotimes macro that do exactly what you want

11:06 Scorchin: Vinzent: yeah, just saw (dotimes) when looking for doseq

11:14 shish_kabob: ,(find-doc "doseq")

11:14 clojurebot: -------------------------

11:14 clojure.pprint/get-pretty-writer

11:14 ([writer])

11:14 Returns the java.io.Writer passed in wrapped in a pretty writer proxy, unless it's

11:14 already a pretty writer. Generally, it is unneccesary to call this function, since pprint,

11:14 write, and cl-format all call it if they need to. However if you want the state to be

11:14 preserved across calls, you will want to wrap them with this.

11:15 Fo...

11:15 shish_kabob: ,(find-doc "dotimes")

11:15 clojurebot: -------------------------

11:15 clojure.core/dotimes

11:15 ([bindings & body])

11:15 Macro

11:15 bindings => name n

11:15 Repeatedly executes body (presumably for side-effects) with name

11:15 bound to integers from 0 through n-1.

11:56 edoloughlin: How do I reference a locally-built JAR in Leiningen's project.clj? Webbit's clojar.org JAR dates from Feb...

11:59 mefesto: edoloughlin: you could use maven to install a jar into your local repository using the install:install-file target

11:59 edoloughlin: mefesto: Thanks, I'll try that. Would be nice if I could just point leiningen at my filesystem, though...

11:59 mefesto: edoloughlin: http://maven.apache.org/plugins/maven-install-plugin/install-file-mojo.html

12:00 I agree, or at least a leiningen install task

12:01 this would be awesome: lein install some.jar [com.test/some "1.0.0"]

12:01 Scorchin: edoloughlin: you can grab the latest webbit jars here: http://oss.sonatype.org/content/repositories/public/org/webbitserver/webbit/

12:02 Vinzent: edoloughlin, also, you can just put it in the lib folder and all should works

12:02 edoloughlin: Scorchin: Thanks. I've no problem building it locally. I would just like to be able to point Leiningen at it.

12:03 Vinzent: I'll give that a go!

12:03 mefesto: oh that sounds handy

12:06 Vinzent: can I clear the cache of memoized function somehow or should I use my own implementation for that?

12:07 mefesto: edoloughlin: looks like calling `lein deps` will clear out any jar that isn't listed in the project.clj

12:08 Vinzent: mefesto, there is some parameter in project.clj that prevents such behaviour

12:10 mefesto: Vinzent: ahh ok: https://github.com/technomancy/leiningen/blob/stable/sample.project.clj#L54

12:10 paraseba: mefesto: in fact, there is an install task in leiningen, and a native-path key in project.clj (at least in dev versions)

12:12 mefesto: paraseba: that can be used for installing a local jar file? i thought that was only for building and installing the current project into your local repo

12:13 paraseba: mefesto: hum, I think you're right

12:14 mefesto: i tend to use mvn install:install-file so i don't have to keep any jars in version control, plus it's nice to have your deps listed in one place (project.clj)

12:23 raek: edoloughlin: which lib is it? are you sure it isn't in the maven central? (search at http://jarvana.com/)

12:26 it has been my experience that often when a person wants to point leiningen to a jar file they are just not aware of that there are more repos than clojars :-)

12:53 void_: hello

12:53 &(reduce (fn [x y] (+ x y)) [1 2 3 4])

12:53 sexpbot: ⟹ 10

12:53 void_: &(reduce #((+ %1 %2)) [1 2 3 4])

12:53 sexpbot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

12:53 void_: I want to write shorter anonymous function but it looks like I'm doing something wrong

12:54 hmm and this works

12:54 &(reduce #(+ %1 %2) coll)

12:54 sexpbot: java.lang.Exception: Unable to resolve symbol: coll in this context

12:54 void_: &(reduce #(+ %1 %2) [1 2 3 4])

12:54 sexpbot: ⟹ 10

12:57 raek: void_: ##(reduce + [1 2 3 4])

12:57 sexpbot: ⟹ 10

12:57 void_: I love clojure

12:57 thanks raek

12:58 &(reduce + [1 2 3 4])

12:58 sexpbot: ⟹ 10

12:58 void_: of course

12:58 + is a function that takes two arguments

12:58 I can pass it directly to reduce

12:58 raek: void_: #((+ %1 %2)) is equivalent to (fn [x y] ((+ x y))). if you call the function with 1 and 2, you get ((+ 1 2)) -> (3) -> error

12:58 since 3 is not a function

13:01 void_: and yes, functional programming rocks! :-)

13:04 void_: when I was 14 I learned about this operator in PHP: boolean ? something : something-else. It felt awesome. Learning Clojure, I have those moments every hour or so. :))

13:07 ohpauleez: clojurebot: ping

13:07 clojurebot: PONG!

13:07 void_: oh and this is cool: https://github.com/abedra/clojure-web

13:20 s450r1: any other clojure users at the SouthEast Linuxfest in Spartanburg, SC?

13:21 mids: void_: ah, thanks for that link

13:21 s450r1: I'd love to say hi if there are. I'm wondering around in a Clojure Conf t-shirt.

13:21 well, wandering and wondering

13:30 TimMc: Recommendations on a relational database to use from Clojure?

13:30 raek: void_: note that the compojure version used there is not the latest. the compojure syntax has changed, so check the version if you find examples that don't seem to work

13:31 void_: TimMc: I'm enjoying working with MongoDB altough that is not exactly a relational database.

13:31 but it works nicely with clojure, perhaps because its schemalessness

13:31 *because of its ...

13:31 raek: these kind of examples are really useful in a modularized world like clojure web programming

13:31 mefesto: TimMc: postgresql is quite a nice rdbms

13:31 TimMc: Not interested in document-oriented.

13:31 mefesto: How is it with unit-testing?

13:32 Or automated testing in general, really.

13:32 mefesto: TimMc: depends on your approach, we use the tx rollback approach

13:32 TimMc: SQLite seems to work really well for that, and that's what I've been using from Python.

13:32 raek: TimMc: I recommend checking out ClojureQL. (it is a library for using SQL, and not a database though)

13:33 TimMc: mefesto: How's that now?

13:34 mefesto: TimMc: you run your tests which modify the db in a transaction. after asserting your values the db is rolled back so you don't have to constantly refresh the data across test runs

13:35 TimMc: OK, sounds about right.

13:36 It's not quite appropriate for my purposes, but I'll keep that in mind.

13:36 My program takes an initial database and runs it through a sequence of modifications, which is a little different.

13:37 The schema actually changes in the process.

13:38 ...and now that I've put it that way, maybe I should be doing this all in memory anyway. >_<

13:39 mefesto: when in production do you expect heavy load for this app?

13:40 if so, mysql and postgres have memory tables that could be handy for local testing. then when deployed the schema uses innodb or normal tables

13:40 TimMc: I don't expect anything over 100,000 entries.

13:40 mefesto: sqlite probably good enough then

13:42 all this coming from someone that doesn't really know what your app is ... so ;)

13:44 TimMc: It publishes a KPhotoAlbum database as an online gallery.

13:45 mefesto: out of curiousity, why does it need to change the schema?

13:46 TimMc: Specifically, it reads a KPhotoAlbum database (metadata in an XML file) and discovers new/changed/moved/deleted files, reflects those changes into a database, a thumbnails directory, and a symlinks folder, munges the metadata (mostly taking the transitive closure of a tag DAG), syncs the symlinked images and thumbnails to Amazon S3, and overwrites the remote DB with the local one.

13:47 mefesto: It might not need to change the schema, but I haven't really touched this code in 3+ years and there were some tricky little challenges I discovered while writing it.

13:48 In any event, the different steps of the process expect different assertions to hold true about the relationships in the DB.

13:50 mefesto: With that said, would transactions be pretty important for this functionality?

13:51 if so, then schema changes might not fit well. afaik, schema changes cannot be rolled back

13:54 TimMc: I'll have to ponder this for a bit.

14:08 void_: compojure sets encoding to iso-8859-1 by default

14:08 ~/Desktop $ curl -i http://127.0.0.1:3000/new

14:08 HTTP/1.1 200 OK

14:08 Date: Sat, 11 Jun 2011 17:41:14 GMT

14:08 clojurebot: I think you mean gnir.

14:08 void_: or jetty sets it

14:09 anyway does anybody know how to change it to utf8?

14:21 bortreb: this is rather basic I'm sure, but I can't seem to find it anywhere --- how do you robustly sanitize a String to give a valid filename for your platform?

14:22 for example, remove all "/" for linux, remove all ":" , etc for windows and replace "com" and "ptr" with something valid?

14:24 TimMc: bortreb: You want to convert a user-supplied filename to a valid system filename without yelling at them over invalid characters?

14:25 raek: void_: yes: add a charset attribute in the content type: "Content-Type" "text/html; charset=UTF-8"

14:25 void_: raek: so I have to do that for each route?

14:26 raek: void_: the servlet spec says that a servlet container must add ISO-8859-1 as the charset if it's missing :(

14:26 TimMc: ew

14:26 void_: meh

14:26 raek: void_: no, add it to the response of the routing

14:26 if all branches produce html

14:27 void_: it's easy to do a middleware function for it

14:28 bortreb: TimMc: yeah, although they're not human supplied strings. I;m downloading many files from a website and trying to give them meaningful names by grabbing text from the same page as the file

14:28 TimMc: so I just want the equivalent of HTML escaping for system filenames

14:29 raek: (defn wrap-utf8-html [handler] (fn [request] (let [response (handler request), content-type (get-in response [:headers "Content-Type"])] (if content-type response (assoc-in response [:headers "Content-Type"])))))

14:29 Dranik: void_, hi !

14:29 TimMc: That's a good question!

14:29 void_: hi Dranik

14:29 Dranik: I have published my blog to github

14:29 void_: awesome, paste link please

14:29 hiredman: bortreb: http://download.oracle.com/javase/1.5.0/docs/api/java/net/URLEncoder.html

14:29 Dranik: it's here: https://github.com/dbushenko/ClojureBlog

14:29 I have supplied lots of comments

14:29 may be you'll find it usefull

14:30 raek: void_: or use (ring.util.response/content-type "text/html; charset=UTF-8") if you unconditionally want html

14:30 TimMc: hiredman: THat doesn't protect from com1.txt, etc.

14:30 void_: raek: where should I put that snippet?

14:31 TimMc: Windows is disgusting that way.

14:33 raek: void_: sorry, the last example cannot be called like that. if you routes (more generally called a handler) is called 'handler', and the middlware function is called wrap-foo you get a handler wrapped in the middleware by calling (wrap-foo handler)

14:33 bortreb: TimMc: , hiredman: yeah, this would work for the linux box I'm working on, but I figure its a common enough problem that there's some apache library or something that handles all the edge cases

14:34 void_: raek: ok, well, I think I'm gonna look into some examples of using middlewares. Thanks!

14:35 raek: void_: I haven't used compojure for a while, but moustache (another routing library) has built in syntax for it: (app wrap-foo wrap-bar ["foo"] {:get get-foo} ["bar"] {:get get-bar, :post post.bar})

14:36 it = adding middleware

14:36 the more manual way of doing it is (def handler ...) (def handler (-> handler wrap-bar wrap-foo)) ;; note the order

14:38 void_: yeah it's pretty simple in compojure too

14:38 there's a function that creates handler from routes

14:38 and I can add wrappers to handler

14:38 I think .. :)

14:39 raek: void_: it's probably a good idea do make a function like this and use it in your handler: (use 'ring-util.response) (defn html-sucess [body] (-> body (response) (content-type "text/html; charset=UTF-8")))

14:39 rather than making a middleware function that fills it in later

14:39 void_: raek: yes that seems like the best way. Altough, I was hoping utf8 would be question of changing some config setting :-/

14:40 raek: so yes, you do it for every route, but factor out the common parts

14:41 void_: Dranik: didn't you have to deal with utf8 encoding when building your blog?

14:41 Dranik: let me check it out..

14:42 void_: I'm asking because Azbuka probably requires utf8 :)

14:42 Kratoss: this might sound weird

14:42 raek: cyrillic?

14:43 Kratoss: but is there some kind of limitation on clojure sets and numbers

14:43 they don;t work for me

14:43 raek: Kratoss: can you show an example?

14:43 Kratoss: ,((into #{} [1 2 3]) 3)

14:43 clojurebot: 3

14:43 Kratoss: hm...

14:43 void_: raek: yeah, I thought Dranik had to deal with that, but maybe he built it in English so he didn't notice

14:44 Kratoss: let's say I have "sieve" function that returns a vector of primes

14:45 (def prime? (into #{} (sieve 100)))

14:45 (prime? 2) returns nil

14:45 but if I operate with strings it works fine

14:45 raek: strings?

14:45 Kratoss: yeah

14:46 (def prime? (into #{} (map str (sieve 100))))

14:46 user> (prime? "2")

14:46 "2"

14:46 but above example with numbers returns nil

14:46 raek: Kratoss: are you interoping with Java? there is a problem with different types of boxed numbers (Integeres and Shorts aren't equal)

14:47 Kratoss: first, if you look at the set in the repl, does it contain 2?

14:47 Dranik: unfortunatelly, I haven't dealt with unicode...

14:47 Kratoss: they are java.lang.Long

14:47 according to class fn

14:47 yes the set contains numbers just fine

14:48 it's confusing as hell

14:48 raek: ah, so there is the problem. the set contains longs and you try to check for an integer

14:48 this issue has been worked in the 1.3 version of Clojure

14:48 where does the longs come from?

14:48 Kratoss: the sieve function

14:49 ah, I just add the cast and we are good to go

14:50 raek: Kratoss: one fix could be to do (def prime? (comp (into #{} (map long (sieve 100))) long))

14:50 TimMc: Kratoss: Now just hope you don't get into BigInteger. :-)

14:50 Kratoss: weird though, that clojure sets treat numbers differently

14:50 based on type

14:50 raek: but in clojure 1.2, I think you should get Integers if the numbers fit in them

14:50 Kratoss: you know.... since it does hidden type changing through autopromoting

14:50 raek: Kratoss: that's a problem inherited from Java

14:50 TimMc: Kratoss: Blame Java for hashing numbers weirdly.

14:51 ,(.hashCode (int 4))

14:51 clojurebot: 4

14:51 TimMc: ,(.hashCode (long 4))

14:51 clojurebot: 4

14:51 TimMc: Well, not that one.

14:51 Kratoss: you got told :P

14:51 TimMc: I shore did. :-?

14:51 can't type today either.

14:51 raek: Kratoss: but in Clojure 1.3 all boxed integer numbers are Longs and float numbers Doubles

14:51 hiredman: (.hashCode (Long. (long 1)))

14:51 ,(.hashCode (Long. (long 1)))

14:51 clojurebot: 1

14:51 hiredman: huh

14:51 maybe it is bigints that hash weird

14:52 yeah

14:52 Kratoss: you probably need to exceed the mod number in hash function

14:52 to get any real effect

14:52 hiredman: ,(.hashCode 1M)

14:52 clojurebot: 31

14:52 hiredman: there

14:52 ^- nuts

14:52 Kratoss: ,(.hashCode (long 100))

14:52 clojurebot: 100

14:52 hiredman: cuckoo for cocoa puffs

14:52 Kratoss: well BigDecimal isn't just the number

14:53 but also magnitude and precision

14:53 2.00000 is not equal to 2.0

14:53 look at bigdecimal javadoc

14:53 hiredman: ,(class 1M)

14:53 clojurebot: java.math.BigDecimal

14:53 Kratoss: so hashcode has to reflect that

14:54 hiredman: huh

14:54 I thought 1M was a biginteger

14:55 anyway, at some point biginteger hashes different and does equality different from longs

14:56 which breaks things, and is why clojure has clojure.lang.BigInt

14:58 void_: I'm giving up on utf8, looks like the solution is not so easy: http://groups.google.com/group/ring-clojure/browse_thread/thread/b2c7cd4c9e045d6/70e622f6ce9b166e?lnk=gst&q=encoding#70e622f6ce9b166e

15:02 raek: void_: didn't setting the header in the response work?

15:03 void_: raek: no

15:03 this guys explains: "If you set only the content-type to "text/html; charset=utf-8", jetty

15:03 will still encode the response to iso-8859-1. "

15:04 I understand you have to call method on Java class, but Ring doesn't have any way to do it

15:04 raek: hrm. if the body is an InputStream, no recoding should be done

15:04 void_: well I'm using hiccup

15:04 raek: void_: what kind of body do you have in the response? a string?

15:04 void_: let me try just put a string in there

15:05 raek: iirc, hiccup will return a string

15:05 somewhere the string needs to be encoded into a byte stream (InputStream)

15:07 void_: so yeah, server is returning correct header, but characters are still messed up

15:07 raek: https://github.com/mmcgrana/ring/blob/master/ring-servlet/src/ring/util/servlet.clj#L72

15:08 ok, so the servlet container has a writer that is configured for some random encoding...

15:08 ugh. what a mess.

15:08 void_: yeah

15:09 I wish there was utf8 by default

15:09 TimMc: ,(map #(.hashCode %) ((juxt int long) -5))

15:09 clojurebot: (-5 4)

15:09 void_: it's 2011 :-/

15:10 raek: void_: at least the clojure file I/O (clojure.java.io) defaults to UTF-8...

15:10 TimMc: Kratoss: Negative integers seem to hash differently as long vs. int.

15:12 raek: void_: what does `echo $LANG` return on your computer?

15:12 void_: sk_SK.UTF-8

15:13 TimMc: SKotland!

15:13 void_: :D

15:13 no

15:13 TimMc: Sweden?

15:13 void_: nope

15:13 http://en.wikipedia.org/wiki/Slovakia

15:13 TimMc: Slovakia, says Google.

15:13 Cool.

15:13 fliebel: Sweden??

15:14 TimMc: Right, Sweden is .se.

15:14 fliebel: Do you highlight on that?

15:14 raek: Sweden? no. we have sv_SE

15:14 fliebel: TimMc: No, just joined, wondered what it's about.

15:14 antares_: hi. Can someone tell me what the clojure.data.xml artifact line for leiningen is?

15:15 that project doesn't even have a README

15:15 fliebel: ~logs

15:15 clojurebot: logs is http://clojure-log.n01se.net/

15:16 fliebel: Logs should be real-time :(

15:16 antares_: anyone?

15:16 clojurebot: Please do not ask if anyone uses, knows, is good with, can help you with <some program or library>. Instead, ask your real question and someone will answer if they can help.

15:17 fliebel: antares_: Look in the pom.

15:17 TimMc: fliebel: void_'s OS uses sk_SK.UTF-8 as $LANG

15:17 antares_: fliebel: what if I am not experienced with reading .pom files?

15:18 hiredman: I'd suggest you complain on the clojure mailing list

15:19 contrib is very maven heavy while most of the clojure world uses project.clj based tools

15:21 antares_: hiredman: not sure if you are talking to me but I have been trying to find any documentation on data.xml or any "new contrib" library artifact for lein. I am certainly quite stupid but man, 20 minutes and no results. data.xml doesn't even have a README.

15:22 hiredman: right, so please bitch about it on the mailing list, squeaky wheel and all that

15:22 antares_: I guess I simple won't be using clojure for this app, it is very sad that contrib libraries are maintained/documented so poorly. Scala projects somehow have at least some information.

15:22 hiredman: why would I? I simply won't use clojure.

15:22 fliebel: antares_: Looking at the pom it's [org.clojure/data.xml "0.0.1-SNAPSHOT"] now, reverse-engineer and do it yourself next time ;)

15:22 antares_: fliebel: that doesn't work

15:23 that was the 1st thing I tried

15:23 leiningen fails to find this artifact

15:23 anyway

15:23 void_: oh I got it working this encoding

15:24 (java.io.ByteArrayInputStream. (.getBytes "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'></head><body>ľščťžýáí</body></html>" "UTF-8")))

15:24 fliebel: antares_: Don't fogert to add the snapshot repo. https://oss.sonatype.org/content/repositories/snapshots

15:24 void_: return that instead of a string

15:24 antares_: fliebel: also, "do it yourself next time" is exactly kind of attitude Clojure community cannot afford. It is too small.

15:24 void_: I found same discussion in logs http://clojure-log.n01se.net/date/2010-08-12.html

15:24 fliebel: antares_: Oh, it;s fine if you aks, but the point is that you *can* do it next time.

15:25 antares_: Does my repo comment help anything?

15:26 raek: void_: nice. so it is at least possible to reliably work around the problem...

15:28 fliebel: wait... he left?

15:35 Cozey: Hello. Is it just me, or does anybody else has problesms with getting [org.springframework.security/spring-security-adapters "2.0.4"]

15:35 ?

15:35 it's present in mvnrepository here http://mvnrepository.com/artifact/org.springframework.security/spring-security-adapters

15:35 but cake fails to download it, although it downloads many other deps....

15:49 Kratoss: the cake is a lie

15:49 *obvious*

15:50 void_: no way

15:50 raek: The problem was that I used Content-type instead of Content-Type

15:50 __name__: Yay, Portal references \o/

15:52 Cozey: :-))

16:35 raek: anyone have a recommendation for a sqlite jdbc driver maven artifact?

16:38 edoloughlin1: raek: Thanks for the pointer to jarvana.org for webbit earlier. (Wasn't around when you replied)

16:39 raek: edoloughlin1: so my intuition was correct? (you needed a java lib not on clojars) :-)

16:45 hrm. why do so many libs forget to mention what namespace you're supposed to use? :)

16:48 edoloughlin1: raek: Yes, you were right. However, it was on clojars but it was a version from Feb.

18:28 TimMc: raek: Urgh, I hate that. *checks own libs...*

18:41 pdk: do type hints have to be class names or interfaces as well

18:48 dnolen: pdk: ?

18:49 pdk: in function arg lists

18:49 like (fn [^Serializable x] ...)

18:49 ,(fn [^Serlializable x] x)

18:49 clojurebot: #<sandbox$eval761$fn__762 sandbox$eval761$fn__762@5043d6>

18:49 pdk: ,((fn [^Serlializable x] x) 1)

18:49 clojurebot: 1

18:50 pdk: ,((fn [^Serializable x] x) 1)

18:50 clojurebot: 1

18:50 pdk: hm

19:08 technomancy: hah; the only thing in the readme of data.xml is "this is not intended for use yet"

19:11 no wonder he couldn't find it

19:29 hv: is there a release schedule or something for clojure 1.3?

19:30 seancorfield: pdk: you were asking about type hints - they are for java interop; they don't cause casts per se

19:31 so (fn [^Serializable x] ...) is only useful insofar as operations on x don't need reflection

19:31 ,((fn [^long x] x) 1.23)

19:31 clojurebot: 1.23

19:32 seancorfield: ,((fn [x) (long x)) 1.23)

19:32 clojurebot: Unmatched delimiter: )

19:32 seancorfield: ,((fn [x] (long x)) 1.23)

19:32 clojurebot: 1

19:32 seancorfield: hth

19:37 mabes: does clojure ship with a function that maps a list's elements into a map with the keys being the original value? Something like this:

19:37 ,(let [vals->map (fn [f vals] (reduce (fn [m v] (assoc m v (f v))) {} vals))] (vals->map inc [1 2 3]))

19:37 clojurebot: {3 4, 2 3, 1 2}

19:38 mabes: (just wondering for future reference)

19:39 raek: ,(let [coll [1 2 3]] (zipmap coll (map inc coll)))

19:39 clojurebot: {3 4, 2 3, 1 2}

19:39 raek: ,(into {} (for [x [1 2 3]] [x (inc x)]))

19:39 clojurebot: {1 2, 2 3, 3 4}

19:40 raek: ,(into {} (map (juxt identity inc) [1 2 3]))

19:40 clojurebot: {1 2, 2 3, 3 4}

19:41 mudge: hello

19:41 mabes: raek: nice, that is much shorter.. I always forget about juxt

19:42 mudge: I am new to clojure and have studied it a little and would like to develop a website with it, does anybody recommend any web development tutorials?

19:42 like the newest up-to-date?

19:44 mabes: mudge: I don't know of any new ones but here is nice one: http://mmcgrana.github.com/2010/07/develop-deploy-clojure-web-applications.html

19:45 raek: mudge: this is very good: http://brehaut.net/blog/2011/ring_introduction

19:46 seancorfield: +1 raek

19:46 raek: the clojure web world consists of many libraries so it can be difficult to know what to look for and where

19:46 mabes: hadn't seen that one, nice resource

19:46 raek: that tutorial walks you though the libs you need to know about

19:46 seancorfield: i'm porting my FW/1 MVC framework to Clojure :)

19:46 mudge: great, thanks guys

19:47 have you guys heard of any book being written for writing web apps in clojure?

19:47 seancorfield: not specifically for web apps, no

19:47 mudge: are you near the bay area, CA?

19:47 amit rathore (clojure in action) is running a one day clojure web app course for $199 on June 25th

19:48 http://www.meetup.com/The-Bay-Area-Clojure-User-Group/events/19931761/

19:48 mudge: cool

19:48 ampleyfly: raek: what's wrong with the colors o.o

19:48 mudge: i am in florida

19:48 brehaut: raek: thanks :)

19:49 raek: brehaut: didn't the site used to be even more yellow?

19:49 brehaut: it did

19:49 too many people complained so i toned it back a bit

19:49 seancorfield: mudge: ah, a bit far to come then :)

19:49 brehaut: all remaining complaints can be sent to /dev/null

19:50 mudge: hey brehaut, the overview of the clojure webstack is written by you. cool

19:50 reading it

19:51 cool, i like that it is recent

19:53 brehaut: mudge: thanks

19:57 mudge: ah, the ring SPEC explains so much: https://github.com/mmcgrana/ring/blob/master/SPEC

19:57 i didn't understand the clojure web terminology before

20:09 tufflax: Is there something like an opposite of interleave?

20:11 pdk: (doc interleave)

20:11 clojurebot: "([c1 c2] [c1 c2 & colls]); Returns a lazy seq of the first item in each coll, then the second etc."

20:11 pdk: take-nth?

20:12 offby1: unzip?

20:12 clojurebot: unzip-with is http://paste.lisp.org/display/76458,1/raw

20:12 offby1: untangle? demultiplex?

20:13 mudge: I understand everything in the SPEC: https://github.com/mmcgrana/ring/blob/master/SPEC except for :headers near the bottom

20:13 A Clojure map of HTTP header names to header values. These values may be

20:13 either Strings, in which case one name/value header will be sent in the

20:13 HTTP response, or a seq of Strings, in which case a name/value header will be

20:13 sent for each such String value.

20:14 chouser: {

20:14 {"Content-type" "text/html"}

20:15 mudge: what does this mean: "in which case one name/value header will be sent in the HTTP response" ?

20:15 raek: I think it means that {"Foo" "bar"} becomes "Foo: bar" and {"Foo" ["bar" "baz"]} becomes "Foo: bar\nFoo: baz"

20:17 this makes sense since a key can only occur once in a map. so if you need multiple values associated with the same key, you need something like this

20:17 chouser: is there a pull-parser included with Java 1.5? What about 1.4?

20:17 tufflax: pdk, offby1 thanks

20:17 mudge: raek, that makes sense, thanks

20:18 raek:, i understand it now because of your help so thanks

20:20 brehaut: your clojure web tutorial is very helpful

20:21 I just read the SPEC and for the first time I understand what a Handler is

20:21 raek: brehaut: XML-RPC looks ridiculous simple to use with necessary-evil. impressive!

20:23 wait what? <dateTime.iso8601> in XML-RPC is not even ISO 8601?

20:26 mudge: what is a clojure form?

20:27 raek: now don't tell me the ANSI Windows code page is not an ANSI standard! ;-)

20:28 mudge: raek, I won't tell you that

20:28 raek: mudge: my interpretation of the word "form" is the generalization of: variable, special form, function application and macro "call"

20:29 tomoj: the form of a form may seem to be function application

20:29 mudge: raek, ah okay, so it is anyone of those?

20:29 and all of them

20:29 tomoj: but '(foo bar baz) is a form even if foo, bar, baz don't resolve

20:30 raek: those are the different cases of a form

20:30 tomoj: and how about '[foo bar baz]?

20:31 raek: mudge: these guys can explain it much better (and have more knowledge about this teminology) than I: http://stackoverflow.com/questions/2877371/definition-of-lisp-form

20:32 tomoj: huh, they say it must eval

20:33 but "form" used e.g. in the -> docs can't be that kind of form

20:34 mudge: raek, thanks once again

20:34 raek: after reading that I would interpret a Clojure form to be a piece of data built of clojure data structures and values that is well-structured (follows the syntax rules of any occuring special forms and macros)

20:35 essentially, clojure data that passed the compilator

20:35 data meaningful as a clojure code

20:36 brehaut: raek: as far as i can tell yeah, that date format is some random not quite any iso format. it has been an infuriating spec to implement

20:40 raek: brehaut: seems like everything is nicely abstracted away from the user at least ;-)

20:41 brehaut: btw, what is your personal preference for the reverse of the word "parse"?

20:43 brehaut: raek: i dont know :) unparse seems awkward

20:44 raek: finding good names is the hardest part of programming :)

20:45 brehaut: and cache invalidation

20:46 raek: for string/line-based protocols, I lean towards "format"

20:47 doesn't feel quite right when it's not primarily for human reading

20:47 so the search goes on...

20:52 brehaut: agreed

20:56 tomoj: I like encode/decode

21:00 korny: Hi folks - any tips on how to bind vars when doing stuff on a separate thread, i.e. using send-off ?

21:00 I found http://clj-me.cgrand.net/2009/01/20/bindings-and-send/ but it's a couple of years ago - wondering if there's a better way

21:01 jao: chouser, i'm a bit late, i know, but nice talk on the expression problem!

21:02 korny: ... my concern with that approach is that I'd need to explicitly name some bindings that are made by libraries outside my call to send-off, which seems like excessive coupling. (For example I'm spawning threads within a (with-oauth) context, don't really want to have to hunt down all the bindings set up by with-oauth)

21:03 dnolen: korny: I believe in 1.3.0 bindings are automatically propagated.

21:03 korny: dnolen: cool. Currently using 1.2 - I could upgrade, but it might be painful (especially as I believe congomongo doesn't support 1.3 yet)

21:04 dnolen: korny: yeah, I don't think this improvement will get backported.

21:04 1.2.0 -> 1.3.0 is not that painful IME.

21:14 chouser: jao: oh, thanks!

21:15 sounds like there will be approximately 10x the Clojureness at Strange Loop this year.

21:50 * halfprogrammer thinks it's a beautiful morning

23:07 seancorfield: darn, just noticed korny was asking about congomongo and clojure 1.3.0

23:07 i just made congomongo compatible with 1.3.0 the other day!

23:08 of course, like c.j.jdbc it relies on a global DB connection and binding so it isn't thread safe in 1.3.0 (as i understand it?)

23:11 i assume that was kornelius sietsma / kornys on twitter?

23:11 tomoj: is the thread safety issue with the so-called "binding conveyance"?

23:12 seancorfield: so i've been told... dynamic vars in 1.3.0 span threads so rebinding them is not thread safe

23:13 if you only have one DB connection, it's fine i guess

23:13 but (with-whatever conn body) usually rebinds a global *conn* var so if conn differs across threads, that would be bad :)

23:14 i haven't verified that - just what i've been told...

23:24 tomoj: I wonder if the only way they span threads is through agent sends

23:34 carllerche: is it crazy to write a macro that looks arbitrarily deep for specific forms?

23:35 pdk: if it does the job

23:36 hell i found some year old code

23:36 looked at the macro i wrote at the top

23:36 carllerche: the alternative would be to make multiple macros i guess

23:36 pdk: and just went "wtf does this even do"

23:41 tomoj: carllerche: sounds like clojure.walk may help?

23:42 carllerche: huh, interesting

23:46 tomoj: I think e.g. lamina uses that to rewrite stuff for async arbitrarily deeply

Logging service provided by n01se.net