10:10 ozzilee: Could anyone tell me why using a recur within a map would cause clojure to go into an infinite loop?
10:11 Chouser: care to paste an example?
10:13 Chouser: ah. recur goes back to nearest containing loop or fn.
10:14 ozzilee: Ah. Hm.
10:14 Recur will go back to a fn rather than a loop? Neat.
10:14 Chouser: yep
10:15 I can't really tell what you're trying to do there, but recur's not going to help you escape from a map early.
10:15 ozzilee: Not sure if it does me any good, but neat. I'm try to recursively convert a json structure represented as HashMaps and Arrays into maps and vectors. Maybe I should try a zipper?
10:15 Chouser: you might try (for ... :while)
10:15 oh, scratch that.
10:15 ozzilee: Oh no, I'm not trying to escape, I just want to recursively convert the map entries.
10:15 drewr: ozzilee: Hey! I was doing the converse of that the other day.
10:16 ozzilee: drewr: Heh, for Jetty bychance?
10:16 drewr: No, loading JDBC ResultSets into CouchDB.
10:17 The process is entirely too fragile IMHO.
10:17 Chouser: ozzilee: for something like that you can probably use a fn instead of loop, and call it by name from inside your map fn.
10:17 you know, just regular recursion.
10:17 ozzilee: Chouser: Right, but that'll eat the stack, correct?
10:18 Chouser: yes, it'll up the stack proportionally to the depth of the JSON structure you're walking. Chances are that'll be ok.
10:18 * ozzilee has no idea how big the JVM stack would be
10:18 ozzilee: Chouser: Ok, maybe I'll just go that route for now.
10:18 drewr: What did you end up doing?
10:19 Chouser: What you'd be doing is much less dangerous than if you're iterating, and using up stack frames for each iteration.
10:20 if you want to be extra-careful (and get other benefits) you can set it up to work lazily.
10:20 drewr: ozzilee: Creating a recursive mess.
10:20 (But it worked.)
10:21 ozzilee: All right. Plain ol' recursion it is. Thanks guys.
12:29 rhickey: hoeck: got your CA
13:30 hoeck: rhickey: okay, cool
14:19 rhickey: I'm thinking about going with the mk-get/assoc defined here: http://
14:20 any comments/suggestions for names?
14:31 alternatives: get->, assoc->, get* assoc* (there's also an mk-update)
14:41 Chouser: what's the mk- meant to imply?
14:44 hoeck: I would vote for get* and assoc*, but I doubt that I'm going to use that feature
14:51 rhickey: mk == multi-key
14:52 hoeck: why wouldn't you use it, if you had nested structure?
14:52 Chouser: ah. not short for "make"
14:56 If it's going to take a vector, I'd vote get* and assoc*
14:57 well, I'd just prefer not get->. get* or get-nested or something.
14:59 parth_m: rhickey: I kind of like get* and assoc* more than mk-get and mk-assoc. mk- sort of sounds like make- convention of CL.
15:02 How about get+ and assoc+ ... + indicating 1 or more?
15:02 hoeck: rhickey: just toying around with relational algebra and trying to avoid hierachical data-access paths
15:03 rhickey: hoeck: ok, FYI I'm looking into adding some sort of Datalog/rule engine which will do recursive queries
15:04 get-in, assoc-in, update-in ?
15:05 parth_m: rhickey: -in sounds good to me. Intuitive.
15:05 Chouser: -in is fine. what's update? :-)
15:06 rhickey: Chouser: takes a fn a la alter/commute - replaces value with function of current value
15:10 Chouser: ah, right. very good.
15:11 parth_m: Ah. I am already seeing my lines of code going down with update-in :-)
15:13 Had a general question triggered by point 2 in this thread: http://
15:14 Probably a noob question. What exactly do we think of items like "String" "Exception" etc. in Clojure? Do we think of these as symbols?
15:14 (def s String) shows s as java.lang.String but (new s "abc") fails.
15:15 Chouser: new is a special form, and it doesn't evaluate the class symbol.
15:15 rhickey: parth_m: new and . are not reflective (i.e. they don't take Class instances)
15:17 parth_m: So apart from symbols and keywords, Clojure has a third category "class" i.e. items like String. right?
15:17 And (def s String) makes s and instance of String?
15:18 rhickey: parth_m: you need to distinguish between the data returned by the reader and its interpretation, when read, String is a symbol
15:19 after . and new, String is interpreted as a class scope (. and new are special forms as Chouser said)
15:19 in normal evaluation contexts, String designates the Class instance String
15:20 so (def s String) makes s the Class String
15:21 user=> (def s String)
15:21 user=> (class s)
15:21 Chouser: which is a big long way of saying that aliasing classes for use in . and new is non-trivial. :-)
15:22 parth_m: I think I get it now.
15:22 So for normal evaluation s would be ok but . and new being special forms do things a little differently
15:22 rhickey: Chouser: I wouldn't say that, but it is not important, and perhaps an anti-feature
15:23 Chouser: hm.
15:24 parth_m: I don't see a need for aliasing classes, I just wanted to improve my understanding of how it all worked. Thanks for the clarifications.
15:24 kotarak: (eval `(new ~s)) does work, no? But it probably supports the anti-feature thesis.
15:25 rhickey: kotarak: right
15:38 Chouser: ooh.
15:38 * drewr likey
15:39 * cemerick drools :-)
15:39 Chouser: is :requires doing an alias, or can I say (ns foo (:requires (clojure.contrib sql :as sql sql.tests :as sql.tests))
15:39 cemerick: I assume the aliasing options are available/
15:40 (what Chouser said)
15:40 rhickey: same stuff as in lib, I think it requires some s
15:40 [very-long-thing :as vlt]
15:40 cemerick: Looks fantastic.
15:42 I don't remember if this has been brought up elsewhere before, but on a related note, it'd be really wonderful if class names could be aliased as well (which would simply be some reader magic, I'd think).
15:42 rhickey: cemerick: we were just discussing that, I think it's an anti-feature
15:42 cemerick: (i.e. (ns foo (:imports (java.util [Date :as JDate]) (com.foo [Date :as FDate]))))
15:44 rhickey: anti-feature as in, bad practice, or as in, doable with macros already?
15:44 rhickey: more likely I'd extend namespace aliasing to Java packages: juitl/Date foo/date
15:44 cemerick: bad in proactice - makes code harder to understand, tougher for tools etc
15:45 foo/Date above
15:45 cemerick: yeah, the namespace aliasing would scratch my itch
15:48 kotarak: this is awesome. Nice to experience this "live", so to say. Normally when I learn a new language it's around 15 years old. :]
15:49 Chouser: kotarak: yeah, it's exciting isn't it? expecially when you start to get the sense that people may actually still be learning it in 15 years.
15:49 Because, you know, they need to in order to get a job anywhere. :-)
15:50 parth_m: Regarding (:requires ...). Can this clause be used to load clj files in a multifile app/library? or should we use load-file(s) in the sources?
15:51 rhickey: parth_m: requires does the loading
15:51 the library itself handles its multiple files if any
15:51 parth_m: Thats nice :-)
15:52 kotarak: Chouser: hehe, and you can tell your kids "Look, that Chouser in the IRC log of ye Olden dayes, that was me! Right from the beginning!" ;)
15:52 Chouser: kotarak: :-)
15:53 parth_m: Might be a silly question. Whats the different between :requires and :uses?
15:54 rhickey: uses refers automatically
15:54 parth_m: Ah. Nice.
15:55 kotarak: :imports, :requires and :uses translates to the similar named functions of clojure.contrib.lib
15:55 ok, :requires and :uses actually...
15:56 parth_m: kotarak: Will look at clojure.contrib.lib. Thanks for the pointer.
15:56 kotarak: parth_m: you did not, up to now? Hurry up. That's a really must-have!
15:57 parth_m: :-)
16:08 tomhickey: rhickey: i like the -in examples, feels nice
16:57 kotarak: I added a section for clojure.contrib.lib on the wiki. But well parth_m has already left...
16:57 rhickey: lib is now integrated!
16:57 This works:
16:57 (ns foo
16:57 (:requires [clojure.parallel :as par])
16:57 (:uses (clojure inspector))
16:57 (:imports (java.util Date Timer Random)
16:57 (java.sql Connection Statement)))
16:58 kotarak: Ok. I'll adapt the wiki entry.
16:58 Chouser: woohoo!
16:59 rhickey: also added a defonce, plus format and printf
17:01 Chouser: :-) printf lives on...
17:03 kotarak: rhickey: does (:require bar.baz) also work? w/o ?
17:04 rhickey: kotarak: yes, s are only needed if using flags like :as
17:05 kotarak: rhickey: ok. Just asking. Don't want to write something wrong on the wiki. :)
17:06 rhickey: kotarak: best to read the embedded docs, which are quite detailed, before you restate them - (doc require)
17:10 * Chouser can't figure out how to do :uses and :exclude
17:13 rhickey: (ns foo
17:13 (:requires [clojure.parallel :as par])
17:13 (:uses [clojure.inspector :exclude (inspect-tree)])
17:13 (:imports (java.util Date Timer Random)
17:13 (java.sql Connection Statement)))
17:16 kotarak: How do I do load-libs now?
17:16 Chouser: (ns foo (:uses [clojure :exclude (slurp load-file)]))
17:16 java.io.FileNotFoundException: Could not locate Clojure resource on classpath: clojure/clojure.clj
17:17 (ns foo (:uses (clojure :exclude (slurp load-file)))) ==> java.lang.IllegalArgumentException: Don't know how to create ISeq from: Keyword
17:18 (ns foo (:uses ([clojure :exclude (slurp load-file)]))) ==> nil, but then: foo=> (def slurp "oops") ==> java.lang.Exception: Name conflict, can't def slurp because namespace: foo refers to:#'clojure/slurp
17:19 gotta go, I'll pick this up again later tonight.
17:19 kotarak: This is happened already before.
17:19 So it's not from the new code, I suppose.
17:23 Chouser: oh, this is because the new ns macro does a (refer 'clojure) for us automatically.
17:23 That was mentioned (and even documented) but I forgot. If I want to exclude some clojure, I'll have to do something before calling ns.
17:24 kotarak: Ok? Hmmm, but I'm sure I had this "exclude but complain anyway" phenomenon also in a previous version.
17:25 And I still miss load-libs...
17:27 kotarak: Ah. Maybe load-resources does the job!
17:28 Chouser: ok, really going now...
18:30 hoeck: wow, built in lib is superb
18:33 pmf: /j vim
20:14 cemerick: I'm pretty sure the answer is currently 'no', but: is there any way to obtain a partial fn from a java object's method?
20:14 Chouser: you can use the #() syntax to build one pretty easily
20:15 cemerick: gawd, yes
20:15 it's been a long week :-)
20:20 Chouser: :-)
21:42 jamii_: Um ...
21:42 user=> (. Integer (getName))
21:42 java.lang.IllegalArgumentException: No matching method: getName
21:42 Chouser: there's no static method getName in the Integer class.
21:43 jamii: Oh. Of course. I want the non-static method of the class object Integer
21:43 Chouser: right. (. (identity Integer) (getName))
21:43 or (. (class 5) (getName))
21:44 jamii: I'm confused. Why does the former work?
21:45 user=> (= (identity Integer) Integer)
21:46 Chouser: . is a special form (not a function). It checks its first arg to see if its a literal class name, in order to provide access to static methods and fields.
21:46 If the first arg to . is anything else, it gets evaluated to get an object instance (an instance of Class in these cases).
21:47 jamii: Ok. I can see that that would rarely cause problems.
21:47 Chouser: In most other contexts, class names evaluate to their instance of Class, which is why your = did what it did.
21:48 yep, I certainly have stumbled on it a few times.
21:54 jamii: My first clojure module
21:56 Chouser: cool!
21:56 jamii: the seeds of a scriptable notetaking app
21:58 has clojure yet evolved a common indentation style?
21:58 Chouser: pretty common, I think. Borrows a lot from Common Lisp of course.
22:00 your paste looks pretty good. Indent the contents of let
22:02 jamii: cool. thanks for the help.
22:06 Chouser: sure
22:08 hey, if you update to the latest clojure svn, you can replace your first two lines with just (ns slots)
23:28 arohner: has anyone tried (ns foo (:require ..))?
23:29 (ns foo (:require 'clojure.contrib.sql)) gives me java.lang.Exception: Unable to resolve symbol: requir in this context
23:29 but (ns foo) (require 'clojure.contrib.sql) works fine
23:30 Chouser: heh
23:37 yep, I see that.
23:38 oh, you need :requires -- note the "s"
23:40 arohner: ah, thanks
23:40 having alias in the (ns) block would be nice
23:40 I notice I tend to use alias right after require
23:47 Chouser: (ns foo (:requires [clojure.parallel :as par]))
23:48 arohner: oh, nice
23:48 maybe I should read the docs fully?
23:48 Chouser: :-)
23:49 well, now you may have to. I'm off to bed.
23:49 arohner: thanks for the help