This is the mail archive of the
kawa@sourceware.org
mailing list for the Kawa project.
Re: define-simple-class vs modules
On Jan 26, 2011, at 7:22 PM, Per Bothner wrote:
On 01/26/2011 01:08 PM, Jamison Hope wrote:
New question: is there any sort of reflection mechanism which will
give
me a list of all the bindings exported by a module?
java.lang.Class#getFields is kind of on the right track, except
that it
gives me mangled names, gives me everything even if it was
define-private or not listed in module-export and includes the extra
Kawa runtime support stuff inserted by the compiler.
No, there isn't but perhaps there should be.
Maybe something based on R6RS's (rnrs records inspection) library?
I looked over (rnrs records inspection), and I'm not sure how applicable
it is, given the differences between (rnrs records) and Java classes.
record-type-field-names is vaguely like what I was asking about, but
rnrs
record fields are per-instance, while there's usually only one module
(either with static methods or an implicit singleton instance).
If we were to adopt this library anyway, we would probably have
something
like this:
(define (record? obj)
(object? obj))
(define (record-rtd record)
(*:get-class obj))
(define (record-type-name rtd)
(*:get-name rtd))
(define (record-type-parent rtd)
(let ((super (*:get-superclass rtd)))
(if (not (eq? #!null super)) super #f)))
(define (record-type-sealed? rtd)
(java.lang.reflect.Modifier:final? (*:get-modifiers rtd)))
The RNRS idea of generative records seems related to Java classes being
serializable, but not exactly. So I'm not sure what record-type-uid and
record-type-generative? would map to. Perhaps something like this for
record-type-uid:
(define (record-type-uid rtd)
(try-catch
(let ((f (*:get-declared-field rtd "serialVersionUID")))
(set! f:accessible #t)
(*:get-long f #!null))
(ex java.lang.Throwable #f)))
There isn't really a good match for record-type-opaque?, either. And
it seems clunky to have to pass an index integer to record-field-
mutable?
rather than a slot name as symbol or string.
Some Schemes (and of course Common Lisp) have a meta-object-protocol
that could provide API suggestions.
A MOP could certainly be handy, though in this case I am only thinking
of
reading information (not modifying behavior).
Somewhat relatedly, I discovered that if you require or import a class
(not necessarily a Kawa module, just any class), all of its static
fields
end up bound in the environment:
#|kawa:1|# (import (javax swing WindowConstants))
#|kawa:2|# DISPOSE_ON_CLOSE
2
#|kawa:3|# (define-simple-class foo () (bar ::int allocation: 'static
5))
#|kawa:4|# foo
class foo
#|kawa:5|# foo:bar
5
#|kawa:6|# (import (foo))
#|kawa:7|# bar
5
Have you thought about having static methods imported as well? Then a
Kawa
import would be roughly the same as a Java import static. For instance,
(import (only (java lang Math) abs))
abs => #<procedure java.lang.Math.abs>
(import (only (java lang System) getenv))
(getenv 'TERM) => xterm-color
For real Kawa modules, which will have ModuleMethod fields as well as
Java
methods, the ModuleMethod "foo" should take precedence over its
corresponding
method foo(), so that require/import work the same way they do now.
--
Jamison Hope
The PTR Group
www.theptrgroup.com