2008-08-28
| 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:12 | lisppaste8 | ozzilee pasted "recur within map" at http://paste.lisp.org/display/66008 |
| 10:13 | Chouser | ah. recur goes back to nearest containing loop or fn. |
| 10:14 | ozzilee | Ah. Hm. |
| 10:14 | ozzilee | Recur will go back to a fn rather than a loop? Neat. |
| 10:14 | Chouser | yep |
| 10:15 | Chouser | 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 | Chouser | 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 | drewr | 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 | Chouser | 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 | Chouser: Ok, maybe I'll just go that route for now. |
| 10:18 | ozzilee | 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 | Chouser | 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 | drewr | (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://groups.google.com/group/clojure/msg/ec91ef45b017db68 |
| 14:20 | rhickey | any comments/suggestions for names? |
| 14:31 | rhickey | 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 | rhickey | hoeck: why wouldn't you use it, if you had nested structure? |
| 14:52 | Chouser | ah. not short for "make" |
| 14:56 | Chouser | If it's going to take a vector, I'd vote get* and assoc* |
| 14:57 | Chouser | 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 | parth_m | 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 | rhickey | 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:09 | lisppaste8 | rhickey pasted "get-in, assoc-in, update-in" at http://paste.lisp.org/display/66030 |
| 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 | parth_m | Had a general question triggered by point 2 in this thread: http://groups.google.com/group/clojure/msg/52491a246b648067 |
| 15:14 | parth_m | 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 | parth_m | (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 | parth_m | 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 | rhickey | after . and new, String is interpreted as a class scope (. and new are special forms as Chouser said) |
| 15:19 | rhickey | in normal evaluation contexts, String designates the Class instance String |
| 15:20 | rhickey | so (def s String) makes s the Class String |
| 15:21 | rhickey | user=> (def s String) |
| 15:21 | rhickey | #'user/s |
| 15:21 | rhickey | user=> (class s) |
| 15:21 | rhickey | java.lang.Class |
| 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 | parth_m | 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:35 | lisppaste8 | rhickey pasted "proposed lib usage" at http://paste.lisp.org/display/66034 |
| 15:38 | Chouser | ooh. |
| 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 | cemerick | (what Chouser said) |
| 15:40 | rhickey | same stuff as in lib, I think it requires some []s |
| 15:40 | rhickey | [very-long-thing :as vlt] |
| 15:40 | cemerick | Looks fantastic. |
| 15:42 | cemerick | 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 | cemerick | 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 | rhickey | cemerick: bad in proactice - makes code harder to understand, tougher for tools etc |
| 15:45 | rhickey | foo/Date above |
| 15:45 | cemerick | yeah, the namespace aliasing would scratch my itch |
| 15:45 | cemerick | s/namespace/package |
| 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 | Chouser | 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 | rhickey | 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 | kotarak | 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 | rhickey | This works: |
| 16:57 | rhickey | (ns foo |
| 16:57 | rhickey | (:requires [clojure.parallel :as par]) |
| 16:57 | rhickey | (:uses (clojure inspector)) |
| 16:57 | rhickey | (:imports (java.util Date Timer Random) |
| 16:57 | rhickey | (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:13 | rhickey | (ns foo |
| 17:13 | rhickey | (:requires [clojure.parallel :as par]) |
| 17:13 | rhickey | (:uses [clojure.inspector :exclude (inspect-tree)]) |
| 17:13 | rhickey | (:imports (java.util Date Timer Random) |
| 17:13 | rhickey | (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 | Chouser | java.io.FileNotFoundException: Could not locate Clojure resource on classpath: clojure/clojure.clj |
| 17:17 | Chouser | (ns foo (:uses (clojure :exclude (slurp load-file)))) ==> java.lang.IllegalArgumentException: Don't know how to create ISeq from: Keyword |
| 17:18 | Chouser | (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 | Chouser | gotta go, I'll pick this up again later tonight. |
| 17:19 | kotarak | This is happened already before. |
| 17:19 | kotarak | 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 | Chouser | 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 | kotarak | And I still miss load-libs... |
| 17:26 | drewr | Excellent: http://is.gd/219Y |
| 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 | cemerick | it's been a long week :-) |
| 20:20 | Chouser | :-) |
| 21:42 | jamii_ | Um ... |
| 21:42 | jamii_ | user=> (. Integer (getName)) |
| 21:42 | jamii_ | 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 | Chouser | or (. (class 5) (getName)) |
| 21:44 | jamii | I'm confused. Why does the former work? |
| 21:45 | jamii | user=> (= (identity Integer) Integer) |
| 21:45 | jamii | true |
| 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 | Chouser | 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 | jamii | Thanks |
| 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 | Chouser | yep, I certainly have stumbled on it a few times. |
| 21:54 | lisppaste8 | jamii pasted "slots" at http://paste.lisp.org/display/66041 |
| 21:54 | jamii | My first clojure module |
| 21:56 | Chouser | cool! |
| 21:56 | jamii | the seeds of a scriptable notetaking app |
| 21:58 | jamii | 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 | Chouser | your paste looks pretty good. Indent the contents of let |
| 22:02 | jamii | cool. thanks for the help. |
| 22:06 | Chouser | sure |
| 22:08 | Chouser | 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 | arohner | (ns foo (:require 'clojure.contrib.sql)) gives me java.lang.Exception: Unable to resolve symbol: requir in this context |
| 23:29 | arohner | but (ns foo) (require 'clojure.contrib.sql) works fine |
| 23:30 | Chouser | heh |
| 23:37 | Chouser | yep, I see that. |
| 23:38 | Chouser | oh, you need :requires -- note the "s" |
| 23:40 | arohner | ah, thanks |
| 23:40 | arohner | having alias in the (ns) block would be nice |
| 23:40 | arohner | 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 | arohner | maybe I should read the docs fully? |
| 23:48 | arohner | :-) |
| 23:48 | Chouser | :-) |
| 23:49 | Chouser | well, now you may have to. I'm off to bed. |
| 23:49 | arohner | thanks for the help |