From: Mike B. <be...@hi...> - 2003-10-27 07:35:11
|
(Sorry in advance for the longish post...) Perhaps ABL can use a similar exchange protocol than Jess or JLisa=20 (JSR-000084)? http://jcp.org/aboutJava/communityprocess/review/jsr094/index.html The Jess/JLisa protocols are simple store/fetch protocol that maps=20 Java instances to Lisp instances. In summary, the protocol works like this: 1) Java creates an instance of Interpreter (JLisa in my case) (In my latest code JLisa is a subclass of ABL.) 2) JLisa then provides for getObject and addObject methods that store things in a commonly accessible HashTable. (HashTable is synchronized...) 3) Java code submits commands to Interpreter through "executRules" .... "evaluate" in Interpreter. 4) Lisp retrieves objects from Java using "getObject" within Lisp and then processes the commands using the converted data=20 from Java. 5) Lisp finishes computation and exits, but leaving results accessible to Java. 6) Java regains control, retrieves the objects in results and continues execution. =20 NOTE: JSR000084 provides the so-called StatefulRulesSession that has methods for: boolean containsObject(Handle objectHandle) Handle addObject(Object object) List addObjects(List objList) void updateObject(Handle objectHandle,Object newObject) void removeObject(Handle handleObject) List getObjects() List getObjects(ObjectFilter filter) void executeRules() void reset() Object getObject(Handle handle) (I personally think it is too restrictive not to pass "known" handles to Lisp i.e. strings, or other identifiers, like Jess does. The problem is that=20 the JSR assumes that the rule engine will execute passed Java object but does not account for the (possible) language on the side (Jess, JLisa,=20 Lisp, Curry.)) (As a side note, I also have a little project to get=20 the JLisa equivalent using what I call JCurry, but it is not native ...=20 it involves GNUJavaProlog, a beast in its own right.) In code, Java does this: JLisa jLisa =3D new JLisa(); // Interpreter in ABL // ----------------------------------------------------- // 2. Set up the environment // ----------------------------------------------------- // "store" in Jess jLisa.addObject("GnuGoat", argGoat); // ----------------------------------------------------- // 3. Execute=20 // ----------------------------------------------------- // "executeCommand" in Jess, "evaluate" in Interpreter JLisa.executeRules("(batch " + argGoat.getRuleFile() + ")"); // ----------------------------------------------------- // 4. Get the results // ----------------------------------------------------- // "fetch" in Jess vo =3D (GnuGoatVO) =3D jLisa.getObject("GnuGoat"); Notice the "addObject" and "getObject" from Java send/receive objects=20 from Lisp. (The above is not exactly JSR000084, but that's because=20 in some easy the JSR is very restrictive... ) In Lisp, this is what gets executed from the "executeCommand", i.e.=20 "evaluate" in Interpreter: ;; In Lisp one defines imported Java classes and instances like this (defclass gg org.example.GNUGoatVO) ;; "getObject" retrieves an object from a HashMap=20 ;; that sits between Lisp and Java. ;; "fetch" in Jess (definstance gg (getObject "GnuGoat") static) ;; JLisa provides for rules like this one: (defrule initial-tasks (declare (salience 0)) (gg (statusCd ?X&:(=3D ?X 1)) (size ?P) (color ?W)) =3D> (okRequest ?P ?W ?R ?RT ?U) (updateObject (gg ( color "blue"))) ) =20 The above executes against Lisp and Java objects, producing results=20 and sending it back to Java. (All object sent or retrieved are=20 assumed to conform to the JavaBean specification i.e. compatible=20 get/set methods, serializable(s), etc.) As stated, Jess has slightly difference names than the above, and=20 JSR000084 has slightly difference interfaces but you get the idea,=20 it is a protocol for: * sending things, (automatically converting=20 values through JavaBean interfaces),=20 * processing in Lisp,=20 * returning things, (automatically updating, or creating objects=20 and values), and=20 * continue to process in Java - Mike -----Original Message----- From: arm...@li... [mailto:arm...@li...] On Behalf Of Peter Graves Sent: Sunday, October 26, 2003 7:41 PM To: Andr=E1s Simon Cc: arm...@li...; Doug McNaught Subject: Re: [j-devel] another patch to Java.java On Mon, 27 Oct 2003 at 02:32:11 +0100, Andr=E1s_Simon wrote: > Time for a java.lisp perhaps? Where this, and e.g. def-java-class &al > could go? Yes. > Thanks! Meanwhile, I realized that jfield should allow a class-ref and > (and not just class-name) argument. But I'm not sending a patch now,=20 > because I have a more ambitious plan, and if you think it's OK, I'll=20 > put everything in one big patch. So: there are a couple of places=20 > (jfield, jstatic, jcall,...) where jlinker lets one use arguments that > are easily converted to Java instances (fixnums, characters, strings,=20 > etc), so that there's no need to use jnew. Now instead of writing=20 > if(.. instanceof ..) .. else if (.. instanceof ..) ...'s all over the=20 > place, I think that using a small static inner class responsible for=20 > these conversion would pay off in the long run: > > ... > > But it probably increases startup time, and may have other drawbacks, > don't know, that's why I'm asking first. Startup time is probably not much of an issue, since we can eventually convert all of this stuff to be autoloaded. The way you suggest would certainly work. But maybe overloaded static methods would work too: public static Object javaInstance(Fixnum arg) { return new Integer(((Fixnum)arg).getValue()); } public static Object javaInstance(LispCharacter arg) { return new Character(((LispCharacter)arg).getValue()); } etc. with a catch-all for Lisp types that don't convert to specific Java types: public static Object javaInstance(LispObject arg) { // Maybe some additional conversions... // If not handled... throw new ConditionThrowable(new TypeError()); } There are, after all, only a handful of types that should get converted automatically. Then you could do: f.set(instance, javaInstance(args[2])); instead of if (args[2] instanceof Fixnum) f.set(instance,new Integer (((Fixnum)args[2]).getValue())); else if (args[2] instanceof LispFloat) f.set(instance,new Double (((LispFloat)args[2]).getValue())); else ... I think this approach might be a tiny bit faster at runtime, but that's probably not going to be your primary concern if you're using this interface... ;) -Peter ------------------------------------------------------- This SF.net email is sponsored by: The SF.net Donation Program. Do you like what SourceForge.net is doing for the Open Source Community? Make a contribution, and help us add new features and functionality. Click here: http://sourceforge.net/donate/ _______________________________________________ armedbear-j-devel mailing list arm...@li... https://lists.sourceforge.net/lists/listinfo/armedbear-j-devel |