From: Timothy H. <tim...@ma...> - 2003-03-09 22:48:19
|
Hi Boris, On Sunday, March 9, 2003, at 12:55 AM, Boris Tschirschwitz wrote: > Hi. > > Assuming that my ignorance mostly stems from not having studied jscheme > long enough, I checked the list archives for answers, Thanks for checking first! > but I couldn't find > anything and the sf system seems to be really terrible. What made it so horrible? Response time, organization,...? > > I am wondering about the following: If I want to program using classes > and > objects, do I have to make all my structures Java classes, objects, ...? > I wonder if this might restrict me in manipulating these objects in the > scheme way. Yes, this sounds very vague, b/c I am not absolutely sure > what > I am asking and hope that someone on the list might understand it better > than I do. You should look at the webpage: http://jscheme.sourceforge.net/jscheme/src/dclass/dclass.html which describes several approaches for working with Java classes from Jscheme. In summary, the main approaches we've tried are: * don't define any new classes (i.e. use Java as a library language), e.g. see the jlib/Swing.scm library * when this doesn't work, define a wrapper class that allows you to dynamically assign functionality to a Java class from Jscheme (e.g. see the jlib/SchemeCanvas.java class) * for an interface you can use the Proxy class to implement that interface at runtime in Jscheme * for a non-interface, you can use the dclass package to define Java classes in Scheme and compile them to Java, e.g. the weblink above gives an example of defining a class "Compare" in a package "frog". This example is in dclass/test.scm, reproduced below: > > (define-class > (package frog) > (import java.util.Comparator) > (public class Compare implements Comparator) > ;; Design issue, fields must be public for Jscheme code to access. > > (public Procedure predicate) > > (public Compare (Procedure predicate) > (.predicate$ this predicate)) > > (public boolean predicate (Object a Object b) > ((.predicate$ this) a b)) > > (public int compare (Object a Object b) > (cond ((.predicate this a b) -1) > ((.predicate this b a) 1) > (else 0))) > > (public boolean equals (Object that) > (and (eq? (.getClass this) (.getClass that)) > (eq? (.predicate$ this) (.predicate$ that)))) > > (public int hashCode () 0)) > > The following script shows how to run that example: > % java -cp lib/jscheme.jar:src jscheme.REPL Note: we have to add a folder "src" to the classpath as dclass will compile all new classes into this folder.. > > > Jscheme 6.1.0 3/7/2003 http://jscheme.sourceforge.net > > > > (load "elf/basic.scm") > #t > > (load "dclass/dclass.scm") > #t At this point we have loaded in the dclass compiler... we are now ready to compile a new class, we could do this interactively by making a call to > (define-class (package-frog) ....) But that can be error-prone...., so we load it in from a file.... > > (load "dclass/test.scm") ; the compiler echoes the generated code to the console as well as to the file > Writing Java code for frog.Compare to > /Users/tim/Research/Software/jscheme/src/frog/Compare.java > // Generated by Jscheme by tim on Sun Mar 09 04:16:20 EST 2003 > package frog; > import java.util.Comparator; > import jsint.Procedure; > import jscheme.JS; > public class Compare implements Comparator { public Procedure predicate; > public Compare(Procedure predicate) { JS.call(DCLASS_C_Compare0, this, > predicate); > } > private static final Procedure DCLASS_C_Compare0 =(Procedure) > JS.eval("(lambda (this predicate) (.predicate$ this predicate))"); > public boolean predicate(Object a, Object b) { return > JS.booleanValue(JS.call(DCLASS_M_I_predicate1, this, a, b)); > } > private static final Procedure DCLASS_M_I_predicate1 =(Procedure) > JS.eval("(lambda (this a b) ((.predicate$ this) a b))"); > public int compare(Object a, Object b) { return > JS.intValue(JS.call(DCLASS_M_I_compare2, this, a, b)); > } > private static final Procedure DCLASS_M_I_compare2 =(Procedure) > JS.eval("(lambda (this a b) (cond ((.predicate this a b) -1) > ((.predicate this b a) 1) (else 0)))"); > public boolean equals(Object that) { return > JS.booleanValue(JS.call(DCLASS_M_I_equals3, this, that)); > } > private static final Procedure DCLASS_M_I_equals3 =(Procedure) > JS.eval("(lambda (this that) (and (eq? (.getClass this) (.getClass > that)) (eq? (.predicate$ this) (.predicate$ that))))"); > public int hashCode() { return > JS.intValue(JS.call(DCLASS_M_I_hashCode4, this)); > } > private static final Procedure DCLASS_M_I_hashCode4 =(Procedure) > JS.eval("(lambda (this) 0)"); > } > Compiling Java code for frog.Compare and it compiles the new code to src/from/Compare.class where it is immediately available to us > #t > Next we use it to sort two arrays.... using two different comparators c1 and c2 > > (define c (frog.Compare. <)) > frog.Compare@0 > > (define arr #(1 4 2 5 6 79 3 4 8 5 3)) > #(1 4 2 5 6 79 3 4 8 5 3) > > (Arrays.sort arr c) > #null > > arr > #(1 2 3 3 4 4 5 5 6 8 79) > > > (define c2 (frog.Compare. (lambda(x y) (or (< (first x) (first y)) (> > (second x) (second y)))))) .... this is a wierd sorting predicate, you can have A<B and B<A for certain lists A,B, e.g. (1 5) and (4 6) > frog.Compare@0 > > (define arr2 #((1 5) (4 3) (4 6) (5 3) (1 3) (1 6) (5 3) (5 4))) > #((1 5) (4 3) (4 6) (5 3) (1 3) (1 6) (5 3) (5 4)) > > (Arrays.sort arr2 c2) > #null > > arr2 > #((1 6) (1 5) (4 6) (1 3) (4 3) (5 4) (5 3) (5 3)) > > > (exit) > #t > % > I hope this starts to answer your question... > Would it be beneficial to use something like Meroon? Perhaps, but then you may have to worry about interacting with two object systems, Java's and Meroon's. I haven't tried to get Meroon working in Jscheme and it might be interesting! Best, ---Tim--- |