#clojure log - Sep 06 2008

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

8:51 achim_p_: hi!

8:52 jgracin: hi, achim_p_

8:53 achim_p_: i tried using reflection with clojure, like this:

8:53 (.getMethods java.lang.String) ; (1)

8:53 (.getMethods (class "")) ; (2)

8:54 (1) throws a CompilerException, but (1) works ... anybody got an idea why?

8:55 (class java.lang.String) and (class (class "")) are both java.lang.Class

8:58 sorry, (2) works, (1) does not

8:59 jgracin: achim_p_, java.lang.String evals to a different thing than (class java.lang.String).

9:00 achim_p_: yes, but j.l.String is an instance of j.l.Class, so i should be able to call getMethods on it, shouldn't i?

9:02 i don't know much about java ...

9:05 jgracin: achim_p_, java.lang.String is not an instance of j.l.Class.

9:05 String.class is

9:06 I think the right thing to use is (.getMethods (class java.lang.String))

9:09 achim_p_: jgracin: hmm, strange. this actually returns j.l.Class's methods

9:09 (into [] (.getMethods (class java.lang.String)))

9:10 user> (instance? java.lang.Class java.lang.String)

9:10 true

9:11 i'm confused ;-)

9:11 jgracin: achim_p_, oh, sorry, I obviously don't know what I'm talking about. Let me try to figure it out... :-)

9:21 rhickey, Hi!. What does java.lang.String symbol evaluate to? achim_p_ asked why (.getMethods java.lang.String) does not work and I'm confused.

9:23 lisppaste8: achim_p pasted "reflection" at http://paste.lisp.org/display/66398

9:26 rhickey: String evaluates the the Class instance for String, but . is a special operator and doesn't evaluate its first arg if it looks like a classname. (.getMethods String) is sugar for (. String getMethods) which won't work because, given a class name, it considers the call a static method of the class, so things like (. String valueOf 42) work. But getMethods isn't a static method of String, it's an instance method of Class

9:26 (.getMethods (identity String)) will work

9:29 achim_p_: rhickey: ah, that makes sense, thanks for the explanation!

9:29 rhickey: If you can't say X.y() in Java you can't say (. X y) in Clojure, and you can't say String.getMethods() in Java

10:37 parth_m: Hello. I have a map (or hash-map) in Clojure and need to pass it to a java method that takes java.util.HashMap. Whats the idiomatic way to do this?

10:38 Do I write a simple conversion function using doto?

10:39 rhickey: (reduce (fn [m [k v]] (do (.put m k v) m)) (java.util.HashMap.) {:a 1 :b 2 :c 3})

10:40 oops, no do needed:

10:40 (reduce (fn [m [k v]] (.put m k v) m) (java.util.HashMap.) {:a 1 :b 2 :c 3})

10:41 parth_m: Exactly what I was looking for. Thanks :-)

16:30 ppjt: Greetings, everyone. I've having an issue accessing a Java nested class. I've imported net.sf.saxon.s9api.Serializer -- which maps to the physical directory-class tree -- but can't get go net.sf.saxon.s9api.Serializer.Property -- the last of which is a nested class inside Serializer.

16:30 Anyone else encountered something like this?

16:32 blackdog: you get nested classes with s9api$Serializer i think

16:32 rhickey_: ppjt: the JVM syntax for a nested class is EnclosingClass$Nested class, so Serializer$Property

16:35 ppjt: Okay, thanks.

16:37 Okay, just to confirm: Serializer has been imported, but clojure says it can't resolve the symbol Serializer$Property. Am I doing something obvious wrong?

16:41 rhickey_: ppjt: you need to import Serializer$Property too

16:43 ppjt: rhickey_: Ah, got it.

16:43 Thanks for the remedial Java help.

16:43 Clojure's been my only real motivation for hopping on the platform...

16:43 rhickey_: sure, the $ is hidden by Java except in the .class file names

16:44 ppjt: I saw those in the .class files, but thought it looked too machine-generated to type...

16:45 It seems awkward, compared to simply following down the package hierarchy

16:46 i.e. Serializer.Property

16:47 rhickey_: ppjt: the problem is Java uses '.' for so many things, some only distinguishable by static typing and context

16:49 ppjt: rhickey_: I see.

16:53 Thanks again for the help, &, surely, for Clojure! For me, it's been a way to do Lisp programming w/o special environment setup, which means Lisp programming with a chance of production use. It's been a real pleasure. Thanks for sharing your experience & effort with the community.

16:54 rhickey_: You're welcome!

17:14 Chouser: rhickey_: any conclusions on defns/ns/in-ns?

17:15 Maybe that would be a conclujion

17:16 rhickey_: Chouser: I had it almost done yesterday but am concerned about the context of the refers, i.e. if you don't refer clojure before anything else then there isn't enough of Clojure to interpret ns/defns in loaded files

17:17 Chouser: yep, so you either need to always say clojure/defns, or have some other special mechanism (reader macro?)

17:17 rhickey_: clojure/defns is ugly

17:17 Chouser: I agree

17:18 rhickey_: The bigger issue is, what is the context of load? Should it be the ns that calls load, or a special read-only loading ns that ensures Clojure will be present to start with

17:19 the latter will dictate that all files start with some sort of ns declaration

17:20 Chouser: that was part of why I asked about defns executing its flags in order -- if :refer-clojure (or the default) were always executed first, the rest of the items could assume clojure would be as much "there" as it ever will be for that file.

17:20 hm -- I kinda like the special read-only ns.

17:20 rhickey_: right but if you don't want most of Clojure but need to load a lib that does...

17:21 Chouser: yeah, the problem is bigger than I had realized when I asked.

17:22 rhickey_: a known starting point is strong, only negative is does it impinge on more casual use, or is there a valid load-in-a-context scenario

17:22 things designed to be loaded in a context are probably broken anyway

17:23 Chouser: the repl could start in 'user, thus have no extra burden. For any given .clj to require at least an (ns foo) at the top doesn't seem at all unreasonable.

17:23 this would only have to apply to things loaded via defns (and perhaps require, etc) -- load-file or other functions could of course be more basic and leave *ns* alone.

17:24 ...if you wanted to something unusual.

17:24 are read-only ns's already supported, or would this be a new class implementing Namespace?

17:25 rhickey_: I don't think defn and the other loads are (or should be) any different

17:25 read-ony ns would need special support

17:28 I hate to go crazy over namespaces that don't include some core of clojure

17:29 There have been scenarios (NetKernel) where some supervisory loader knows the (tear-off) namespace that the loaded file doesn't

17:30 Chouser: all you really need is some way to get to defns and ns without depending on the current namespace.

17:30 rhickey_: and everything they expand into

17:30 Chouser: The patch I sent you for ns uses fully-qualified names for all the expressions it generates.

17:31 rhickey_: that's good

17:35 Chouser: defns and ns could be rolled into one, like (ns :create foo) vs. (ns foo). Then you'd only need a single reader macro.

17:37 #!(:create foo (:import ...))

17:37 * Chouser suspects the chances of a reader macro are low.

17:37 rhickey_: I don't know about a reader macro, but could have some special resolution to clojure/ns

17:38 I've been leaning towards ns/in-ns, where in-ns still takes symbol, and enabling all other ns- fns to take symbol or actual namespace

17:39 unqualified ns and in-ns could always resolve to clojure/ns and clojure/in-ns

17:39 probably easiest

17:53 Chouser: I guess that would behave essentially a special form, like "new"

17:53 rhickey_: less special than that

18:34 ok - try it out - added :refer-clojure support to ns, special resolution of ns and in-ns, moved to ns for inspector/parallel/set/xml/zip, rev 1017

23:30 pjb3: Is there a nice method to convert a keyword to a string without the colon?

23:30 Chouser: name

23:30 user=> (name :foo)

23:30 "foo"

23:44 pjb3: thx

Logging service provided by n01se.net