#clojure log - Feb 11 2010

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

1:51 Raynes: http://jobs.arstechnica.com/list/543/?utm_source=Indeed&utm_medium=organic&utm_campaign=Indeed "are pragmatic enough to understand that clojure is not a cure for cancer..."

1:51 Heh heh. It's a job offer.

2:00 herdrick:

2:01 ,indexed

2:01 clojurebot: #<seq_utils$indexed__697 clojure.contrib.seq_utils$indexed__697@19cc8fd>

2:07 DeusExPikachu: Raynes, it doesn't cure cancer "yet"...

2:07 :)

2:34 LauJensen: Good morning all

3:41 ordnungswidrig: re

4:53 neotyk: ~def for

5:04 LauJensen: ~source for

5:07 Licenser_: I wonder, is there a way to get a better help during problems then: java.lang.NullPointerException (NO_SOURCE_FILE:1)?

5:15 AWizzArd: Licenser_: well, you could step through your code with a debugger.

5:16 Although I must admit that I always had heavy problem with using debuggers for Clojure code.

5:18 ordnungswidrig: error reporting must definitively improve

5:20 AWizzArd: I agree.

5:20 It would be great if JSwat would simply work.

5:21 It was working better in older versions. Maybe this really is the mistake of JSwat and not Clojure.

5:23 If JSwat would work I would constantly have it opened during development.

5:27 fullets: What's an idiomatic way to go from [:a :b :c :d] -> [:a :c] (i.e., transform a sequence to a sequence containing every other item of the input)

5:29 AWizzArd: fullets: you can do (vec (take-nth 2 [:a :b :c :d])) ==> [:a :c]

5:29 fullets: AWizzArd: Excellent, thanks!

6:14 Licenser_: AWizzArd: thank you for the hint

6:16 zab: hi im having trouble using vimclojure

6:16 im opening a file called 'hello_world.clj' and it gives me: Couldn't execute Nail! java.io.FileNotFoundException: Could not locate hello_world__init.class or hello_world.clj on classpath:

6:17 'hello_world.clj' has a namespace declaration at the top of the file. if i open another .clj file without a namespace, it loads fine

6:18 anyone know what's up?

6:19 cypher23: zab, the ng server needs the correct class path, so it can find your files

6:20 e.g. if your file is located under src/my/namespace/hello_world.clj, you need to make sure that 'src' is on the Classpath for the nailgun server

6:20 The way I do it is start the ng server inside the src dir, and have "." on the classpath

6:22 zab: hmm okay. i've added the directory to the classpath. i've just added it to the environment variable in my ~/.profile (mac os box). i now get a slightly different message

6:22 Couldn't execute Nail! java.io.FileNotFoundException: Could not locate compojure__init.class or compojure.clj on classpath:

6:22 cypher23: well, now it can't find compojure :)

6:22 zab: yeah i put the path to compojure in my classpath as well though :(

6:23 cypher23: do you have compojure in source form, or as a jar?

6:23 zab: jar

6:23 triyo: What would be the equivalent in Clojure of the CL's atom symbol?

6:23 cypher23: did you add the dir the jar is in, or the path to the jar?

6:24 Licenser_: any advice about debugging with emacs and clojure?

6:24 zab: the dir the jar is in but with a wildcard

6:24 i.e. ~/vim/vendor/vimclojure/compojure/*

6:25 cypher23: zab, yeah, that never works for me, at least on os x. you have to add each jar individually

6:25 zab: cypher23: yikes even the dependancies?

6:25 cypher23: zab, http://gist.github.com/301431

6:25 that's how I do it (I have all my jars symlinked into ~/classes/)

6:26 zab: okay that's certainly nicer than what was rushing through my head

6:26 cypher23: zab, no idea. I'm not a Java person, so all this CLASSPATH dealings are somewhat arcane to me :)

6:27 tomoj: triyo: I don't think there is one, really

6:27 zab: cypher23: obviously i am in the same boat. not a Java person either. :)

6:27 tomoj: zab, cypher23: I haven't scrolled up to see what you're really talking about, but have you looked at lein?

6:28 I haven't worried about CLASSPATH in quite a while

6:28 zab: tomoj: i've seen mention of lein in several places but never really explored it.

6:28 tomoj: I see a mention of nailgun though, dunno how/if lein could work with that

6:28 cypher23: tomoj, no, not yet. Still basically doing my first steps in Clojure

6:28 tomoj: ah, ok

6:28 cypher23: tomoj, yeah, nailgun can be a bit tricky to get it up and running

6:29 tomoj: hmm

6:29 actually it appears there is a lein-nailgun plugin :D

6:30 esj: cypher23: indeed, getting everything in place the first time is very trying, but be strong: its worth it.

6:30 tomoj: supposedly you can just add it to your dev-dependencies and then do 'lein nailgun' to start a nailgun server

6:31 esj: yeah, its supposed to do the same for emacs with lein swank, but I had some classpath issues I was too stupid to resolve :(

6:31 tomoj: hmm

6:32 I had some classpath issues once, but after a recent upgrade they disappeared

6:32 (I use lein-swank)

6:33 cypher23: esj, it's mostly the Java stuff that trips me up. Clojure itself has been quite nice so far.

6:33 esj: you and me both, but the bump doesn't take too long to get over

6:34 cypher23: I hope :)

6:38 AWizzArd: Maybe you two can rewrite the JVM in Clojure :)

6:40 tomoj: hmm

6:40 I had never considered clojure hosting itself

6:40 it's possible, right?

6:41 would just require distributing an already compiled version, I think?

6:43 AWizzArd: It is possible, and in fact this is a work in progress.

6:43 ambient: well you need some backend, if not jvm then win32/elf machine code at least

6:43 tomoj: right

6:43 AWizzArd: It already has begun. Yesterday Master Hickey implemented lots of stuff of Vectors in pure Clojure.

6:44 tomoj: I had always just thought of cinc as a way to get clojure on other virtual machines

6:44 not as possibly taking us closer to clojure compiling itself

6:44 ambient: it is, but it can do so much more.. :)

6:44 at least how i understand it

6:45 implementing a scheme compiler in scheme opened my eyes a bit of the possibilities

6:45 tomoj: bit shifts are inlined, hurrah

6:46 zab: hmm, i'm fairly sure my classpath is all sorted now thanks to cypher23, but now i get:Couldn't execute Nail! java.lang.ExceptionInInitializerError (hello_world.clj:0) at clojure.lang.Compiler.eval(Compiler.java:4543)

6:48 tomoj: what is this implicit arg stuff? http://github.com/richhickey/clojure/commit/277f0235c1387ddd6247a72857597814a3e10bc3

6:50 oh, http://www.assembla.com/spaces/clojure/tickets/242

6:51 LauJensen: Wonder why the ticket doesnt explain the pitfalls

6:52 tomoj: pitfalls?

6:53 AWizzArd: Moin cemerick.

6:54 cypher23: zab, how does your hello_world.clj look like?

6:55 LauJensen: tomoj: I think if your macro generates an fn which it internally depend on, then it will break with this change

6:55 clarify: depends on it having a particular signature

6:58 tomoj: hmm, I figured that was for code internal to clojure

7:01 zab: cypher23: it's the first 'hello.clj' example here: http://en.wikibooks.org/wiki/Compojure/Getting_Started

7:02 LauJensen: zab, long story short, head to my blog, read "installing slime", "beating the arc challenge", "reddit clone 1", "reddit clone 2", and you'll be a webguru in no time: http://www.bestinclass.dk/index.php/blog

7:05 zab: LauJensen: i'm just starting out in clojure. your blog has some good content. will definitely check it out. once i get vimclojure working. :(

7:06 LauJensen: zab: great, but the reason I mentioned "installing slime" as the first stop, was not so that you could continue in Vim :)

7:07 zab: LauJensen: hah! yes well it will take more than a few hardships getting vimclojure set up, to get me to move away from vim.

7:08 LauJensen: Ok - Its also worth saying, that VimClojure is pretty great actually

7:09 ohpauleez: fwiw, I love vimclojure. I don't use the repl stuff, but I do use the completion and doc lookup

7:09 zab: LauJensen: yeah I've been playing with the REPL and I'm able to send my current buffer to it, no problems. I really like what I've seen so far.

7:09 underdev: 10 year vimmer here- emacs is impressing the heck out of me. Esp since i'm lisping, i've learned some stuff just setting up emacs.

7:09 cypher23: zab, as a workaround, you could just have a REPL running in a shell next to Vim, and just keep calling (require 'hello-world :reload) to reload your file

7:10 underdev: but vim is excellent, and i had to start editing my .emacs file with it

7:10 and most other situations i find i'm still opening text with vim

7:10 LauJensen: cypher23: May I henceforth address you as Mr. Fred Flintstone ?

7:11 cypher23: I don't have a pet dinosaur :)

7:11 underdev: in other situations (like tcl) i used screen to have a top window of vim and a bottom one of the repl

7:12 LauJensen: cypher23: well... technically you do :D

7:12 zab: cypher23, LauJensen heh. yeah not ideal. i'm still going to pursue this VimClojure setup. but good to know.

7:12 LauJensen: zab: Most evenings CET kotarak hangs out in here, he built it

7:13 cypher23: zab, you could wait for kotarak, he can probably help you out (he helped me a lot)

7:13 zab: LauJensen, cypher23: cool. I'm so close to it, I can taste it.

7:14 cypher23: LauJensen, I do?

7:14 LauJensen: cypher23: You use Vim right ?

7:15 cypher23: LauJensen, sometimes

7:17 LauJensen: Anyway, enough Vim bashing, lets drop the subject and pick it back up again in 20 minz or so :)

7:19 cypher23: hehe, k

7:20 LauJensen: A wee bit OT, but does anybody know if ZyXEL NSA-210 supports SSH ?

7:22 somnium: http://gist.github.com/301463 << spontaneous attempt at coaxing more error info out of exceptions. is there a better way to terminate execution?

7:32 zab: hooray i have VimClojure working with Compojure.

7:33 turns out I didn't have the same clojure.jar and clojure-contrib.jar files that I compiled compojure against, in the classpath

7:34 i'm able to load files which require compojure fine now, except upon loading it, vim gives me: E15: Invalid expression: 2010-02-11 23:27:50.193::INFO: Logging to STDERR via org.mortbay.log.StdErrLog^@clojure.proxy.javax.servlet.http.HttpServlet

7:34 anyone seen this before?

7:39 AWizzArd: rhickey: Hi. I think I just discovered a bug in Clojures compiler. When I try to compile my namespace it tells me (Windows XP) that the file name is wrong. I found out that this happens when I try to compile a deftype which contains a slot which contains a questionmark in its name.

7:40 While for example vars are translated into foo$somefn_QMARK__2457.class this seems to not happen with slots inside deftypes.

7:41 zab: gg, thanks for your help everybody.

7:43 AWizzArd: Can any windows user please try to confirm this issue? Put this into a file yourcp/bar/foos.clj (ns bar.foos) (deftype Foo [a b c?])

7:43 When you then do (binding [*compile-path* "yourcp/build/"] (compile 'bar.foos)) you should see an error message.

7:44 maybe under Linux this is a problem too, don't know how questionsmarks are handled.

7:51 triyo: Any Clojurians here read the OnLisp book and attempted to implemented the solutions in Clojure?

7:57 lpetit: triyo: sure. For example: http://blog.thinkrelevance.com/tags/on%20lisp

7:59 triyo: lpetit: thanks. Thats great. I'm working on chapter 19 - Query compiler part. Hope I didn't bite of more then I can chew.

7:59 so far so good

8:06 Licenser_: hjmm can anyone give me an advice here? when adding a emacs swank option I get let: Wrong type argument: listp, "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8888"?

8:07 ah found it had to add '( arund it

8:10 oh my got jswat is not doing what I expect

8:12 AWizzArd: Yeah, because you can not set break points and such.

8:19 krumholt: if i have only one ref in my program i want an atom instead right?

8:19 AWizzArd: krumholt: not necessarily

8:20 I will tell you in .de ;-)

8:31 ordnungswidrig: me is building a validation library. The name of some validation functions clash or nearly clash with existing functions, what would you suggest to be a good solution? Using a prefix, like v-odd or !odd ?

8:32 Maybe I should use some macro to build a validation dsl?

8:33 AWizzArd: ordnungswidrig: don't know if possible, but perhaps the validation fns can have the same name, and your Data Structures can extend a Protocol?

8:33 cemerick: ordnungswidrig: that's what namespaces are for

8:34 ordnungswidrig: cemerick: sure. hm, I see. you mean put the validation functions in foo.validation and import the ns a "v" so that I can use v/all v/odd v/or ?

8:35 AWizzArd: If you can use protocols, if they make sense, then they can free you from that naming problem. Otherwise you are only shifting it to some other level.

8:35 cemerick: ordnungswidrig: Yup. There's sometimes a bit of an art to naming the alias ("v" in your example), but it's the way to go.

8:35 AWizzArd: Namespaces or slightly differently named fns don't resolve polymorphically.

8:36 cemerick: AWizzArd: having name clashes is *not* a reason to use protocols.

8:36 Plenty of good reasons to do so, but none of them have anything to do with namespace issues.

8:36 ordnungswidrig: cemerick: so I end up with ((v/all (v/in :name (v/applied count (v/less-than 5))) (v/in :age (v/greater-than 20))) { :name "John" :age 16})

8:37 cemerick: using a clever macro I could eventually reduce this to (validate (all (in :name (applied count (less-than 5))) (in :age (greter-than 20))) ...)

8:38 cemerick: ordnungswidrig: sure. Alternatively, if you're using that namespace constantly, you could use the whole thing, and exclude or rename the same-named fns from other namespaces.

8:39 ordnungswidrig: Totally not worth it, IMO. namespaces are there to solve these issues, and make it obvious to those who come after you what's going on. A macro is just source-level obfuscation in this case.

8:39 ordnungswidrig: when I want to have an open set to validators which can be used as "keys" in the above dsl then I need to use some kind of registry, right? a map like { :all v/all :prime my.custom/prime }

8:39 AWizzArd: cemerick: for name clashes you are right. I just saw the indicator that ordnungswidrig likes to have many fns that should in principle have an identical name.

8:40 And this is a potentially a signal that Protocols may help.

8:40 ordnungswidrig: or I can omit a macro and use keywords: (validate :all [:in :name :applied :count :less-than 5] [:in :age :greater-than 20] ...)

8:40 cemerick: AWizzArd: Maybe, maybe. Without knowing more, I wouldn't recommend them, though.

8:41 ordnungswidrig: well, in that case, a macro makes a lot of sense, insofar as it would "compile" that DSL so that you don't have to do so at runtime.

8:41 AWizzArd: Yes, too early for a recommendation.

8:42 ordnungswidrig: AWizzArd: the validation shall be independent from the data type. you can validate a string against it's content or it's lenght. I don't see how protocols fall in place there.

8:43 AWizzArd: ordnungswidrig: and multimethods also can't help?

8:43 ordnungswidrig: cemerick: is there some support for DSLs like that in a lib? In my case it'd be rather simplistic

8:44 cemerick: ordnungswidrig: not sure I grok your question -- are you looking for an example of macro usage like that?

8:44 somnium: ordnungswidrig: you would be parsing :less-than-5 into #(< % 5) ?

8:44 AWizzArd: ordnungswidrig: it would be very much work to make it work with Protocols and strings. But you could invent funny Types, such as StringWithLessThan100Chars or StringThatContainsNoFs :)

8:44 ordnungswidrig: cemerick: I have a basic understanding of macros. I think I can go with it.

8:45 somnium: the predicates like #(< % 5) are lifted to be a validator which returns a map, e.g { :level :error :validator :less-than :info 5 }

8:46 cemerick: ordnungswidrig: OK. FWIW, enlive has a pretty extensive DSL for defining CSS selectors, which it compiles to finite state machines for walking HTML/XML nodes. That's not a simple example, but you can look at its API for an idea of how usage might look like your case?

8:46 ordnungswidrig: somnium: I need this to validate nested structures and consolidate on the error level

8:46 cemerick: that is a good idea!

8:47 unomi: Hi, anyone around?

8:47 ordnungswidrig: unomi: hmm, no :)

8:47 unomi: thats a shame :(

8:47 ordnungswidrig: are you a contributor?

8:47 cemerick: heh, this channel is hardly ever quiet anymore :-)

8:48 ordnungswidrig: unomi: contributor? no, I don't think so.

8:48 unomi: I am wondering if I could ask you guys some questions about your code repo

8:48 ordnungswidrig: pastie

8:48 cemerick: lisppaste8: url?

8:48 ordnungswidrig: where's clojurebot?

8:48 unomi: you are on assembla right?

8:48 cemerick: ordnungswidrig: OK, the bot's down, again :-/

8:48 AWizzArd: bot is sleeping

8:48 ordnungswidrig: bot is depressed

8:48 cemerick: unomi: that's where the issue tracker and dev wiki is.

8:49 unomi: would you recommend it?

8:49 cemerick: I'm not a huge fan, but it's worked for Rich's requirements.

8:49 ordnungswidrig: shall I gist or shall I pase...

8:50 s/e/t&/

8:51 For whom is interested: this is what I have for now: http://gist.github.com/301521

8:51 And the validator definition is a little verbose for my eyes.

8:52 jcromartie: somnium: is support for dbref planned in congomongo

8:53 AWizzArd: Oh, what is dbref?

8:53 Sounds like one of my data structures.

8:53 somnium: jcromartie: not currently. storing object-ids is just as effective with less ceremony

8:54 the-kenny: AWizzArd: a data type which refers to another entry in the database.

8:54 AWizzArd: good

8:54 jcromartie: dbref isn's a datatype

8:54 it's just a convention

8:54 the-kenny: oh ok, sorry

8:54 AWizzArd: And what is congomongo?

8:54 jcromartie: {$ref: "column_name", $id: "the object id"}

8:55 somnium: jcromartie: is there a use case where holding object-ids isnt sufficient?

8:55 the-kenny: AWizzArd: a client for mongodb in clojure

8:55 jcromartie: congomongo is a clojure wrapper around the Java mongodb driver

8:55 somnium: no but dbref is the convention in mongo

8:55 AWizzArd: And MongoDB is not relational but document oriented?

8:55 jcromartie: right

8:56 dbref optionally supports cross-database references

8:56 and it includes the collection name

8:56 it would enable automatic dereferencing language-side

8:57 somnium: jcromartie: well, theyre supported in the java-driver, so patches welcome

8:57 jcromartie: ah, cool

8:57 ok

8:57 I am a total n00b when it comes to these drivers :)

8:58 somnium: I just havent seen anyone use them :) its a map with :db, :object-id, :collection right? why not just use a map

8:58 but maybe Im not understanding

8:59 jcromartie: it is just a map

8:59 just a convention

8:59 http://www.mongodb.org/display/DOCS/DB+Ref

8:59 (or an object in JSON terms)

9:01 somnium: ah, they use it like an embedded query

9:01 well, patches welcome :)

9:13 esj: i'm using congomongo

9:13 admittedly, only for a couple of days now...

9:14 krumholt: can something bad happen if i throw an exception inside a transaction?

9:14 jcromartie: krumholt: that's what transactions are for

9:14 they don't commit if an exception is thrown

9:15 krumholt: so i can throw my own exceptions inside transactions?

9:15 jcromartie: yeah, but they don't bubble up

9:15 err, sorry, that's for agents

9:15 yeah you can throw your own

9:16 krumholt: ok thanks

9:17 AWizzArd: You can get Exceptions out of an agent, but it is a little bit hackish.

9:57 _fogus_: ,(cond nil 1 nil 2 :lollipop "POP")

9:58 Clojure-bot must be shoveling also

10:06 pdk: that gives "POP" in the console

10:08 chouser: pdk: clojurebot? Is that you?

10:09 pdk: in the form of an s expression please

10:09 chouser: pdk: (= you clojurebot)

10:09 AWizzArd: ~max people

10:09 clojurebot: max people is 246

10:09 esj: he's in disguise

10:09 pdk: now gotta define 'you'

10:09 esj: tired of being asked silly questions all day long

10:09 pdk: and where's the comma :|

10:19 powr-toc: Does anyone know why leiningen is setting my projects root directory to src/myproject, rather than the root directory where my project.clj file is???

10:19 lein swank - specifically

10:23 esj: never figured that out - using swank-clojure-project directly instead

10:23 powr-toc: esj: so I'm not the only one then? :-)

10:23 esj: well, you're in poor company, but not alone.

10:24 powr-toc: lol

10:24 Jomyoot: Does clojure.contrib.sql support talking to 2 db simultaneously

10:26 powr-toc: esj: swank-clojure-project does it too :-(

10:26 esj: oh, now you've lost even your poor company

10:26 mine asks me what the root directory is

10:27 powr-toc: esj: so does mine... but (import java.io.File) (. (File. ".") getAbsolutePath) tells me the JVM is running without that as its root dir

10:27 fdaoud: hi all

10:28 Jomyoot: I need to use 2 databases simultaneously. how do I do that with with-connection* ?

10:28 fdaoud: what's the easiest way to convert {:a 1 :b 2} to {"a" 1 "b" 2} ?

10:30 tomoj: hmm

10:30 ,(into {} (map (fn [[k v]] [(name k) v]) {:a 1 :b 2}))

10:30 clojurebot: {"a" 1, "b" 2}

10:30 powr-toc: Jomyoot: Don't know specifically, but with-foo's usually setup bindings, i.e. vars... so you should be able to nest them

10:30 tomoj: awfully ugly

10:30 fdaoud: I had

10:31 esj: powr-toc: you're correct - I dunno, i was referring to the root in the classpath, sorry.

10:31 tomoj: ,(letfn [(map-keys [f m] (into {} (map (fn [[k v]] [(f k) v]) m)))] (map-keys name {:a 1 :b 2}))

10:31 clojurebot: {"a" 1, "b" 2}

10:32 fdaoud: tomoj: i had something like that (but yours is better), but i thought there was a less convoluted way

10:32 powr-toc: esj: it seems like a bug to me

10:32 fdaoud: ,(let [m {:a 1 :b 2}] (apply array-map (map (fn [k v] [(name k) v]) (keys m) (vals m))))

10:32 clojurebot: {["a" 1] ["b" 2]}

10:32 tomoj: I can't think of one if you want a map back

10:32 Jomyoot: I don't see binding option

10:32 fdaoud: thx tomoj

10:33 that will only do the top-level, right, not any nested maps?

10:33 tomoj: indeed

10:33 powr-toc: Jomyoot: can you pastie your code?

10:33 AWizzArd: Jomyoot: you can not have an overlapping transaction anyway, so could you not just first query db1, retrieve all results you need, and then query db2 with the information from the first run?

10:33 tomoj: also note that's not lazy

10:34 Jomyoot: Because I don't want to open/close connections all the time.

10:34 I want to keep 2 DB connections open simultaneously

10:34 fdaoud: that's fine, i just need to pass the whole map to a Java method..

10:34 tomoj: ah

10:34 Jomyoot: (with-connection db -- opens up connection

10:34 fdaoud: but converting keywords to strings

10:34 tomoj: for nested maps it gets uglier :(

10:35 Jomyoot: THen I have (with-query-results rs -- to do the querying

10:35 AWizzArd: yes

10:35 Jomyoot: (with-query-results) does not allow me to specify which connection.

10:35 AWizzArd: do you know how to help me?

10:35 fdaoud: indeed....but I thought for sure someone else needed that and there was a built-in or contrib function

10:35 tomoj: (letfn [(map-keys [f m] (into {} (map (fn [[k v]] [(f k) (if (associative? v) (map-keys f v) v)]) m)))] (map-keys name {:a {:foo 3 :bar {:baz 4}} :b 2}))

10:36 I've often felt that way too

10:36 mapping over maps sucks

10:36 powr-toc: Jomyoot: which library are these functions part of?

10:36 tomoj: when you want a map back, anyway

10:36 AWizzArd: Jomyoot: I don't see how it is possible what you want to do without going to some manual use of Java functions.

10:36 Jomyoot: clojure.contrib.sql

10:36 AWizzArd: Otherwise I would suggest you to first do one query, close the conn, then open the second and run that query.

10:37 Jomyoot: is there a different/better library for sql?

10:38 hiredman: Jomyoot: they all use dynamic binding unfortunately

10:38 AWizzArd: I think nearly all of them concentrate on using one db at a time.

10:38 tomoj: hmm

10:38 AWizzArd: You can however open two connections manually.

10:38 Jomyoot: How would one deal with sharding/replication then?

10:38 tomoj: can't you get around it by messing with *db* yourself?

10:38 hiredman: AWizzArd: concenctrate is the wrong word

10:38 AWizzArd: :)

10:40 tomoj: or using the clojure.contrib.sql.internal functions?

10:40 * triyo is loving the handy letfn form

10:44 tomoj: (with-connection _ (let [db1 *db*] (with-connection _ (let [db2 *db*] _ (binding [*db* db1] _) (binding [*db* db2] _)))))

10:44 :(

10:44 of course you could wrap that up in a couple macros

10:44 hiredman: :|

10:45 tomoj: I guess you'd be better off rewriting clojure.contrib.sql

10:45 or wrapping it I mean

10:45 chouser: wow. that's what's wrong with having any args only passable via Var

10:45 hiredman: right

10:45 tomoj: clojureql doesn't do that, does it?

10:45 AWizzArd: chouser: what do you mean specifically?

10:46 chouser: AWizzArd: if looking at tomoj's code doesn't cause you pain, there's not much I can do for you.

10:46 er, that example in particular. not tomoj's code in general. :-)

10:46 tomoj: hehe

10:46 AWizzArd: ^^

10:46 Well, one could split it over several lines and nest it a little :-)

10:47 But really, maybe Jomyoot can simply call some .java methods and have two DBs open at the same time.

10:47 tomoj: it's still just fundamentally evil

10:47 well, there's get-connection in the internal ns

10:48 but the problem is, the functions for doing db ops don't care

10:48 you still have to bind *db*

10:48 * hiredman makes an addition to the coding guidelines thread

10:48 tomoj: huh, I guess clojureql does the same thing?

10:48 cemerick: I was wondering about this the other day -- so every fn should always have at least two arities, one that takes an explicit env (*db* in this case), and another that just delegates to the former using the current value of the bound env?

10:48 hiredman: yes

10:49 tomoj: whyyy

10:49 chouser: right, you should always be able to pass in everything you need via regular args. Clojure's print fns suffer from the same issue.

10:49 tomoj: I'm pretty sure I remember reading a discussion about this for clojureql quite a while ago

10:49 how did the var people win

10:49 cemerick: it makes the common case a lot cleaner, short of doing what I just suggested.

10:49 chouser: cemerick: I think so. It's ok to have separate fns if different arities are enough

10:50 tomoj: can we write a macro that makes it easy to do both?

10:50 chouser: aren't

10:50 cemerick: tomoj: that's just what I was thinking about

10:50 hiredman: all my database functions in clojurebot start with (binding [*db* db] ...)

10:50 chouser: (prn-to my-out foo bar)

10:50 tomoj: you need to specify what the implicit arg is and where it is in the args... would always first arg be good?

10:50 cemerick: trying to generally allow describe the various vars that might be in play is likely intractable tho

10:51 tomoj: in most cases, though, I think it's the first arg

10:51 chouser: hm. I bet if clojure's print fns did that it would help set the culter and expectations for other libs.

10:51 cemerick: arg position isn't the issue, its when there's multiple bindable vars

10:51 tomoj: though, a lot of these functions take &args I guess

10:51 chouser: rhickey: would you hate having prn-to, print-to, println-to, etc?

10:51 tomoj: cemerick: huh?

10:51 hiredman: cemerick: how often does that happen?

10:52 tomoj: it's usually just *db*, *server-hostname*, *out*, stuff like that, that I've seen

10:52 maybe the macro can ask for a suffix to tack on to the function names so arity isn't an issue

10:52 rhickey: chouser: no, prn-to or prn-on?

10:52 tomoj: e.g. for query you could have query-db

10:52 cemerick: hiredman: more than you'd suspect

10:53 once you're past trivial stuff, the usefulness of vars is hard to resist

10:53 chouser: rhickey: "to" seems more natural to me. or maybe "into"

10:53 fdaoud: tomoj: thanks for your help

10:53 hiredman: cemerick: I would argue the reverse

10:54 once you are past the trival stuff, rebinding vars makes a ball of string of your functions

10:54 tomoj: in any case the pattern of having a var to pick out a resource and then functions which interact with the resource is common

10:55 rhickey: chouser: not into, streams are not containers/collections

10:55 cemerick: in many cases, the choices are (a) have a pile of vars, (b) thread lots of args, or (c) ball up the environment into an uber-map

10:55 hiredman: :(

10:56 cemerick: (c)

10:56 cemerick: ugh. That's way messier than vars, IMO.

10:57 hiredman: cemerick: until you have to deal with two environments

10:57 cemerick: sure

10:58 I generally try to ensure everything I do is thread-bound anyway (e.g. not using pmap, etc) -- even I'm not using vars at the moment, one of the libs I'm using might, etc.

10:58 even if*

10:58 chouser: I'd be find with print-on, though that's not how I usually think of output streams.

10:59 hiredman: cemerick: :(

10:59 rhickey: generic vectors move forward: http://gist.github.com/301644

10:59 hiredman: so the fact that a library you use may be using vars means you are restricted to operating in a single thread?

11:00 and you are still pro-var?

11:00 rhickey: all that's left is a little macrology, but I've factored out the commonality so that only the little bits at the end need to be macros

11:01 cemerick: hiredman: I think for the vast majority of code, single-thread operation is just fine, and vars are often clearer and easier to work with compared to options (b) or (c). When I find a hotspot, then I cull that bit out, and ensure that I'm using options (b) or (c), and then pmap away or whatever.

11:02 again, I'm talking here about nontrivial situations where the "environment" is not just a single value, etc.

11:03 hiredman: cemerick: single threaded and single environment, no matter how many values are in the environment, is trivial

11:04 cemerick: compojure is a perfect example of this -- James is very much against vars, but being super-explicit about what data is going where when there's dozens of sources balled up in each request is extraordinarily tiresome. So, we've got some middleware that sets up ~ a dozen vars -- for params, url params, session state, current user, current account, blah blah.

11:05 hiredman: well, I don't like passing around large and opaque grab-bags of values.

11:05 hiredman: opaque?

11:05 how is a map opaque?

11:06 if anything a map is less opaque than vars, you can dump a map in a single call to prn, how do you do that for a bunch of vars?

11:07 chouser: rhickey: why definterface instead of defprotocol?

11:07 rhickey: chouser: int args :(

11:07 AWizzArd: I currently have a similar "dilemma". For my Clojure DB I will have transaction, and in those one states the DB. Now I am thinking: should I make insert/update/delete aware of this?

11:07 cemerick: hiredman: Because the available slots in a map can be changed at any time, and the only indication of that is the source code that does the modification. fn args are explicit about what's available, as are vars.

11:07 AWizzArd: (insert some-db obj) vs. (insert obj)

11:08 chouser: rhickey: oh, of course.

11:08 rhickey: I did prototype with a protocol, fwiw

11:08 chouser: easy to switch later. :-)

11:08 rhickey: extremely

11:08 chouser: I need to do something like that for finger trees

11:08 hiredman: cemerick: bound vars are even more susceptible to change via set!

11:08 AWizzArd: rhickey: did you notice the problem that I reported 3,5 hours ago?

11:09 With compiling deftypes that have slots which contain questionmarks? This fails under Windows XP.

11:09 rhickey: don't use question marks

11:09 AWizzArd: Why did you allow them in function names and vars?

11:09 chouser: right now my measure/reduce objects are little maps with functions in them. I need to allow use of primitives there.

11:09 AWizzArd: (def *is-null?* false) is fine.

11:10 cemerick: hiredman: I don't mean changing the values (though set! is a very rare operation), I mean changing the slots that are defined.

11:10 AWizzArd: also (defn even? ...) is allowed

11:10 why not (deftype Foo [a b is-null?])?

11:10 hiredman: cemerick: so?

11:10 AWizzArd: Those get automatically renamed to QMARK

11:10 cemerick: AWizzArd: deftype doesn't mangle field names to the same degree as vars, etc.

11:10 rhickey: chouser: I really need to bite the bullet and dig into the long/double arg/return support

11:11 at least definterface is dynamic now

11:11 AWizzArd: cemerick: yes, but is there a principle reason why it shouldn't?

11:11 hiredman: AWizzArd: deftype fields are java fields, and java fields cannot have ? in the name

11:11 chouser: rhickey: what's blocking ccinc? design improvement questions?

11:11 cemerick: AWizzArd: no, but I believe it's a low-priority item

11:12 rhickey: chouser: not much. I really want to find a nice way to work on it, together in a group

11:12 chouser: rhickey: is it not worth doing something closer to a straight port just to provide a better basis on which to do design improvements like you have on the wiki page as well as things like primitive arg/return?

11:12 AWizzArd: hiredman: the ? is no problem for Java at all. Only when I *compile* my code the problem shows up. Because the compiler tries to save the field name with a ? inside.

11:12 And Windows XP does not allow that.

11:12 If XP allowed questionmarks in files then all would be fine now.

11:13 rhickey: chouser: I'm not going to port the mutable bits, too hard to keep straight. But I think there is a simple mapping to protocols for the same abstractions

11:13 hiredman: AWizzArd:

11:13 foo.java:2: ';' expected int foo? = 0;

11:13 chouser: AWizzArd: I don't know that that would be true for all JVMs

11:13 AWizzArd: hiredman: I can type into my repl: (deftype Bar [a b c?])

11:13 chouser: rhickey: yes! ok.

11:13 hiredman: AWizzArd: it is not a filename issue

11:13 AWizzArd: This code gets compiled when I type enter.

11:13 cemerick: AWizzArd: and you won't be able to access the c? field from a Bar.

11:13 AWizzArd: And I can do (println (:c? (Bar 1 2 3)))

11:14 hiredman: AWizzArd: deftype's are different when AOT'ed

11:14 chouser: rhickey: protocols on plain maps?

11:14 rhickey: chouser: I'm very frustrated with the online design and collab tools

11:14 AWizzArd: cemerick: in my Clojure it works perfectly well.

11:14 rhickey: chouser: no, deftypes

11:14 fdaoud: ,(associative? ["a" "b"])

11:14 clojurebot: true

11:14 rhickey: protocol on plain map just begs how to dispatch

11:14 chouser: ok

11:14 fdaoud: yikes

11:15 cemerick: AWizzArd: Then your build has slightly better runtime mangling than mine, but apparently AOT'ing non-java field names isn't yet there. *shrug*

11:15 fdaoud: what is true for a map but false for a vector or list?

11:15 hiredman: fdaoud: vectors associate indexs to values

11:15 AWizzArd: I just found it to be a bit inconsistent to allow questionmarks in principle everywhere else, but not as slots for deftypes.

11:15 hiredman: fdaoud: map?

11:15 chouser: ,(map? [])

11:15 clojurebot: false

11:15 chouser: fdaoud: like that?

11:15 esj: fdaod: map?

11:15 fdaoud: chouser: yes, but that's so simple that I feel foolish now

11:15 cemerick: AWizzArd: AFAIK it's not a design decision, merely an implementation limit right now.

11:16 AWizzArd: Okay.

11:16 esj: rats.... that'll teach me to paste before seeing if somebody beat me to it....

11:16 AWizzArd: So, for now I will rename those guys then.

11:16 is-null-p comes to mind ;)

11:17 spariev: Hi, I'm getting reflection warning on (java.io.File. path) - call to java.io.File ctor can't be resolved

11:17 hiredman: why are you naming a field as a predicate anyway?

11:17 fdaoud: tomoj: so I changed associative? to map? since I want vectors and lists to stay intact

11:17 spariev: where should I put type hint ?

11:17 fdaoud: for example, {:a 1 :b ["a" "b"] :c {:d 5 :e 6}}

11:17 chouser: spariev: (java.io.File. #^String path) ... or on wherever path is defined in the first place.

11:18 AWizzArd: hiredman: rhickey did that himself too in some .java files, without the questionmark of course. It is nice for slots that will always be true or false.

11:18 spariev: chouser: many thanks

11:18 fdaoud: ,(letfn [(map-keys [f m] (into {} (map (fn [[k v]] [(f k) (if (associative? v) (map-keys f v) v)]) m)))] (map-keys name {:a 1 :b ["a" "b"] :c {:d 5 :e 6}}))

11:18 clojurebot: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassCastException: java.lang.Character cannot be cast to clojure.lang.Named

11:18 fdaoud: ,(letfn [(map-keys [f m] (into {} (map (fn [[k v]] [(f k) (if (map? v) (map-keys f v) v)]) m)))] (map-keys name {:a 1 :b ["a" "b"] :c {:d 5 :e 6}}))

11:18 clojurebot: {"a" 1, "b" ["a" "b"], "c" {"d" 5, "e" 6}}

11:18 chouser: spariev: np!

11:19 BrandonW: trying to come to terms with writing programs functionally: i have 2 vectors of the same number of elements. how do i transform the first vec so that it returns a new vec where each element is added to the element with the same index of the 2nd vector? is a list comprehension the only concise way to do that?

11:19 chouser: ,(map + [1 2 3] [10 20 30])

11:19 clojurebot: (11 22 33)

11:19 hiredman: ,(vec (map + [1 2] [3 4]))

11:19 clojurebot: [4 6]

11:19 BrandonW: errr

11:19 i even looked at map

11:19 but it didn't click for some reason

11:20 oh, i know. i was forgetting the optional multiple collections, heh

11:20 chouser: BrandonW: 'for' is for when you want to do something like a nested loop or a cross product, that is every item in seq1 with every item in seq2

11:20 BrandonW: 'map' is great when you want to walk two seqs in step.

11:21 BrandonW: gotcha

11:22 yeah functional programming is going to take a while to wrap my head around :) certainly brings the fun back in programming though

11:22 unfo-: literally ;)

11:22 fdaoud: lol

11:23 "Clojure puts the fun in functional"

11:23 unfo-: or rather, as i saw in a tshirt once, only functional programmers know real fun --- where the last 'fun' was in fixed width font ;)

11:24 tomoj: fdaoud: oh, yeah

11:24 forgot they were associative as well

11:24 fdaoud: I wouldn't have thought of that, but I guess it makes sense that it's index -> value

11:27 anyone here ever watched Night Court? there's a scene where a crazy lady is holding a gun (she thinks she's in a movie) and they're all trying to act a character from movies to try and convince her to give them the gun

11:27 they're going through so much trouble and then Bull just walks in and takes the gun from her.

11:28 this is how Clojure makes me feel vs. all the Java EE world..

11:29 all that ceremony and frameworks and layers and set up and dependency injection and AOP and....meanwhile with Clojure you just get things done.

11:31 Apage43: but then there's the other side, when you spend so much time writing this amazing thing, you finish, you're proud of it.. then you feel.. odd

11:31 because it's only.. 40 lines of code..

11:32 chouser: Apage43: heh. yeah.

11:32 or 10

11:32 Apage43: yeah that's worse.

11:33 phirsch: Hi all! I have a problem with file-str on Windows. Whenever a path contains "/" or "\", file-str throws an exception: "java.lang.StringIndexOutOfBoundsException: String index out of range: 1".

11:33 Looks like a bug in c.c.duck-streams/file-str to me, as it tries to replace "/" by "\" using java.util.regex.Matcher/replaceAll,

11:33 which in turn tries to interpret the "\" as the start of a numbered back reference.

11:33 Unfortunately, I do not have a CA yet, so I cannot post this on the google group.

11:33 Any ideas how to proceed with this?

11:33 AWizzArd: I single "\" should not be used.

11:33 A single one you can get by "C:\\mein\\pfad\\datei.txt"

11:34 fdaoud: ,(doc letfn)

11:34 clojurebot: "([fnspecs & body]); Takes a vector of function specs and a body, and generates a set of bindings of functions to their names. All of the names are available in all of the definitions of the functions, as well as the body. fnspec ==> (fname [params*] exprs) or (fname ([params*] exprs)+)"

11:34 phirsch: AWizzArd: sure, I used the string literal "\\", resulting in a single "\"

11:34 AWizzArd: phirsch: do you have a small text file directly in C:\?

11:34 If yes, please try: (slurp "/some.txt")

11:34 phirsch: AWizzArd: I'll try...

11:34 fdaoud: Apage43: you can add some documentation to make you feel better :)

11:34 stuartsierra: phirsch: please file a ticket

11:35 AWizzArd: okay, so it is a bug and I should not upgrade :)

11:35 chouser: phirsch: file-str in clojure.contrib.io on the master branch seems to work here. you must be using an older version?

11:38 stuartsierra: file-str should work fine on windows, it uses java.io.File/separator

11:40 phirsch: Ok, it works with slurp, but not with file-str:

11:40 user=> (file-str "c:/")

11:40 #<CompilerException java.lang.StringIndexOutOfBoundsException: String index out of range: 1 (NO_SOURCE_FILE:4)>

11:40 user=> (file-str "c:\\")

11:40 #<CompilerException java.lang.StringIndexOutOfBoundsException: String index out of range: 1 (NO_SOURCE_FILE:5)>

11:40 user=> (count (slurp "c:\\menu.lst"))

11:40 3057

11:40 user=> (count (slurp "c:/menu.lst"))

11:40 3057

11:41 chouser: phirsch: what version of contrib are you using?

11:42 hiredman: ,"c:\\"

11:42 clojurebot: "c:\\"

11:42 hiredman: ,"c:\"

11:42 clojurebot: EOF while reading string

11:42 phirsch: chouser: Should be 1.1.0 final, but I have checked the latest source on github, and there was no change to file-str.

11:42 hiredman: ,(doc file-str)

11:42 clojurebot: "clojure.contrib.duck-streams/file-str;[[& args]]; Concatenates args as strings and returns a java.io.File. Replaces all / and \\ with File/separatorChar. Replaces ~ at the start of the path with the user.home system property."

11:42 DeusExPikachu: is there an idiomatic way to get common lisp defvar behavior (conditional binding) with def?

11:43 hiredman: ,(use '[clojure.contrib.duck-streams :only file-str])

11:43 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol

11:43 hiredman: ,(use '[clojure.contrib.duck-streams :only (file-str)])

11:43 clojurebot: nil

11:43 tomoj: DeusExPikachu: not really idiomatic, but defonce

11:43 hiredman: ,(meta #'file-str)

11:43 clojurebot: {:ns #<Namespace clojure.contrib.duck-streams>, :name file-str, :file "clojure/contrib/duck_streams.clj", :line 86, :arglists ([& args]), :doc "Concatenates args as strings and returns a java.io.File. Replaces\n all / and \\ with File/separatorChar. Replaces ~ at the start of\n the path with the user.home system property.", :tag java.io.File}

11:44 tomoj: (I say not idiomatic because that's just the macro for it, doesn't seem like an idiom)

11:44 hiredman: ,(file-str "/")

11:44 clojurebot: #<File />

11:44 hiredman: ~def file-str

11:45 DeusExPikachu: tomoj, ok, you ever use like that before?

11:45 tomoj: I just realized that "defonce" is at least 10x better as a name than "defvar"

11:45 DeusExPikachu: true

11:45 tomoj: that's the right way to do it, I was just being pedantic

11:46 phirsch: chouser: The problem is file-str's use of java.util.regex.Matcher/replaceAll - which tries to interpret the replacement string (on Windows, that is a single '\') as a back-reference that should be followed by a number, but there is no number following it. On Unix, the replacement is a "/", which has no special meaning to replaceAll, and is therefore fine to use.

11:46 the-kenny: Oh, I didn't know about :strs and :syms while destructuring a map.

11:46 Awesome :) Thanks, Joy of Clojure :D

11:46 chouser: phirsch: ah, got it.

11:46 hiredman: phirsch: I don't believe java's regexs don't use \1 for back references

11:46 er

11:47 remove one of those don'ts

11:47 DeusExPikachu: ah, so defonce is the defvar of CL, cool

11:47 chouser: both are supported

11:47 phirsch: hiredman: You can choose to use "$x" and "\x" notations

11:47 hiredman: oh, I see

11:48 phirsch: Could someone file a bug for this?

11:48 stuartsierra: phirsch: ok, I see

11:48 fdaoud: tomoj: where does letfn come from?

11:48 chouser: fdaoud: it's a special form

11:48 stuartsierra: phirsch: I'll fix it

11:48 phirsch: stuartsierra: ;_)

11:48 tomoj: fdaoud: huh?

11:49 hiredman: ~def c.l.Compiler

11:49 fdaoud: (doc letfn) in my REPL gives java.lang.Exception: Unable to resolve var: letfn in this context (NO_SOURCE_FILE:1)

11:49 clojurebot: "([fnspecs & body]); Takes a vector of function specs and a body, and generates a set of bindings of functions to their names. All of the names are available in all of the definitions of the functions, as well as the body. fnspec ==> (fname [params*] exprs) or (fname ([params*] exprs)+)"

11:49 chouser: ,(.replaceAll (re-matcher #"/" "~/foo/bar/baz") "\\")

11:49 clojurebot: java.lang.StringIndexOutOfBoundsException: String index out of range: 1

11:50 tomoj: strange, I see it as a macro

11:50 hiredman: http://github.com/richhickey/clojure/blob/b63af1ad6ce38b50552be3c424ea166cb063ee7c/src/jvm/clojure/lang/Compiler.java?r=b63af1ad6ce38b50552be3c424ea166cb063ee7c#L4597

11:50 chouser: fdaoud: are using clojure 1.0 perhaps?

11:50 tomoj: I get that error for (doc letfn*) though

11:50 despite:

11:50 ,(letfn* [])

11:50 clojurebot: nil

11:50 chouser: because it's a special form

11:51 hiredman: most of the "special forms" are macros which emit a call to the real special form fn => fn* letfn => letfn*, etc

11:51 specials forms have no vars to hang a docstring on

11:51 chouser: ,(.replaceAll (re-matcher #"/" "~/foo/bar/baz") (java.util.regex.Pattern/quote "\\"))

11:51 clojurebot: "~Q\\EfooQ\\EbarQ\\Ebaz"

11:51 chouser: hehe

11:51 fdaoud: chouser: ah, my app is clojure 1.1.0 but the repl is 1.0.0 for some reason :/

11:52 hiredman: fdaoud: using lein?

11:52 what do you mean by "my app is clojure 1.1.0"

11:52 fdaoud: hiredman: maven

11:53 hiredman: fdaoud: that is a word

11:54 fdaoud: hiredman: ?

11:54 hiredman: fdaoud: you are going to have to give me more than a single word

11:55 fdaoud: hiredman: that's what I'm using: Maven (http://maven.apache.org)

11:55 hiredman: fdaoud: ok, and what does that have to do with "my app is clojure 1.1.0"

11:56 fdaoud: hiredman: my maven app is set up to use 1.1.0, but my plain command-line repl is on 1.0.0. now I figured out that I should use mvn clojure:repl to get a repl with the same environment as my app.

11:57 hiredman: sorry if I'm not making much sense.

11:59 hiredman: *shrug*

11:59 fdaoud: hiredman: lein is a build system?

12:01 stuartsierra: yes

12:01 hiredman: it uses some maven stuff internally

12:04 fdaoud: thanks, I'll have to check it out, everyone seems to be on it

12:04 stuartsierra: phirsch: pushed file-str fix to master

12:04 fdaoud: Not everyone :)

12:05 phirsch: stuartsierra: Thanks! :-)

12:05 fdaoud: stuartsierra: well, maven is just easiest for me right now, mvn jetty:run and it's a go

12:05 phirsch: stuartsierra: Looks good to me!

12:06 stuartsierra: Now try that with commercial software...

12:07 stuartsierra: ... I mean getting a fix within 5 minutes.

12:07 stuartsierra: yep

12:07 We aim to please.

12:08 phirsch: stuartsierra: Sounds like a motto for clojure ;-)

12:10 Is there an idiomatic way to use with-open (or any other resource-managing form for that matter) with lazy seqs? I have been tripped up by the stream already having been closed when I realize the seq later on. I suspect I should use some kind of closure?

12:11 hiredman: not for with-open

12:11 stuartsierra: phirsch: this is a common problem. A technical solution is in the works.

12:11 Chousuke: I think the most common thing to do is to use doall

12:11 stuartsierra: Yep, that's the simplest for now

12:11 hiredman: or move the code that uses the resource within the with-open

12:12 phirsch: Chousuke: The prohibitive size of the file was the reason to use the lazy seq in the first place...

12:12 cemerick: phirsch: There are cases where I don't particularly care whether something gets closed...there, I simply put the close in the terminating condition of the fn producing the lazy seq. *shrug*

12:12 That can bite in different ways, of course.

12:12 hiredman: phirsch: you can move the processing code inside the with-open

12:13 phirsch: cemerick: I see, that's what I was referring to as using a closure.

12:14 cemerick: phirsch: well, it's not even that complicated -- more like (if (whatever) (lazy-seq (this-fn other-args)) (.close data-source))

12:14 phirsch: hiredman: That's what I have done. But it still feels like a workaround. I wanted to turn a seq of filenames into a seq of java.io.File's and that in turn into a seq of lines - and all that lazily, if possible...

12:14 hiredman: ,(doc file-seq)

12:14 clojurebot: "([dir]); A tree seq on java.io.Files"

12:14 Chousuke: phirsch: there's already line-seq if you're fine with just reading the file line by line

12:14 phirsch: but you must consume the entire seq

12:15 hmm

12:15 phirsch: Yes, I was using file-seq and line-seq, but realizing the line-seq (outside of the function turning the seq of filenames into files) was where the closed stream bit me.

12:16 Chousuke: (mapcat line-seq (map #(File. &) filenames))

12:16 hiredman: ,(doc line-seq)

12:16 clojurebot: "([rdr]); Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader."

12:16 hiredman: ^- doesn't take a File

12:16 Chousuke: ah, damn.

12:17 phirsch: Chousuke: Will look at that - and see if it plays nicely with adding additional layers of using ZipInputStream and decryption on top...

12:18 Chousuke: anyway, the point is that you don't need to use with-open with line-seq

12:18 the stream is closed when all of it has been read.

12:18 BrandonW: i'm stumped again: how do i use the max function if i have a seq?

12:18 Chousuke: BrandonW: apply it :)

12:18 chouser: ,(apply max [1 2 3 4])

12:18 clojurebot: 4

12:18 BrandonW: ah yes, i remember now :)

12:19 cemerick: Chousuke: and even if it wasn't, the underlying inputstream would get closed upon GC.

12:19 BrandonW: it's weird when you read it in a book and you understand it completely, but then when you start writing code it seems to elude me :)

12:19 phirsch: Chousuke: That's another problem: The "File"s I am talking about are parts of a ZipInputStream, and when no more lines are available, I should not close the stream, but call .getNextEntry instead...

12:20 hiredman: phirsch: you have two resources open there

12:20 Chousuke: ah.

12:20 phirsch: hiredman: ?

12:20 hiredman: or you don't actually have a File

12:21 actually, you must not have a File

12:21 * hiredman doesn't actually remember how the zip/jar stuff works

12:22 phirsch: Yes, as written above, there are three sequences: involved: Filenames (of zip files), ZipInputStreams, and lines.

12:23 hiredman: You can do (java.util.ZipInputStream. anyotherinputstream)

12:23 hiredman: phirsch: you might want to look at ZipFile instead of ZipInputStream

12:23 phirsch: hiredman: java.util?

12:23 hiredman: http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/ZipFile.html

12:24 it has an entries() method so you can just get a collection of entries

12:25 ,(doc enumeration-seq)

12:25 clojurebot: "([e]); Returns a seq on a java.util.Enumeration"

12:25 phirsch: hiredman: Thanks for the hint, I somehow missed that. Have to find out how to use it with decryption (which Java itself does not support.)

12:27 hiredman: ugh

12:27 zipentries might not actually allow you to get the data

12:28 how horrible

12:28 oh, you have to pass the entry back through ZipFile

12:28 interesting choice there

12:35 phirsch: hiredman: Yes, that is exactly what I thought when I looked at this API.

12:43 avarus: hi!

12:44 stuartsierra: hi

12:46 cemerick: this "clojure has a runtime" stuff is irritating.

12:47 chouser: cemerick: namespaces and such?

12:48 cemerick: chouser: just the standard library constitutes a runtime, apparently: http://twitter.com/njbartlett/

12:52 stuartsierra: Clojure has a runtime, it's just a singleton.

12:54 chouser: well ... it has a few static fields of mutable object. I suppose those together consititue a runtime, don't they?

12:54 cemerick: that's pretty weak

12:54 for a language, to me, runtime == interpreter

12:54 clojurebot: I will hold the money!

12:55 cemerick: anyway, he's an osgi guy, so I'm hoping to find out what the beef is there.

12:57 chouser: I know essentially nothing of OSGi, but I did think that static fields of mutable things like that might be an issue, since you probably can't separate copies of them for independant scripts without also copying all of the clojure classes.

12:57 or something.

12:58 that sentence alone surely proves how much I don't understand. *sigh*

12:59 cemerick: there's apparently a distinct issue with using clojure across osgi bundles (e.g. http://twitter.com/njbartlett/status/8968196187), but there's no problem with the corollary in netbeans apps, so there's something particular to osgi going on there.

12:59 rhickey: (vector-int) or (gvector :int) ?

12:59 chouser: "gvector"?

13:00 rhickey: generic vector

13:00 chouser: there will only ever be long, double, or Object?

13:00 rhickey: no, all primitive types

13:01 byte,short,char,int,long,float,double,boolean

13:01 erm. maybe not boolean

13:02 chouser: I think that tips the scales for me to making it an arg. Not sure I like "gvector" though.

13:02 rhickey: now's a good time to suggest names :)

13:02 chouser: yes. thinking...

13:02 cemerick: pvector is probably linked to parallel, eh?

13:02 cgrand: (vector-of :int)

13:02 chouser: ooh!

13:02 cemerick: nixw

13:02 nice

13:03 rhickey: what's special about booleans?

13:03 rhickey: there are only 2 canonic values, so don't have the storage overhead of the other boxed primitives

13:05 chouser: a reference to a boolean is bigger than a byte, isn't it? of course you could also just use (vector-of :byte) then.

13:05 hiredman: ,(identical? true true)

13:05 clojurebot: true

13:06 hiredman: ideally it's all the same object

13:06 chouser: ,(if (Boolean. "false") "oops")

13:06 clojurebot: "oops"

13:06 hiredman: "2 canonic values" etc

13:06 chouser: hehe

13:07 hiredman: that is a Boolean anyway

13:07 chouser: right, but an array of Boolean length n probably takes about n*8 bytes on a 64-bit machine, doesn't it?

13:08 rhickey: chouser: true, I'll include it

13:08 hiredman: ,(identical? false (boolean (Boolean. "false")))

13:08 clojurebot: true

13:09 Drakeson: how would you store and update a simple map on disk?

13:09 hiredman: ,(doc prn)

13:09 clojurebot: "([& more]); Same as pr followed by (newline). Observes *flush-on-newline*"

13:10 * hiredman rolls eyes

13:10 hiredman: ,(doc pr)

13:10 clojurebot: "([] [x] [x & more]); Prints the object(s) to the output stream that is the current value of *out*. Prints the object(s), separated by spaces if there is more than one. By default, pr and prn print in a way that objects can be read by the reader"

13:12 Drakeson: hiredman: thanks, maybe I should have explained in more details.

13:13 I am looking for a [possibly] simple form of persistence

13:13 hiredman: ,(let [x {:a 1}] (read-string (pr-str x)))

13:13 clojurebot: {:a 1}

13:15 Drakeson: the problem is with the "update". I am looking for a way that is more efficient than reading the whole map for every update

13:15 do you know of a simple persistence library in contrib or otherwise in clojars ?

13:15 chouser: can you keep it in memory as well, so you only need to read it on startup?

13:16 hiredman: Drakeson: clojure maps are immutable

13:17 Drakeson: chouser: I am doing that, but I was hoping for a more efficient way (in terms of memory)

13:17 stuartsierra: someone wrote a persistent lib that does logging, don't remember what it was called

13:18 But at that point, you're implementing a database, so doing it correctly requires a vast amount of work.

13:19 chouser: I don't know of anything that (a) doesn't keep the whole db in memory and (b) isn't a full on DB with its own query language (SQL or otherwise), etc.

13:20 cemerick: wasn't there a tokyo cabinet wrapper floating around?

13:20 obviously a variety of (b), but a good options

13:21 * cemerick really needs to open source the jdbm wrapper he wrote months ago

13:22 noidi: how can I get stdout to be redirected to swank's REPL?

13:22 or some other readable buffer

13:24 rhickey: vectors of primitives: http://gist.github.com/301644

13:25 still needs some finish work, equality symmetry with vectors, j.u.Collection support, IFn etc

13:26 cemerick: whew, having the interfaces inline is rough in this kind of setting

13:26 rhickey: ?

13:26 cemerick: rhickey: when asking one's self, "what interfaces does this deftype implement"

13:27 rhickey: ah, yeah, I'd like some better highlighting support for deftype definitely

13:27 although it's stil la difficult question to answer in Java as well, will all the inheritance. I need IntelliJ's hierarchy browser for that

13:28 with all

13:28 hoeck: noidi: slime-redirect-inferior-output may work

13:28 cemerick: I guess that's what supers is for in general.

13:31 chouser: the type parameterization macro is amazingly small.

13:31 I must be doing something wrong...

13:32 hiredman: rhickey: collections support would mean boxing?

13:34 noidi: hoeck, it doesn't seem to work with a swank server (to which I connect with slime-connect), but thanks

13:34 rhickey: hiredman: there is dynamic boxing, even now for the Clojure collections interfaces which are object-based.

13:35 hiredman: I mean for the j.u.Collection interface

13:35 rhickey: the j.u.Collections would be the same. But under the hood the storage is primitives in both cases. It's strictly a matter of implementing all the j.u.collection interfaces

13:35 what's nice is Vec ended up being one type, not N types

13:35 hiredman: right

13:36 rhickey: N array managers

13:38 Drakeson: I thought clojure.contrib.duck-stream was renamed to clojure.contrib.io ; clojure-contrib-1.2.0-SNAPSHOT.jar still contains duck_stream$*

13:38 cemerick: rhickey: this is all pointing towards an endstate that will be quite remarkable. :-)

13:38 rhickey: what's fun is that these are faster than vector for most things

13:39 I think it's kind of a shame to have to use interfaces for primitive args, but it's all in Clojure at least

13:40 so, one thing that's not present is that the coercion ops truncate rather than balk on out-of-range

13:41 I can either 'fix' int/long/short coercions or make checking versions

13:44 chouser: this is something that's generally not available in Java container types outside of specialized math/vector libs, right?

13:44 sorry, I mean math/matrix

13:46 rhickey: chouser: apache has/had specialized containers per primitive type

13:46 the reason this hasn't been done is the on-the-fly boxing involved, probably prohibitive in the past

13:47 and so far, I haven't seen escape analysis doing to much across fn calls

13:47 so the big benefit here might be memory footprint

13:47 eyeris: I'm trying to setup NetBeans with the Enclojure plugin. When I load source code into the repl, I get FileNotFound exceptions for libraries that I've added to the NetBeans project's Libraries menu. Is there something more I have to do to make sure those libraries are added to the CP of the repl?

13:47 rhickey: until we get some ops that can reach into the representation

13:48 hiredman: IReduce, etc?

13:49 rhickey: hiredman: yeah that, but still as long a the reducing fn takes/returns objects, you'll need escape analysis to optimize away the ephemeral box

13:49 now, fns taking/returning long/doubles otoh...

13:49 hiredman: :D

13:49 cemerick: eyeris: classpath changes do not apply to running repls, you'll have to restart it

13:50 eyeris: cemerick: Do I have to restart NB to do that? I don't see a UI element to do so.

13:51 cemerick: eyeris: right-click in the repl window to restart it, or close the repl window and start a new one from the project node.

13:52 hiredman: "project node"

13:52 * hiredman giggles

13:55 eyeris: cemerick: When I right-click on the repl window, I see a Reset option, but that doesn't do anything (visually).

13:55 cemerick: eyeris: you should get a new prompt

13:55 hiredman: you're just that 133t :-P

13:56 eyeris: the enclojure devs hang out in #enclojure, BTW :-)

13:56 eyeris: Well I can't seem to kill that one, but I started a new one, which seems to work

13:56 cemerick: or some of them, anyway

13:56 eyeris: Thanks for your help.

13:56 cemerick: np

13:57 hiredman: "project node" "factory factory" how do you say these without at least a smirk

13:57 cemerick: well, I don't use any factory factories :-)

13:57 "project node" I have no problem with

13:58 hiredman: describe a project node for me

13:58 cemerick: it's the top-level representation of a single project, off of which a variety of operations hang.

13:59 surely not a new concept?

13:59 hiredman: isn't that just a project?

14:00 cemerick: yes, but in NetBeans, each icon in the project panel are called nodes

14:00 avarus: ahhh catch Exception reveals the BUG! :_)

14:00 odd, the same statement worked before

14:04 cemerick: OT: this seems properly inline with typical MS nuttiness: http://weblogs.asp.net/bleroy/archive/2008/01/18/dates-and-json.aspx

14:10 chouser: cemerick: it sure does

14:11 avarus: I don't get it...regarding contrib.sql: INSERT INTO todos (user_id,title,body,created_on,created_by,finish_on) VALUES ('1','foo','bar','11-02-2010','1','12-02-2010') <--this works perfectly in pgadmin but if I execute this statement via contrib.sql I get the error that the date is not a timestamp but a var char...:>

14:26 rhickey: why do unexpected test exceptions always report tes_clojure.clj?

14:26 ERROR in (test-pos?-zero?-neg?) (test_clojure.clj:77)

14:36 stuartsierra: rhickey: I need to look into that

14:37 I think it's because the exception gets caught at the top level.

14:40 I've been thinking that I should rewrite clojure.test with less macro magic and more functional-ness.

14:40 Drakeson: is clojure.contrib.prxml broken? it does not init

14:40 stuartsierra: Drakeson: ?

14:41 Drakeson: (require 'clojure.contrib.prxml)

14:41 java.lang.IllegalAccessError: escape-xml is not public (NO_SOURCE_FILE:0)

14:41 stuartsierra: That's a bug, something changed.

14:42 lazy-xml changed; I can fix that

14:42 fdaoud: is there something simpler than (or (list? a) (vector? a) (seq? a))

14:43 chouser: oh, I probably broke it. sorry.

14:43 cemerick: (or (sequable? a) (seq? a)) ?

14:44 stuartsierra: chouser: no problem, easy fix

14:45 fdaoud: cemerick: where does sequable? come from? contrib?

14:45 cemerick: no, it's in the stdlib; maybe starting with 1.1 though?

14:45 fdaoud: I'm on 1.1.0

14:46 cemerick: hrm. Well, I'm using a build from the 'new' branch from november :-/

14:46 stuartsierra: fdaoud: try (instance? clojure.lang.Sequential ...)

14:47 Drakeson: stuartsierra: thanks

14:47 tomoj: sequential?

14:48 ,(map sequential? [[] () (seq [1 2 3])])

14:48 clojurebot: (true true true)

14:48 fdaoud: excellent, thanks all

14:49 tomoj: this is for {:a [{:b 2} {:c 3}]}

14:49 our solution wasn't looking at maps inside e.g. vectors

14:49 cemerick: heh, I had forgotten about sequential?

14:49 I hardly ever use predicates like that.

14:50 fdaoud: cemerick: i'm just trying to convert a map (and all nested maps) from {:a ...} to {"a" ...} so that Java can use it.

14:50 stuartsierra: fdaoud: clojure.walk/stringify-keys will do that for you

14:50 tomoj: hehe

14:51 fdaoud: stuartsierra: omgwtfbbq

14:51 where were you this morning? :D

14:52 cemerick: bbq? :-)

14:53 fdaoud: http://www.thinkgeek.com/homeoffice/kitchen/aa6a/

14:53 cemerick: heh

14:54 fdaoud: stuartsierra: well thanks, i knew there had to be something already done for this. this was still a useful learning exercise.

14:56 eyeris: I have a ns macro on line 0. Later in my file (ns-resolve 'the.ns.named (symbol "function-name")) resolves the function, but (resolve (symbol "function-name")) returns nil, so somewhere I am changing the ns but I don't call in-ns anywhere. How else might I be changing the ns?

14:57 (ns-resolve *ns* (symbol "function-name")) also returns nil

14:58 Drakeson: debug it with (println *ns*) ?

14:58 eyeris: Yeah, it's set to clojure.core

14:58 stuartsierra: Drakeson: just pushed a fix

14:59 Drakeson: I mean, find the expression that changes the ns

14:59 stuartsierra: This is what happens when you don't have unit tests. :D

14:59 hiredman: eyeris: how are you loading the file?

14:59 eyeris: hiredman: it is from a jar packaged by netbeans

15:00 hiredman: eyeris: so it's AOT'ed?

15:00 eyeris: Yes

15:02 hiredman: come to think of it, it may not even be an AOT issue

15:02 cemerick: I've actually seen this once before, but just worked around it.

15:03 and it wasn't in AOT'd code

15:03 hiredman: resolve is runtime

15:04 lisppaste8: url

15:04 guh

15:04 Drakeson: eyeris: what happens if you place (resolve (symbol "function-name")) right after the (ns) ?

15:04 stuartsierra: thanks

15:04 hiredman: http://gist.github.com/301896

15:05 the function that calls resolve runs in the namespace that calls it

15:05 so resolve runs in that namespace

15:05 Raynes: hiredman: What namespace do you run in? :D

15:05 hiredman: in this case your -main is being called by clojure.core

15:06 well, something in clojure.core

15:06 eyeris: Oh! that makes sense, since the main change I made was sticking the mainline code into a -main

15:07 Although, wait. -main doesn't call (resolve)

15:07 resolve is called down the stack a ways

15:08 Does that matter?

15:08 hiredman: yes

15:08 well no

15:08 I mean no

15:09 *ns* is 'clojure.core unless something in the stack says otherwise

15:09 eyeris: Drakeson: nothing happens if I put (println *ns*) right after the (ns ...) call.

15:10 hiredman: th ns form has nothing to do with it

15:10 the

15:11 between clojure.core and the call to your.namespace/-main nothing changes the value of *ns*

15:14 *ns* has a runtime value and a compile time value, resolve is the runtime value

15:14 eyeris: Okay. In my.ns/-main I call my.ns/run-report as (run-report). I've confirmed that *ns* is clojure.core in -main. Why does the call to (run-report) not result in a resolution error?

15:14 I guess that answers it.

15:14 hiredman: eyeris: because at compile time the value of *ns* is my.ns

15:15 (defmacro capture-ns [] @#'*ns*) (def this-ns (capture-ns))

15:15 eyeris: So I can call (in-ns my.ns) in -main

15:16 hiredman: eyeris: better to just pass the namespace as an arg to ns-resolve if you go that route

15:16 * Drakeson mumbles something about perl ...

15:16 hiredman: ,(doc create-ns)

15:16 clojurebot: "([sym]); Create a new namespace named by the symbol if one doesn't already exist, returns it or the already-existing namespace of the same name."

15:17 Chousuke: hiredman: isn't @#'*ns* exactly equivalent to *ns*? :/

15:18 hiredman: no

15:18 well

15:19 maybe close enough

15:19 I just wanted to be sure to capture the value at macro expansion time and not at runtime

15:19 which I guess just *ns* would do

15:19 Chousuke: yeah

15:20 eyeris: hiredman: Does ns-resolve work with aliased namespaces?

15:20 hiredman: eyeris: define "work"

15:20 if *ns* were private @#'*ns* would get you the value anyway :P

15:20 eyeris: e.g. (ns my.ns (:require [my.ns.level.two as :alias]))

15:21 Can I then call (ns-resolve 'alias ...)?

15:23 The reason is that this function looks up named ranges in Excel spreadsheets, then tries to resolve a function corresponding to the name, then interpolates the results of the function into the spreadsheet.

15:24 Specifying the namespace would require that I change it from project to project

15:25 tcrayford: how do I define a function that only takes a seq of args?

15:25 I'm thinking something like (defn foo [& args] blah)

15:25 but this doesn't seem to work

15:25 Chousuke: that would take any number of args

15:25 you want just (defn foo [aseq] ...)

15:26 tcrayford: nah I want the any number of args actually

15:26 described the problem wrong

15:26 I have the following function definition:

15:26 (defn td

15:26 [& args] (map #(vector :td) args))

15:26 and passing any arguments to it results in an illegal number of arguments exception

15:27 oh

15:27 yeah fixed

15:27 didn't call % in the anon function

15:27 Chousuke: heh.

15:27 tcrayford: though that shouldn't be an illegal number of args thing

15:28 ,(vector 1

15:28 clojurebot: EOF while reading

15:28 tcrayford: ,(vector 1)

15:28 clojurebot: [1]

15:28 tcrayford: seeing as that works

15:28 Chousuke: it is. the anonymous function takes no args

15:28 tcrayford: ahhh

15:28 Chousuke: and map requires a function that takes one in this case.

15:28 tcrayford: yeah makes sense

15:28 #() forms are confusing sometimes here

15:30 hiredman: (partial vector :td)

15:30 :D

15:30 tcrayford: yeah that's nicer

15:31 and tests still pass

15:31 chairs

15:31 hiredman: ,::D

15:31 clojurebot: :sandbox/D

15:35 tcrayford: on other notes, http://katas.softwarecraftsmanship.org/?p=154

15:36 feedback from you guys would be very much appreciated

15:37 avarus: ok, it seems I have to convert my data with (.setTimeStamp foobar)

15:37 but apparently contrib.sql doesn't touch pgsql anymore :)

15:38 eyeris: What is the correct syntax for (create-ns)?

15:38 hiredman: ,(doc create-ns)

15:38 clojurebot: "([sym]); Create a new namespace named by the symbol if one doesn't already exist, returns it or the already-existing namespace of the same name."

15:38 hiredman: ,(create-ns 'foo)

15:38 clojurebot: #<Namespace foo>

15:38 hiredman: ,(create-ns 'sandbox)

15:38 clojurebot: #<Namespace sandbox>

15:38 eyeris: (create-ns my.ns) and (create-ns 'my.ns) both throw java.lang.IllegalArgumentException: Don't know how to create ISeq from: Symbol

15:38 hiredman: ,(identical? (create-ns 'sandbox) *sn*)

15:38 clojurebot: java.lang.Exception: Unable to resolve symbol: *sn* in this context

15:38 hiredman: ,(identical? (create-ns 'sandbox) *ns*)

15:38 clojurebot: true

15:39 hiredman: eyeris: then you are doing it wrong

15:41 eyeris: Alright, I fixed that. (I had it out-side my do) But now it says Can't change/establish root binding of: *ns* with set

15:42 hiredman: eyeris: stopping using set!

15:42 eyeris: I'm not. I'm using (in-ns)

15:42 hiredman: ~def in-ns

15:42 clojurebot: No entiendo

15:42 hiredman: bah

15:42 what do you think in-ns does?

15:42 12:19 hiredman : eyeris: better to just pass the namespace as an arg to ns-resolve if you go that route

15:43 eyeris: Yeah, it sets *ns*

15:43 hiredman I exaplained why that's not a good option.

15:43 I don'

15:44 hiredman: 12:18 hiredman : (defmacro capture-ns [] @#'*ns*) (def this-ns (capture-ns))

15:44 unfo-: btw. how does clojurebot's execute work? does it work with REPL or something else?

15:44 eyeris: I don't want to use in-ns. I want to be able to use (ns-resolve) with a compile-time evaluation of *ns*

15:44 That didn't work.

15:45 Maybe I used it wrong?

15:45 hiredman: eyeris: what does "doesn't work" mean?

15:46 eyeris: It still used clojure.core

15:47 hiredman: eyeris: what do you mean by "It"

15:47 eyeris: Your capture-ns macro

15:47 hiredman: eyeris: how did you use it?

15:47 eyeris: I tried both (ns-resolve (capture-ns) sym) and (ns-resolve (this-ns) sym)

15:47 To be honest, I don't understand how it is supposed to work.

15:49 hiredman: if you ran (ns-resolve (this-ns) sym) you should have gotten an exception

15:49 did you?

15:49 eyeris: No

15:50 hiredman: eyeris: then you didn't run it

15:52 that macro and the def may not actually even compile

15:52 (AOT compile, they will of course work at the repl)

15:53 eyeris: They compiled.

15:53 So I just looked really hard at it.

15:53 avarus: how can I define some data to be http://java.sun.com/j2se/1.5.0/docs/api/java/sql/Timestamp.html :)?

15:53 eyeris: And it looks like I should call (capture-ns) at the top of my fn

15:53 then use this-ns instead of *ns*

15:53 Is that right?

15:53 hiredman: eyeris: no, you don't call capture ns in your fn

15:54 you need to call it outside your fn, in the def I suggested

15:54 eyeris: I must have missed that in my scroll-buffer.

15:54 hiredman: avarus: you use the constructors to make one

15:55 12:18 hiredman : (defmacro capture-ns [] @#'*ns*) (def this-ns (capture-ns))

15:55 eyeris: Omg! PARENS!

15:55 I mis-read that totally

15:56 That makes a lot more sense now.

15:56 hiredman: as Chousuke pointed out, you should be fine leaving off the swearing "@#'"

15:57 eyeris: That works. Thank you for being patient with me.

15:57 hiredman: :)

15:59 stuartsierra: avarus: Just make an instance: (Timestamp. 1234567890)

16:04 BrandonW: if i want to join two vectors together, is this the correct way to do it: (into second-part (reverse first-part)) ?

16:04 tcrayford: try concat

16:04 BrandonW: ah

16:04 tcrayford: ,(concat [1 2 3] [1 2 3])

16:04 clojurebot: (1 2 3 1 2 3)

16:04 hiredman: BrandonW: why are you reversing the second part?

16:04 first part

16:04 whichever, the second vector

16:04 fdaoud: ,(into [1 2 3] [1 2 3])

16:04 clojurebot: [1 2 3 1 2 3]

16:04 BrandonW: well because if i didn't, then the elements would be in the wrong order

16:04 hmm

16:04 hiredman: are you sure?

16:04 BrandonW: no

16:04 :)

16:05 let me take closer look

16:05 stuartsierra: only if they're lists

16:05 BrandonW: well i perform some operations on them

16:05 they get returned as sequences, but that doesn't change them from being vectors, right?

16:05 hiredman: BrandonW: of course it does

16:05 BrandonW: oh

16:05 hiredman: a sequence is not a vector

16:05 avarus: stuartsierra: yessir, it didn't throw an error but there wasn't any changes in the db: http://pastie.org/820783 <-- that's how I did it

16:06 stuartsierra: avarus: I dunno, that may be something to do with how c.c.sql talks to the database

16:06 avarus: ya :P

16:07 BrandonW: ,(class (rest [1 2 3]))

16:07 clojurebot: clojure.lang.PersistentVector$ChunkedSeq

16:07 BrandonW: that looks like a vector

16:07 chouser: no, it looks like a seq

16:07 ,(vector? (rest [1 2 3]))

16:07 clojurebot: false

16:08 chouser: ,(seq? (rest [1 2 3]))

16:08 clojurebot: true

16:08 stuartsierra: Hey contrib authors: wanna help me factor out c.c.java (formerly java-utils?)

16:08 BrandonW: so it isn't a vector or a list

16:08 it is a seq

16:08 triyo: $ChunkedSeq is a inner class

16:08 chouser: it's a kind of seq that happens to be defined inside the PersistentVector class, but it's a seq

16:08 danlarkin: stuartsierra: factor out how?

16:08 BrandonW: okay, so you know the output was derived from persistent vector, but it isn't of that type any more

16:09 ok

16:09 chouser: even that detail doesn't make if very far down a chain of seq ops

16:09 ,(class (filter odd? [1 2 3]))

16:09 clojurebot: clojure.lang.LazySeq

16:09 hiredman: ,(class (map inc [1 2]))

16:09 clojurebot: clojure.lang.LazySeq

16:10 stuartsierra: danlarkin: Fix all the libs that use c.c.java to use the other namespacse

16:10 hiredman: ,(class (cons 2 (map inc [1 2])))

16:10 clojurebot: clojure.lang.Cons

16:10 stuartsierra: I mentioned I was going to do this on the dev list

16:10 hiredman: ,(class (filter even? (cons 2 (map inc [1 2]))))

16:10 clojurebot: clojure.lang.LazySeq

16:10 stuartsierra: http://groups.google.com/group/clojure-dev/browse_thread/thread/b4acea9c95a9cfe9#

16:10 Pushed a new branch to github, "drop-java"

16:10 Just need some help finding all the usages and fixing them.

16:11 danlarkin: wall-hack-* getting a name change is probably a good idea :)

16:11 stuartsierra: yes

16:11 It's now c.c.reflect

16:11 Per Halloway's suggestion

16:12 hiredman: :(

16:12 danlarkin: although whoever came up with that name originally is a genius

16:12 hiredman: <--

16:12 stuartsierra: I never understood what it meant.

16:12 hiredman: clojurebot: hiredman

16:12 clojurebot: hiredman is an evil genius.

16:12 danlarkin: well then you had a sad childhood!

16:12 :-p

16:12 stuartsierra: clojurebot: stuartsierra

16:12 clojurebot: stuartsierra is volunteering

16:12 stuartsierra: Ha!

16:12 fdaoud: clojurebot: danlarkin

16:12 clojurebot: Gabh mo leithscéal?

16:13 hiredman: http://en.wikipedia.org/wiki/Cheating_in_online_games#Wallhacking

16:13 fdaoud: clojurebot: fdaoud

16:13 clojurebot: Gabh mo leithscéal?

16:13 fdaoud: clojurebot: rhickey

16:13 clojurebot: Gabh mo leithscéal?

16:13 triyo: clojurebot: clojurebot

16:13 clojurebot: clojurebot is like life: you make trade-offs

16:14 fdaoud: clojurebot: chouser

16:14 clojurebot: Who??

16:14 danlarkin: ookay that's enough

16:14 triyo: haha

16:14 fdaoud: you started it

16:14 stuartsierra: Seriously, though, can people with commit access pitch in to fix this?

16:14 boojum: hello world

16:16 eyeris: Is there a good example of how to use clojure.set.join?

16:16 * chouser pulls

16:16 hiredman: /

16:16 it is clojure.set/join

16:17 eyeris: Right.

16:17 hiredman: ,(doc clojure.set/join)

16:17 clojurebot: "([xrel yrel] [xrel yrel km]); When passed 2 rels, returns the rel corresponding to the natural join. When passed an additional keymap, joins on the corresponding keys."

16:17 tcrayford: github.com/relevance/functional-koans, see the clojure branch on sets

16:17 * danlarkin is not a contrib committer :'(

16:17 * hiredman is not either :D

16:17 tcrayford: (and run through the whole thing, its useful)

16:17 hiredman: ,(clojure.set/join #{:a :b} #{:c :d})

16:17 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword

16:18 * kotrin says "me three"

16:18 eyeris: Thanks tcrayford

16:19 stuartsierra: Argh, anyone remember how to push a new update on a remote branch?

16:20 tcrayford: git push origin branch-with-the-same-name-as-remote-branch

16:20 chouser: stuartsierra: I see only json, http.connection, pprint, and test-java

16:20 tcrayford: at least that's all I've ever done

16:20 cemerick: or git push origin local-name:remote-name

16:20 chouser: stuartsierra: does that seem right?

16:20 stuartsierra: tcrayford: yeah, not working, says eveyrthing is up to date

16:20 tcrayford: git status?

16:21 stuartsierra: chouser: yes, I thought it was more than that actually

16:21 tcrayford: :P

16:21 stuartsierra: "On branch drop-java \n nothing to commit"

16:21 tcrayford: weiird

16:21 hiredman: stuartsierra: what does git remote say?

16:22 chouser: stuartsierra: Should I do pprint?

16:22 stuartsierra: chouser: yes, thanks

16:22 hiredman: is origin the right repo?

16:22 stuartsierra: hiredman: yes, git@github.com:richhickey/clojure-contrib.git

16:22 chouser: oh, jmx is there too

16:22 hiredman: *shrug*

16:22 stuartsierra: " Tracked remote branches

16:22 1.0.x 1.1.x clojure-1.0-compatible drop-java gh-pages master maven new"

16:22 arohner: are pre & post conditions supported on multimethods yet?

16:23 the-kenny: how can I convert \r\n to the native newline of the os?

16:24 stuartsierra: Oh, maybe it's just Github not showing the commit yet...

16:24 tcrayford: github can be kinda slow sometimes

16:24 chouser: stuartsierra: what broke with lazy-xml earlier? it wasn't escape-xml was it?

16:26 stuartsierra: chouser: yes, it was escape-xml

16:26 LauJensen: Guys - What is the simplest class(es) which allow me to load an image from a while, and then poke at the pixels, like (getColor 15 15) ==> RGB(1,2,3) ?

16:29 hiredman: ImageIO

16:29 ~jdoc javax.imageio.ImageIO

16:32 LauJensen: Sank ju!

16:35 Ah yes now I remember - This was the class which borked with OpenJDK

16:35 Always use it with Oracle JDK instead

16:35 chouser: stuartsierra: only jmx is left, I think. Are you on it?

16:37 stuartsierra: chouser: yes

16:37 chouser: thanks

16:37 chouser: hardly anything, but you're welcome. thanks for leading up such efforts.

16:37 hiredman: LauJensen: really? I've never had it not work

16:38 possibly it supports a different set of image formats on the openjdk

16:38 LauJensen: hiredman: For outputting jpegs with certain color models, it would just emit black images. I struggled with it for hours until I flushed OpenJDK, then it worked

16:39 hiredman: interesting

16:41 stuartsierra: I'd be done now, if only scgilardi weren't so clever about abbreviating his lib names...

16:42 (:use (clojure.contrib [java :only ...])) hmph

16:42 chouser: ooh, my grep didn't catch those.

16:42 stuartsierra: mine either

16:43 chouser: want me to do sql or miglayout?

16:43 stuartsierra: I've started sql,

16:43 avarus: holy moly

16:43 stuartsierra: go for miglayout

16:43 avarus: I'm missing out columbo for that shit timestamp issue :P

16:46 Nikelandjelo: Is there any function to merge 2 or more sequences? I can't find :(

16:47 stuartsierra: ok, pushed c.c.sql fixes

16:48 chouser: pushed miglayout

16:48 3 times before I quit comflicting with you. :-)

16:48 stuartsierra: oops

16:48 ok, testing now

16:48 boojum: Nikelandjelo, interleave?

16:48 chouser: I assumed that was possible with git, but never actually ran into it before.

16:49 hiredman: http://www.thelastcitadel.com/lab/contrib.svg

16:49 stuartsierra: chouser: I guess that's why we're supposed to work on separate branches and merge. Oh well.

16:49 Tests pass, preparing to merge on master.

16:50 Pushed to master.

16:50 Deleting 'drop-java' branch

16:50 chouser: we'll have to do something like this again for libs that go from clojure.contrib.foo -> clojure.foo, right?

16:51 stuartsierra: yep

16:51 I've been doing this kind of thing for a couple of weeks.

16:51 chouser: and once that's done, I'll have to go through and fix the book...

16:51 stuartsierra: yep

16:51 Renaming's a bitch.

16:52 hiredman: http://www.thelastcitadel.com/lab/contrib.svg <-- updated

16:52 chouser: do they have any refactoring tools for markdown? :-P

16:52 hiredman: good! so much clearer now!

16:52 hiredman: :P

16:53 I completely forgot about clojure-dependency-grapher

16:53 avarus: stuartsierra: what have you changed?

16:55 stuartsierra: avarus: just posted to the main list

16:56 avarus: ok

16:57 stuartsierra: Wait, dammit, did I just delete one of the commits?

16:58 yes, miglayout

16:58 fixed, pushed

16:58 * stuartsierra is running tests

16:59 avarus: btw. I changed my database field type to text now instead of timestamp :(...there doesn't seem to be a way to insert timestamp values for now

16:59 stuartsierra: test-java is still there

17:00 avarus: omg.-..now I have the same error just with integer :(

17:01 stuartsierra: Ok, NOW the tests pass.

17:05 * stuartsierra wants a refactoring tool

17:07 rhickey: ok, vector-of is up. help welcome in bringing it over the goal line

17:07 also feedback on use/perf

17:11 ulfster: hi there, anybody knows if it is possible to add headers to a response in compojure, when using the defroutes macro?

17:12 hiredman: bleh, the .io nic is $100 a year

17:12 arohner: ulfster: yes, it's possible

17:13 the response is just a map, and headers is a key

17:13 ulfster: i got a route like (GET "/url" (myFunction))

17:14 inside the route i return (html someStuff)

17:14 how do i add the headers in this case?

17:15 chouser: rhickey: awesome!

17:15 arohner: return {:status 200 :body (myFunction) :headers { "HeaderName" value}}

17:15 ulfster: which header do you want to return? there are helper functions for several common ones, like mime type and cache control

17:15 if it's a one off, you can do what I wrote above

17:16 or you can write a middleware, which is a wrapper function that modifies the response

17:16 ulfster: i want to set a cookie, but that happens conditionally inside myFunction

17:16 rhickey: chouser: if nothing else, it proves the deftype stuff and relatively ordinary clojure code is as fast as the Java implementation

17:16 arohner: in that case, you want to call session-assoc

17:17 it should be part of the return value

17:17 rhickey: hrm, I guess it is kind of primitive code :)

17:17 well, let's say it proves you can write the bottom layer in Clojure

17:18 arohner: [ (session-assoc cookie-map) (myFunction)]

17:18 ulfster: FYI, there's also a #compojure, but it's pretty quite

17:18 *quiet

17:18 ulfster: ok, thanks, i will try it from here

17:22 arohner: awesome, it worked! thanks a lot!

17:22 arohner: ulfster: great

17:24 BrandonW: do clojure newbies tend to get bitten by lots of vector/list/seq issues?

17:47 ska2342: Hi. Currently I'm trying to get rid of a particularly Perlish way of thinking and to find a functional way of parsing file-formats which were created with line by line parsing and state-keeping in mind. E.g. the popular ini-file format. Can you give me any pointers?

17:48 avarus: how can I call java.sql.Timestamp.valueOf("some value") from inside clojure?

17:48 hiredman: ska2342: is there a reason you can't use java.util.Properties?

17:49 avarus: http://clojure.org/java_interop

17:49 avarus: I'm there for 30mins now :P

17:49 ska2342: escaping to Java is one possibility for just solving the problem, sure. However, I'd like to adjust my rather Perl-influenced thinking ;-)

17:50 hiredman: ska2342: why is it escaping?

17:50 a library exists to do what want you want

17:50 use it

17:50 avarus: so what is the problem?

17:51 it's very clear

17:51 ska2342: hiredman: because it's not functional. I know how well it is integrated and that it is perfectly acceptable, even encouraged, to do so.

17:51 avarus: too few examples, too many possibilities :)

17:51 no, for me it's not

17:51 that's why I am asking

17:51 I came up with something like this: (java.sql.Timestamp. (.valueOf (str "2005-04-06 09:01:10"))))

17:51 but I get "no matching field" :>

17:52 hiredman: avarus: why would you expect that to work?

17:52 avarus: it compiles and doesn't look too strange :)

17:52 hiredman: the interop page says ClassName. is the same was (new ClassName)

17:53 avarus: ya, I know

17:53 so?

17:53 hiredman: so you are constructing a new Timestamp argument and pass the result of (.valueOf (str "2005-04-06 09:01:10"))) to the constructor

17:53 avarus: ah oh

17:54 hiredman: what is the signature of the method you are trying to call?

17:54 ska2342: avarus: if I understand it correctly, the answer to your question is right on the top of the page, hiredman suggested.

17:54 avarus: ya, it was!

17:55 but the example wasn't clear enough :)

17:55 (java.sql.Timestamp/valueOf (str "2005-04-06 09:01:10")) <-- I didn't know you could write it like this

17:55 I'm struggling with this shit for over an hour now

17:56 hiredman: what is not clear about it?

17:56 avarus: but that works perfectly now

17:56 ska2342: avarus: do you need the str at all?

17:56 hiredman: (Classname/staticMethod args*) ; exactly the same was what you just wrote

17:56 avarus: I don't know what. I can only tell that it confused me and I wrote the stuff in all kinds of variants

17:57 ska2342: no :)

17:57 works without

17:57 hiredman: why did you have the call to str in the first place?

17:57 avarus: ska2342: oh, apparently it's needed

17:58 hiredman: avarus: why do you say that?

17:58 avarus: hiredman: please relax; I'm not a pro like you and if you don't feel like helping me, don't do it; i'm not taking it personal

17:58 why? because it fails without :P

17:58 hiredman: what makes you think I am not relaxed?

17:58 ska2342: It fails with what message?

17:59 avarus: java.lang.String cannot be cast to clojure.lang.IFn

17:59 hiredman: avarus: why would it be trying to treat the string as a fn?

17:59 ska2342: Maybe you omitted the str but kept the parens?

17:59 hiredman: ska2342: shhh

17:59 avarus: ska2342: yep, the parens were still there :) thx

17:59 ska2342: hiredman: uhm, sorry, to fast and beyond the lesson ;-)

18:00 avarus: the lesson not to help :>?

18:00 come on guys

18:00 hiredman: to ask questions until we find one you know the answer to, and work from there

18:00 ska2342: avarus: hiredman is asking the important questions and therby helping a lot if you solve them.

18:01 avarus: heh, the problem is I don't understand

18:01 ska2342: .. just in my case he didn't get the intent of the question ;-)

18:01 avarus: my question was very simple :)

18:02 hiredman: that is a problem, but you are not a tabula rasa, you have some guess

18:02 guesses

18:02 avarus: for him it would take a second to answer

18:02 and I would understand

18:02 but this way we only wasted so many lines here

18:02 for nothing :)

18:02 hiredman: I'm trying to teach you to fish

18:03 ska2342: avarus: I happen to disagree; it's just not giving the quick solution but paving the way.

18:03 hiredman: but feel free to /ignore

18:03 avarus: ska2342: if you followed the chat I was having this problem with interop almost two hours ago :)

18:03 and since then I experimented a lot

18:04 ska2342: anyway, need some sleep. Cheers :-)

18:04 avarus: read that page about interop, looked at some examples at github etc...

18:04 there is some time where a "pro" just knows the answer

18:05 hiredman: I never ignored anyone :)

18:09 arohner: I have a text file living in the source directory of my app. Is there a way to get the path to the file, without hardcoding the location?

18:12 like using getResource(), or something like that?

18:13 hiredman: are you using lein?

18:13 arohner: no

18:13 hiredman: so it's in the source directory?

18:13 and that is on the classpath?

18:13 arohner: yes, and yes

18:14 avarus: (System/getProperty "user.dir") works for me

18:15 hiredman: arohner: http://github.com/hiredman/clojurebot/blob/master/src/hiredman/clojurebot.clj#L22

18:15 clojurebot.properties is a file at the root of a directory on the classpath

18:16 the (fn []) is kind of an interesting wrinkle, and I kind of forget why I did that

18:16 previously it was (-> clojure.lang.RT (.getRe...

18:16 arohner: thanks

18:17 maybe it has something to do with clojure classloaders getting GC'd

18:17 ?

18:17 hiredman: I don't think so

18:17 I think it was when I started using lein for clojurebot, which was when I start aot compiling it

18:31 avarus: thanks for the clarification on the interop problem I had, hiredman ...

18:31 ... and good night :)

19:03 abrenk: If I want to implement the following pseudo code "repeat (64): ctext = encrypt-ecb(state, ctext)" (so the value of 'ctext' is the result of a previous call) which form should I take a look at?

19:03 Can I use 'recur' in an anonymous function?

19:04 Or do I need to defn a seperate function?

19:04 rhickey: abrenk: yes, you can use recur

19:04 abrenk: And introduce the counter as a seperate parameter and stop recursion when it hits 64?

19:05 rhickey: thanks.

19:06 hiredman: abrenk: have you seen iterate

19:06 ,(doc iterate)

19:06 clojurebot: "([f x]); Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects"

19:06 abrenk: hiredman: Ah! You always know the right form. :-)

19:09 hiredman: But I don't need all the values - just the last one. So I'll try an anonymous function with recur first. That should do it.

19:10 hiredman: that will most likely be faster

19:10 I got tweeted

19:11 http://twitter.com/schipplock/statuses/8982760061

19:11 abrenk: hiredman: but you're a nice guy as far as I can tell!

19:11 danlarkin: how rude

19:12 hiredman: I'm sure they are verying opinions

19:12 there

19:36 technomancy: is there any kind of agenda for this evening?

19:40 technomancy: hiredman: it's freeform... just getting to know folks and possibly pulling out projects if we run out of things to talk about. =)

19:40 meetings that involve presentations every time are great, but they're a lot more work to organize. plus then you're bottlenecked by finding speakers.

19:41 Sonian's Seattle branch is a 140 sq-ft office in my back yard; not exactly lots of hosting options like you have in SF

19:42 hiredman: sure

20:06 BrandonW: do clojure newbies typically have problems with vec vs list vs seq?

20:06 are you supposed to use quoted lists by default, unless you need the vec data structure specifically for performance?

20:07 technomancy: often even small vectors are more convenient

20:08 especially for literals

20:08 use a list if you're going to be processing it in a first/rest fashion

20:09 BrandonW: i just kind of defaulted to vectors by default, but it seems kind of awkward to choose to use vectors, and then any time you execute a seq operation on the vec, you have to convert it back to a vec if you want the same conj (and any other function that operates differently depending on the data structure used)

20:09 behaviour

20:11 technomancy: yeah, if you need vector performance you should avoid seq-ifying operations

20:11 BrandonW: aren't the majority of data structure functions seq-ifying, though?

20:12 maybe it is just a coincidence that most of the operations i use in my first project happen to be seq-ifying

20:14 technomancy: yes, many core functions are sequifying. if you _really_ need performance you will need to either avoid them or learn to frame your problem in terms of seqs. (the latter is probably the right approach)

20:15 BrandonW: that's what i was thinking. I just have to start training myself to think in terms of seqs.

20:15 technomancy: seqs are pretty central to clojure

20:16 it's common to build up a vector in one step, then start using a seq that's based on the vector once you're ready to consume it.

20:16 using a seq based on a vector is cheap; it's going the other direction that's expensive

20:17 BrandonW: i think once i get this puzzle solver working i'm going to convert it to be seq-based

20:17 right now it is kind of seq/vec hybrid (had a few bugs involving that, too)

20:30 abrenk: Strange, if I use #(... (recur (inc %1) x)) it works, but (fn [i x] ...) I get "Can only recur from tail position".

20:31 How come? Named parameters would be nice. And (let [i %1 x %2] ...) seems unnecessary.

20:31 http://paste.lisp.org/+215N

20:33 It is a tail position...!?

20:35 chouser: nope, it's not

20:35 there are other differences between your #() and (fn ...) examples

20:35 You have (fn [i state] (if ...) 0 state)

20:35 so the 'if' is not in the tail position of the fn

20:36 * abrenk gets his glasses...

20:39 abrenk: chouser: am I missing a paren then or how did I screw up there? Seems I've got the syntax to call a (fn [] ...) form wrong.

20:40 chouser: If you meant to call the fn right there like you do with the #(), then you need ((fn [] ...) 0 state)

20:40 abrenk: Right!!!

20:41 chouser: Thanks again for taking a look! Now I've got it.

20:41 chouser: np

21:17 lancepantz: anyone have any experience implementing a connection pool with the sql api in clojure-contrib?

21:18 _mst: lancepantz: I haven't tried it with the c.c sql, but I've had good success using http://proxool.sourceforge.net/. I *think* it'd work for c.c sql too

21:23 lancepantz: cool, thanks man

21:23 looks like it does

21:53 qed: monads are scary

21:54 i dont know why im reading about monads in clojure...

22:06 offby1: clojurebot: hey ho

22:06 clojurebot: I don't understand.

22:28 Luyt: qed: Don't worry, I don't understand monads either. Not yet.

23:26 BrandonW: whoo finally!

23:27 completely un-optimized, but i now have a snake puzzle solver

23:27 took around 10 minutes to brute-force, heh

Logging service provided by n01se.net