case-lambda and Java
Jamison Hope
jrh@theptrgroup.com
Mon Dec 7 23:48:00 GMT 2009
Is there a way to invoke procedures defined with case-lambda from
Java? In a slightly-contrived example, I have written a set of
functions which convert some Java collection types into Scheme lists,
along with a case-lambda procedure which dispatches to the others
based upon argument type:
> $ cat collections_utils.scm
> (module-export Enumeration->list
> Iterator->list
> Iterable->list
> Array->list
> ->list)
>
> ;;; Returns a list of the elements of the given Enumeration.
> (define (Enumeration->list (enum :: java.util.Enumeration)) :: list
> (let loop ((ls '()))
> (if (enum:hasMoreElements)
> (loop (cons (enum:nextElement) ls))
> (reverse ls))))
>
> ;;; Returns a list of the elements of the given Iterator.
> (define (Iterator->list (iter :: java.util.Iterator)) :: list
> (let loop ((ls '()))
> (if (iter:hasNext)
> (loop (cons (iter:next) ls))
> (reverse ls))))
>
> ;;; Returns a list of the elements of the given Iterable.
> (define (Iterable->list (it :: java.lang.Iterable)) :: list
> (Iterator->list (it:iterator)))
>
> ;;; Returns a list of the elements of the given array.
> (define (Array->list (array :: Object)) :: list
> (when (*:isArray (array:getClass))
> (let* ((n :: int (java.lang.reflect.Array:getLength array))
> (result-vector :: vector (make-vector n)))
> (do ((i 0 (+ i 1)))
> ((= i n) (vector->list result-vector))
> (vector-set! result-vector i (array i))))))
>
> ;;; Converts the given object into a list.
> (define ->list
> (case-lambda
> ((l :: list) :: list l)
> ((l :: java.lang.Iterable) :: list (Iterable->list l))
> ((l :: java.util.Iterator) :: list (Iterator->list l))
> ((l :: java.util.Enumeration) :: list (Enumeration->list l))
> ((l :: Object) :: list (Array->list l))))
> ;;; EOF
> $ java kawa.repl --target 1.5 --module-static-run --warn-undefined-
> variable -C collections_utils.scm
> (compiling collections_utils.scm to collections_utils)
From Scheme, I can easily call any of these functions, including -
>list:
> $ cat usage1.scm
> (require collections_utils)
>
> (format #t "~A~%" (->list #(1 2 3 4 5)))
> (format #t "~A~%" (Array->list (int[] 1 2 3)))
> ;;; EOF
> $ java kawa.repl --target 1.5 --module-static-run --warn-undefined-
> variable --main -C usage1.scm
> (compiling usage1.scm to usage1)
> $ java usage1
> (1 2 3 4 5)
> (1 2 3)
but when I inspect collections_utils.class to see what Java methods
are available to me, I only see analogs of Enumeration->list, Iterator-
>list, Iterable->list, and Array->list:
> public class collections_utils extends gnu.expr.ModuleBody{
> public static final gnu.expr.ModuleMethod Enumeration$Mn$Grlist;
> public static final gnu.expr.ModuleMethod Iterator$Mn$Grlist;
> public static final gnu.expr.ModuleMethod Iterable$Mn$Grlist;
> public static final gnu.expr.ModuleMethod Array$Mn$Grlist;
> public static final gnu.mapping.Location $Mn$Grlist;
> public static final collections_utils $instance;
> public collections_utils();
> public static gnu.lists.LList Enumeration$To
> $List(java.util.Enumeration);
> public static gnu.lists.LList Iterator$To
> $List(java.util.Iterator);
> public static gnu.lists.LList Iterable$To
> $List(java.lang.Iterable);
> public static gnu.lists.LList Array$To$List(java.lang.Object);
> public final void run(gnu.mapping.CallContext);
> public static {};
> public int match1(gnu.expr.ModuleMethod, java.lang.Object,
> gnu.mapping.CallContext);
> public java.lang.Object apply1(gnu.expr.ModuleMethod,
> java.lang.Object);
There's the $Mn$Grlist Location which presumably points to the case-
lambda body, but that's all. I was hoping to find either a family of
overloaded methods (akin to what you get when using #!optional args),
or a single $To$List method which performed the dispatch internally.
So I'm guessing that the answer to my initial question is "No, there's
no way to invoke procedures defined with case-lambda from Java. Or,
more accurately, no simple/non-clunky way." Is that correct, or am I
missing something obvious?
Thanks,
Jamie
--
Jamison Hope
The PTR Group
www.theptrgroup.com
More information about the Kawa
mailing list