This is the mail archive of the kawa@sourceware.org mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]