Constructing a java lambda expression?

Alessio Stalla alessiostalla at gmail.com
Wed Aug 24 07:42:59 UTC 2022


Function is a convenient interface for cases when a more specific interface
does not exist. But any Java interface with a single abstract method can be
the target of a lambda expression:

new Thread(() -> { System.out.println("foo"); }).run();

The Thread constructor takes a Runnable argument, not a Function.

Lambda is just syntax sugar for interfaces with a single method, so you can
reproduce them on ABCL with the jinterface thing + some macrology.

On Wed, 24 Aug 2022 at 05:10, Vibhu Mohindra <vibhu.mohindra at gmail.com>
wrote:

> On 23/08/2022 05:27, Alan Ruttenberg wrote:
> > There's a library I want to use that takes a lambda as an argument.
> > Anyone know how to construct one in ABCL?
>
> I assume it's a Java library taking a Java Lambda that you want to call
> from ABCL.
>
> A Java Lambda is really an instance of one of the classes in
> java.util.function. Which one depends on how many parameters it has and
> whether it returns a value. Let's assume your library wants a Java
> Lambda that has one parameter and returns a value. That's a
> java.util.function.Function. Say it looks like this:
>
> //Lib.java
> public class Lib {
>    public static void f(java.util.function.Function f) {
>      System.out.println("You answered: " + f.apply(5));
>    }
> }
>
> such that it can be used from Java with a Java Lambda like this:
>
> Lib.f((Object x) -> (Integer)x * (Integer)x);
> => You answered: 25
>
> You'd like to give it a Lisp Lambda from ABCL as follows:
>
> (jstatic "f" "Lib" #'(lambda (x) (* x x)))
>
> but that's not allowed because although Java can implicitly convert from
> a Java Lambda to a java.util.function.Function, it can't convert from a
> Lisp Lambda to a java.util.function.Function.
>
> A Lisp Lambda is really an org.armedbear.lisp.Function. So one solution
> is to adapt that.
>
> //Adaptor.java
> import org.armedbear.lisp.*;
> public class Adaptor implements java.util.function.Function {
>    private org.armedbear.lisp.Function lispFn;
>    public Adaptor(org.armedbear.lisp.Function lispFunction) {
>      this.lispFn = lispFunction;
>    }
>    public Object apply(Object input) {
>      return lispFn.execute(
>        JavaObject.getInstance(input, true)).javaInstance();
>    }
> }
>
> and use it from ABCL like this:
>
> (jstatic "f" "Lib" (jnew "Adaptor" #'(lambda (x) (* x x))))
> => You answered: 25
> => NIL
>
> ----
> Notes:
>
> I'm on Java 10, ABCL-1.4.0 (which is old).
> I did this to build and run, starting with the jar and two java files in
> the current directory:
> javac -classpath abcl-1.4.0.jar:. Adaptor.java Lib.java
> java -classpath abcl-1.4.0.jar:. org.armedbear.lisp.Main
>  > (jstatic "f" "Lib" (jnew "Adaptor" #'(lambda (x) (* x x))))
>
> You can probably create the Adaptor class from within ABCL if you don't
> like that it's written in Java, but I don't remember how to. ABCL's
> documentation might describe such bytecode generation somewhere.
>
> Pointers:
> Java: java.util.function.*
> ABCL: In org.armedbear.lisp, LispObject, JavaObject, Function
>
>
> --
> Vibhu
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/armedbear-devel/attachments/20220824/8946f0f6/attachment.html>


More information about the armedbear-devel mailing list