How to get the values in ABCL using Java

490 views Asked by At

I am searching the API for handling the values in Armed Bear Common Lisp (ABCL) implementation of the Common Lisp language in the JVM, using Java.

It works when a function returns (only) a list or a string.

When it returns multiple values I only can fetch the first returned value.

I do not know how to fetch the other values.

This is my test.lisp file :

(defun get-list ()
   (list "abc" 12 'a 'b))

(defun get-value ()
    (values "abc" 12 'a 'b))

And my Java code is :

public static void main(String[] args) throws Exception {
    Interpreter interpreter = Interpreter.createInstance();

    LispObject lobj = interpreter.eval("(load \"test.lisp\")");
    org.armedbear.lisp.Package defaultPackage = Packages.findPackage("CL-USER");

    Symbol myFunctionSym = defaultPackage.findAccessibleSymbol("GET-LIST");
    Function myFunction = (Function) myFunctionSym.getSymbolFunction();
    LispObject o = myFunction.execute();

    System.out.println(o.listp());    // this return false

    Symbol myFunctionSym2 = defaultPackage.findAccessibleSymbol("GET-VALUE");
    Function myFunction2 = (Function) myFunctionSym.getSymbolFunction();

    LispObject o2 = myFunction.execute();

}
4

There are 4 answers

0
Mars On

You could use multiple-value-bind, etc. on the Lisp side to assign to separate variables, and then access them individually in Java. Or you could call multiple-value-bind from Java. That's not the answer you are looking for. I assume what you'd really like is a method that you can call in Java that will get values other than the first one directly. I don't have that answer, but no one else has provided that answer.

However, poking around in the source and in javadoc, I see that classes Primitives and Symbol have methods VALUES and MULTIPLE_VALUE_BIND. I would guess that these are not designed to be called in user source code, but they might at least help you find the answer you want.

And finally, I think this might be something that you need to ask on the ABCL mailing list. You could report the full answer back here as an answer to your own question.

1
Svante On

Is multiple-value-bind or nth-value what you are looking for, or is there something more to this question?

0
easyE On

After a call to a function that returns multiple values, the values are associated with the executing LispThread until the next call into Lisp.

One may access the values object as a list of LispObject instances via a call to getValues() as evidenced by the following code:

org.armedbear.lisp.Package cl = Packages.findPackage("CL"); Symbol valuesSymbol = cl.findAccessibleSymbol("VALUES"); LispObject[] valuesArgs = { LispInteger.getInstance(1), LispInteger.getInstance(2) }; LispObject result = valuesSymbol.execute(valuesArgs); LispObject[] values = LispThread.currentThread().getValues(); for (LispObject value: values) { System.out.println("value ==> " + value.printObject()); }

0
JanDasWiesel On

I think there are two copy paste errors with your code above (you want to use myFunctionSym2 and myFunction2 in the last two lines, i.e.

Function myFunction2 = (Function) myFunctionSym2.getSymbolFunction();
LispObject o2 = myFunction2.execute();
System.out.println(o2.listp()); // additional line added by me

With this, it works for me.