[armedbear-devel] Utility macros to access Java from Lisp

Blake McBride blake at mcbride.name
Sun Jan 24 04:35:06 UTC 2010


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 , at arg-types))
   (,cls (jclass ,cls-name)))
       (defun ,lfun ,arglist
 (jcall ,method ,cls , at 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 , at arg-types)))
       (defun ,lfun ,arglist
 (jcall ,method , at 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 , at arg-types)))
       (defun ,lfun ,arglist
 (jnew ,method , at arglist)))))


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

(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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/armedbear-devel/attachments/20100123/5740a6bd/attachment.html>

More information about the armedbear-devel mailing list