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]

case-lambda and Java


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




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