Greetings,
I find the following utility macros helpful when wanting to access Java from
Lisp. I will give some examples after the actual code.
(defmacro defun-class-method (lfun cls-name meth-name &rest arg-types)
(let ((arglist (mapcar (lambda (x) (gensym)) arg-types))
(method (gensym))
(cls (gensym)))
`(let ((,method (jmethod ,cls-name ,meth-name ,@arg-types))
(,cls (jclass ,cls-name)))
(defun ,lfun ,arglist
(jcall ,method ,cls ,@arglist)))))
(defmacro defun-instance-method (lfun cls-name meth-name &rest arg-types)
(let ((arglist (mapcar (lambda (x) (gensym)) (cons nil arg-types)))
(method (gensym)))
`(let ((,method (jmethod ,cls-name ,meth-name ,@arg-types)))
(defun ,lfun ,arglist
(jcall ,method ,@arglist)))))
(defmacro defun-constructor (lfun cls-name &rest arg-types)
(let ((arglist (mapcar (lambda (x) (gensym)) arg-types))
(method (gensym)))
`(let ((,method (jconstructor ,cls-name ,@arg-types)))
(defun ,lfun ,arglist
(jnew ,method ,@arglist)))))
Examples:
The following line defines a lisp function named "java-abs". java-abs is a
proxy for the java version. It takes the same arguments.
(defun-class-method java-abs "java.lang.Math" "abs" "int")
After the above is called, you may call the Java method from lisp as
follows:
(java-abs -44)
The lisp functions created by these utilities are fast because they are
closures. The class and method lookups are only done once.
Other examples:
(defun-constructor newInteger "java.lang.Integer" "int")
(defun-instance-method hashCode "java.lang.Integer" "hashCode")
I am in the process of doing the same thing for Java. Stay tuned.
Blake McBride