Constructing a java lambda expression?

Alan Ruttenberg alanruttenberg at gmail.com
Thu Aug 25 04:36:33 UTC 2022


So in order to implement this I need to know the interface to use for the
lambda? Presumably I can determine this with reflection.

An example of one of the functions that takes the lambda is defined:

public final NitfSegmentsFlow forEachImageSegment(final
Consumer<ImageSegment> consumer)

But consumer has two methods: accept and andThen

Eventually it looks like accept is called on the consumer. So in this case
it looks like I need to use jinterface-implementation and define the accept
method, no lambda necessary?

What confuses me now is if a lambda is passed as the test code I'm reading
does:

forEachImageSegment(imageSegment -> {do something})

How does java know that the lambda is the implementation of accept rather
than andThen. Or more practically, how do I figure out which method to
implement without reading the source code?

Thanks,
Alan


On Wed, Aug 24, 2022 at 4:14 AM Alessio Stalla <alessiostalla at gmail.com>
wrote:

> 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/20220825/5b58036f/attachment.html>


More information about the armedbear-devel mailing list