#clojure logs

2008-08-28

10:10ozzileeCould anyone tell me why using a recur within a map would cause clojure to go into an infinite loop?
10:11Chousercare to paste an example?
10:12lisppaste8ozzilee pasted "recur within map" at http://paste.lisp.org/display/66008
10:13Chouserah. recur goes back to nearest containing loop or fn.
10:14ozzileeAh. Hm.
10:14ozzileeRecur will go back to a fn rather than a loop? Neat.
10:14Chouseryep
10:15ChouserI 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:15ozzileeNot 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:15Chouseryou might try (for ... :while)
10:15Chouseroh, scratch that.
10:15ozzileeOh no, I'm not trying to escape, I just want to recursively convert the map entries.
10:15drewrozzilee: Hey! I was doing the converse of that the other day.
10:16ozzileedrewr: Heh, for Jetty bychance?
10:16drewrNo, loading JDBC ResultSets into CouchDB.
10:17drewrThe process is entirely too fragile IMHO.
10:17Chouserozzilee: for something like that you can probably use a fn instead of loop, and call it by name from inside your map fn.
10:17Chouseryou know, just regular recursion.
10:17ozzileeChouser: Right, but that'll eat the stack, correct?
10:18Chouseryes, it'll up the stack proportionally to the depth of the JSON structure you're walking. Chances are that'll be ok.
10:18ozzileeChouser: Ok, maybe I'll just go that route for now.
10:18ozzileedrewr: What did you end up doing?
10:19ChouserWhat you'd be doing is much less dangerous than if you're iterating, and using up stack frames for each iteration.
10:20Chouserif you want to be extra-careful (and get other benefits) you can set it up to work lazily.
10:20drewrozzilee: Creating a recursive mess.
10:20drewr(But it worked.)
10:21ozzileeAll right. Plain ol' recursion it is. Thanks guys.
12:29rhickeyhoeck: got your CA
13:30hoeckrhickey: okay, cool
14:19rhickeyI'm thinking about going with the mk-get/assoc defined here: http://groups.google.com/group/clojure/msg/ec91ef45b017db68
14:20rhickeyany comments/suggestions for names?
14:31rhickeyalternatives: get->, assoc->, get* assoc* (there's also an mk-update)
14:41Chouserwhat's the mk- meant to imply?
14:44hoeckI would vote for get* and assoc*, but I doubt that I'm going to use that feature
14:51rhickeymk == multi-key
14:52rhickeyhoeck: why wouldn't you use it, if you had nested structure?
14:52Chouserah. not short for "make"
14:56ChouserIf it's going to take a vector, I'd vote get* and assoc*
14:57Chouserwell, I'd just prefer not get->. get* or get-nested or something.
14:59parth_mrhickey: I kind of like get* and assoc* more than mk-get and mk-assoc. mk- sort of sounds like make- convention of CL.
15:02parth_mHow about get+ and assoc+ ... + indicating 1 or more?
15:02hoeckrhickey: just toying around with relational algebra and trying to avoid hierachical data-access paths
15:03rhickeyhoeck: ok, FYI I'm looking into adding some sort of Datalog/rule engine which will do recursive queries
15:04rhickeyget-in, assoc-in, update-in ?
15:05parth_mrhickey: -in sounds good to me. Intuitive.
15:05Chouser-in is fine. what's update? :-)
15:06rhickeyChouser: takes a fn a la alter/commute - replaces value with function of current value
15:09lisppaste8rhickey pasted "get-in, assoc-in, update-in" at http://paste.lisp.org/display/66030
15:10Chouserah, right. very good.
15:11parth_mAh. I am already seeing my lines of code going down with update-in :-)
15:13parth_mHad a general question triggered by point 2 in this thread: http://groups.google.com/group/clojure/msg/52491a246b648067
15:14parth_mProbably a noob question. What exactly do we think of items like "String" "Exception" etc. in Clojure? Do we think of these as symbols?
15:14parth_m(def s String) shows s as java.lang.String but (new s "abc") fails.
15:15Chousernew is a special form, and it doesn't evaluate the class symbol.
15:15rhickeyparth_m: new and . are not reflective (i.e. they don't take Class instances)
15:17parth_mSo apart from symbols and keywords, Clojure has a third category "class" i.e. items like String. right?
15:17parth_mAnd (def s String) makes s and instance of String?
15:18rhickeyparth_m: you need to distinguish between the data returned by the reader and its interpretation, when read, String is a symbol
15:19rhickeyafter . and new, String is interpreted as a class scope (. and new are special forms as Chouser said)
15:19rhickeyin normal evaluation contexts, String designates the Class instance String
15:20rhickeyso (def s String) makes s the Class String
15:21rhickeyuser=> (def s String)
15:21rhickey#'user/s
15:21rhickeyuser=> (class s)
15:21rhickeyjava.lang.Class
15:21Chouserwhich is a big long way of saying that aliasing classes for use in . and new is non-trivial. :-)
15:22parth_mI think I get it now.
15:22parth_mSo for normal evaluation s would be ok but . and new being special forms do things a little differently
15:22rhickeyChouser: I wouldn't say that, but it is not important, and perhaps an anti-feature
15:23Chouserhm.
15:24parth_mI 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:24kotarak(eval `(new ~s)) does work, no? But it probably supports the anti-feature thesis.
15:25rhickeykotarak: right
15:35lisppaste8rhickey pasted "proposed lib usage" at http://paste.lisp.org/display/66034
15:38Chouserooh.
15:39Chouseris :requires doing an alias, or can I say (ns foo (:requires (clojure.contrib sql :as sql sql.tests :as sql.tests))
15:39cemerickI assume the aliasing options are available/
15:40cemerick(what Chouser said)
15:40rhickeysame stuff as in lib, I think it requires some []s
15:40rhickey[very-long-thing :as vlt]
15:40cemerickLooks fantastic.
15:42cemerickI 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:42rhickeycemerick: we were just discussing that, I think it's an anti-feature
15:42cemerick(i.e. (ns foo (:imports (java.util [Date :as JDate]) (com.foo [Date :as FDate]))))
15:44cemerickrhickey: anti-feature as in, bad practice, or as in, doable with macros already?
15:44rhickeymore likely I'd extend namespace aliasing to Java packages: juitl/Date foo/date
15:44rhickeycemerick: bad in proactice - makes code harder to understand, tougher for tools etc
15:45rhickeyfoo/Date above
15:45cemerickyeah, the namespace aliasing would scratch my itch
15:45cemericks/namespace/package
15:48kotarakthis is awesome. Nice to experience this "live", so to say. Normally when I learn a new language it's around 15 years old. :]
15:49Chouserkotarak: 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:49ChouserBecause, you know, they need to in order to get a job anywhere. :-)
15:50parth_mRegarding (: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:51rhickeyparth_m: requires does the loading
15:51rhickeythe library itself handles its multiple files if any
15:51parth_mThats nice :-)
15:52kotarakChouser: 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:52Chouserkotarak: :-)
15:53parth_mMight be a silly question. Whats the different between :requires and :uses?
15:54rhickeyuses refers automatically
15:54parth_mAh. Nice.
15:55kotarak:imports, :requires and :uses translates to the similar named functions of clojure.contrib.lib
15:55kotarakok, :requires and :uses actually...
15:56parth_mkotarak: Will look at clojure.contrib.lib. Thanks for the pointer.
15:56kotarakparth_m: you did not, up to now? Hurry up. That's a really must-have!
15:57parth_m:-)
16:08tomhickeyrhickey: i like the -in examples, feels nice
16:57kotarakI added a section for clojure.contrib.lib on the wiki. But well parth_m has already left...
16:57rhickeylib is now integrated!
16:57rhickeyThis works:
16:57rhickey(ns foo
16:57rhickey (:requires [clojure.parallel :as par])
16:57rhickey (:uses (clojure inspector))
16:57rhickey (:imports (java.util Date Timer Random)
16:57rhickey (java.sql Connection Statement)))
16:58kotarakOk. I'll adapt the wiki entry.
16:58Chouserwoohoo!
16:59rhickeyalso added a defonce, plus format and printf
17:01Chouser:-) printf lives on...
17:03kotarakrhickey: does (:require bar.baz) also work? w/o []?
17:04rhickeykotarak: yes, []s are only needed if using flags like :as
17:05kotarakrhickey: ok. Just asking. Don't want to write something wrong on the wiki. :)
17:06rhickeykotarak: best to read the embedded docs, which are quite detailed, before you restate them - (doc require)
17:13rhickey(ns foo
17:13rhickey (:requires [clojure.parallel :as par])
17:13rhickey (:uses [clojure.inspector :exclude (inspect-tree)])
17:13rhickey (:imports (java.util Date Timer Random)
17:13rhickey (java.sql Connection Statement)))
17:16kotarakHow do I do load-libs now?
17:16Chouser(ns foo (:uses [clojure :exclude (slurp load-file)]))
17:16Chouserjava.io.FileNotFoundException: Could not locate Clojure resource on classpath: clojure/clojure.clj
17:17Chouser(ns foo (:uses (clojure :exclude (slurp load-file)))) ==> java.lang.IllegalArgumentException: Don't know how to create ISeq from: Keyword
17:18Chouser(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:19Chousergotta go, I'll pick this up again later tonight.
17:19kotarakThis is happened already before.
17:19kotarakSo it's not from the new code, I suppose.
17:23Chouseroh, this is because the new ns macro does a (refer 'clojure) for us automatically.
17:23ChouserThat 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:24kotarakOk? Hmmm, but I'm sure I had this "exclude but complain anyway" phenomenon also in a previous version.
17:25kotarakAnd I still miss load-libs...
17:26drewrExcellent: http://is.gd/219Y
17:27kotarakAh. Maybe load-resources does the job!
17:28Chouserok, really going now...
18:30hoeckwow, built in lib is superb
18:33pmf /j vim
20:14cemerickI'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:14Chouseryou can use the #() syntax to build one pretty easily
20:15cemerickgawd, yes
20:15cemerickit's been a long week :-)
20:20Chouser:-)
21:42jamii_Um ...
21:42jamii_user=> (. Integer (getName))
21:42jamii_java.lang.IllegalArgumentException: No matching method: getName
21:42Chouserthere's no static method getName in the Integer class.
21:43jamiiOh. Of course. I want the non-static method of the class object Integer
21:43Chouserright. (. (identity Integer) (getName))
21:43Chouseror (. (class 5) (getName))
21:44jamiiI'm confused. Why does the former work?
21:45jamiiuser=> (= (identity Integer) Integer)
21:45jamiitrue
21:46Chouser. 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:46ChouserIf the first arg to . is anything else, it gets evaluated to get an object instance (an instance of Class in these cases).
21:47jamiiOk. I can see that that would rarely cause problems.
21:47jamiiThanks
21:47ChouserIn most other contexts, class names evaluate to their instance of Class, which is why your = did what it did.
21:48Chouseryep, I certainly have stumbled on it a few times.
21:54lisppaste8jamii pasted "slots" at http://paste.lisp.org/display/66041
21:54jamiiMy first clojure module
21:56Chousercool!
21:56jamiithe seeds of a scriptable notetaking app
21:58jamiihas clojure yet evolved a common indentation style?
21:58Chouserpretty common, I think. Borrows a lot from Common Lisp of course.
22:00Chouseryour paste looks pretty good. Indent the contents of let
22:02jamiicool. thanks for the help.
22:06Chousersure
22:08Chouserhey, if you update to the latest clojure svn, you can replace your first two lines with just (ns slots)
23:28arohnerhas anyone tried (ns foo (:require ..))?
23:29arohner(ns foo (:require 'clojure.contrib.sql)) gives me java.lang.Exception: Unable to resolve symbol: requir in this context
23:29arohnerbut (ns foo) (require 'clojure.contrib.sql) works fine
23:30Chouserheh
23:37Chouseryep, I see that.
23:38Chouseroh, you need :requires -- note the "s"
23:40arohnerah, thanks
23:40arohnerhaving alias in the (ns) block would be nice
23:40arohnerI notice I tend to use alias right after require
23:47Chouser(ns foo (:requires [clojure.parallel :as par]))
23:48arohneroh, nice
23:48arohnermaybe I should read the docs fully?
23:48arohner:-)
23:48Chouser:-)
23:49Chouserwell, now you may have to. I'm off to bed.
23:49arohnerthanks for the help