public inbox for kawa@sourceware.org
 help / color / mirror / Atom feed
* using lambda to implement one method interface
@ 2017-09-17 15:32 Sonny To
  2017-09-17 15:38 ` Sonny To
  0 siblings, 1 reply; 13+ messages in thread
From: Sonny To @ 2017-09-17 15:32 UTC (permalink / raw)
  To: Kawa mailing list

follwing docs at https://www.gnu.org/software/kawa/Anonymous-classes.html

(let ((handler (android.os.Handler (android.os.Looper:getMainLooper)))
      (runnable (lambda ()
                        (android.util.Log:i "scm" "run me"))))
  (handler:post runnable)
  )

that doesn't seem to work. Do I need to give type hints to be able to do this?

I'm getting this error:

#|.....44|# #|.....45|# #|.....46|# #|.....47|# /dev/stdin:46:17:
warning - type function is incompatible with required type
java.lang.Runnable
java.lang.ClassCastException: don't know how to coerce
gnu.expr.LambdaExp$Closure to java.lang.Runnable
        at gnu.bytecode.ObjectType.coerceFromObject(ObjectType.java:180)
        at gnu.kawa.functions.Convert.apply2(Convert.java:38)
        at gnu.mapping.Procedure2.applyToObject(Procedure2.java:62)
        at java.lang.reflect.Method.invoke(Native Method)
        at gnu.mapping.CallContext$ReflectMethodHandle.invokeExact(CallContext.java:726)
        at gnu.mapping.Procedure.applyToConsumerDefault(Procedure.java:75)
        at java.lang.reflect.Method.invoke(Native Method)
        at gnu.mapping.CallContext$ReflectMethodHandle.invokeExact(CallContext.java:726)
        at gnu.mapping.CallContext.runUntilDone(CallContext.java:586)
        at gnu.mapping.CallContext.getFromContext(CallContext.java:616)
        at gnu.expr.Expression.eval(Expression.java:52)
        at gnu.expr.ApplyExp.apply(ApplyExp.java:161)
        at gnu.expr.LetExp.apply(LetExp.java:72)
        at gnu.expr.ModuleExp.evalModule2(ModuleExp.java:281)
        at gnu.expr.ModuleExp.evalModule(ModuleExp.java:211)
        at kawa.Shell.run(Shell.java:283)
        at kawa.Shell.run(Shell.java:196)
        at kawa.Shell.run(Shell.java:183)
        at kawa.TelnetRepl.apply0(TelnetRepl.java:25)
        at gnu.mapping.RunnableClosure.run(RunnableClosure.java:75)
        at java.lang.Thread.run(Thread.java:764)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: using lambda to implement one method interface
  2017-09-17 15:32 using lambda to implement one method interface Sonny To
@ 2017-09-17 15:38 ` Sonny To
  2017-09-17 15:59   ` Per Bothner
  0 siblings, 1 reply; 13+ messages in thread
From: Sonny To @ 2017-09-17 15:38 UTC (permalink / raw)
  To: Kawa mailing list

this works

(let ((handler (android.os.Handler (android.os.Looper:getMainLooper)))
      )
  (handler:post (lambda ()
                        (android.util.Log:i "scm" "run me")))
  )

this is non-intuitive. why doesn't it work if i bind the lambda to a
symbol? seems like a bug to me


On Sun, Sep 17, 2017 at 8:32 AM, Sonny To <son.c.to@gmail.com> wrote:
> follwing docs at https://www.gnu.org/software/kawa/Anonymous-classes.html
>
> (let ((handler (android.os.Handler (android.os.Looper:getMainLooper)))
>       (runnable (lambda ()
>                         (android.util.Log:i "scm" "run me"))))
>   (handler:post runnable)
>   )
>
> that doesn't seem to work. Do I need to give type hints to be able to do this?
>
> I'm getting this error:
>
> #|.....44|# #|.....45|# #|.....46|# #|.....47|# /dev/stdin:46:17:
> warning - type function is incompatible with required type
> java.lang.Runnable
> java.lang.ClassCastException: don't know how to coerce
> gnu.expr.LambdaExp$Closure to java.lang.Runnable
>         at gnu.bytecode.ObjectType.coerceFromObject(ObjectType.java:180)
>         at gnu.kawa.functions.Convert.apply2(Convert.java:38)
>         at gnu.mapping.Procedure2.applyToObject(Procedure2.java:62)
>         at java.lang.reflect.Method.invoke(Native Method)
>         at gnu.mapping.CallContext$ReflectMethodHandle.invokeExact(CallContext.java:726)
>         at gnu.mapping.Procedure.applyToConsumerDefault(Procedure.java:75)
>         at java.lang.reflect.Method.invoke(Native Method)
>         at gnu.mapping.CallContext$ReflectMethodHandle.invokeExact(CallContext.java:726)
>         at gnu.mapping.CallContext.runUntilDone(CallContext.java:586)
>         at gnu.mapping.CallContext.getFromContext(CallContext.java:616)
>         at gnu.expr.Expression.eval(Expression.java:52)
>         at gnu.expr.ApplyExp.apply(ApplyExp.java:161)
>         at gnu.expr.LetExp.apply(LetExp.java:72)
>         at gnu.expr.ModuleExp.evalModule2(ModuleExp.java:281)
>         at gnu.expr.ModuleExp.evalModule(ModuleExp.java:211)
>         at kawa.Shell.run(Shell.java:283)
>         at kawa.Shell.run(Shell.java:196)
>         at kawa.Shell.run(Shell.java:183)
>         at kawa.TelnetRepl.apply0(TelnetRepl.java:25)
>         at gnu.mapping.RunnableClosure.run(RunnableClosure.java:75)
>         at java.lang.Thread.run(Thread.java:764)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: using lambda to implement one method interface
  2017-09-17 15:38 ` Sonny To
@ 2017-09-17 15:59   ` Per Bothner
  2017-09-17 16:04     ` Sonny To
  0 siblings, 1 reply; 13+ messages in thread
From: Per Bothner @ 2017-09-17 15:59 UTC (permalink / raw)
  To: Sonny To, Kawa mailing list

On 09/17/2017 08:38 AM, Sonny To wrote:
> this works
> 
> (let ((handler (android.os.Handler (android.os.Looper:getMainLooper)))
>        )
>    (handler:post (lambda ()
>                          (android.util.Log:i "scm" "run me")))
>    )
> 
> this is non-intuitive. why doesn't it work if i bind the lambda to a
> symbol? seems like a bug to me

Perhaps a documentation bug: It may not be clear that when the manual
say "required type" in:

     This is possible when the required type is an interface or
     abstract class with a Single (exactly one) Abstract Methods.

we mean the type required by the *compile-time context* of the expression.

This is a deliberate design limitation, not a bug.  This way the anonymous
class can be created a compile-time, not run-time.  Doing it at run-time
would be more difficult and more expensive. Kawa has always put a high
priority on performance.

Perhaps a future Kawa extension will allow "SAM-conversion" at run-time,
but it is not currently in the plans.
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: using lambda to implement one method interface
  2017-09-17 15:59   ` Per Bothner
@ 2017-09-17 16:04     ` Sonny To
  2017-09-17 16:50       ` Per Bothner
  0 siblings, 1 reply; 13+ messages in thread
From: Sonny To @ 2017-09-17 16:04 UTC (permalink / raw)
  To: Per Bothner; +Cc: Kawa mailing list

Thanks for the explanation. However, I'm still not clear about
compile-time. I'm evaluating this in the TelnetRepl. its interpreted
no?

On Sun, Sep 17, 2017 at 8:59 AM, Per Bothner <per@bothner.com> wrote:
> On 09/17/2017 08:38 AM, Sonny To wrote:
>>
>> this works
>>
>> (let ((handler (android.os.Handler (android.os.Looper:getMainLooper)))
>>        )
>>    (handler:post (lambda ()
>>                          (android.util.Log:i "scm" "run me")))
>>    )
>>
>> this is non-intuitive. why doesn't it work if i bind the lambda to a
>> symbol? seems like a bug to me
>
>
> Perhaps a documentation bug: It may not be clear that when the manual
> say "required type" in:
>
>     This is possible when the required type is an interface or
>     abstract class with a Single (exactly one) Abstract Methods.
>
> we mean the type required by the *compile-time context* of the expression.
>
> This is a deliberate design limitation, not a bug.  This way the anonymous
> class can be created a compile-time, not run-time.  Doing it at run-time
> would be more difficult and more expensive. Kawa has always put a high
> priority on performance.
>
> Perhaps a future Kawa extension will allow "SAM-conversion" at run-time,
> but it is not currently in the plans.
> --
>         --Per Bothner
> per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: using lambda to implement one method interface
  2017-09-17 16:04     ` Sonny To
@ 2017-09-17 16:50       ` Per Bothner
  2017-09-17 18:54         ` Sonny To
  0 siblings, 1 reply; 13+ messages in thread
From: Per Bothner @ 2017-09-17 16:50 UTC (permalink / raw)
  To: Sonny To; +Cc: Kawa mailing list

On 09/17/2017 09:03 AM, Sonny To wrote:
> Thanks for the explanation. However, I'm still not clear about
> compile-time. I'm evaluating this in the TelnetRepl. its interpreted
> no?

Yes and no. "Compile-time" is when the Scheme expression is parsed,
analyzed, and (normally) translated to JVM bytecode.  On most platforms,
even when you type an expression into a REPL, it gets translated to bytecode
and then loaded on-the-fly using java.lang.ClassLoader.defineClass.

Because Android doesn't have ClassLoader.defineClass (because it uses dex),
we don't translate REPL input to bytecode. Instead, there is an
interpreter that evaluates to tree (Expression) form of the expression.

Determining when "SAM-conversion" (converting lambda to anonymous class)
is allowed is done at compile-time.  On most platforms, creating the
anonymous class is also done at time-time.  On Android, the last step is
deferred to run-time, using a ProcedurallProxy class, but that only supports
converting a lambda to an interface, not a class.

It probably wouldn't be difficult to use ProcedurallProxy at run-time to convert
a procedure value to a class instance. However, it would require changes to
error handling: Instead of compiling a simple cast, we have to compile to a more
complex (and slower) procedure.  There is also a question of what warning messages,
if any to emit.  Perhaps worth revisiting if/when we implement
"Optional strict typing along with an explicit dynamic type"
(https://www.gnu.org/software/kawa/Ideas-and-tasks.html#Optional-strict-typing-along-with-an-explicit-dynamic-type).

(The 'dynamic' type is already partially supported.)
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: using lambda to implement one method interface
  2017-09-17 16:50       ` Per Bothner
@ 2017-09-17 18:54         ` Sonny To
  2017-09-17 20:02           ` Per Bothner
  0 siblings, 1 reply; 13+ messages in thread
From: Sonny To @ 2017-09-17 18:54 UTC (permalink / raw)
  To: Per Bothner; +Cc: Kawa mailing list

this is a big problem for my use case...

i wouldn't be able to do something like this on android at runtime

(object (java.lang.Runnable)
((run (a ::void))::void
         (+ 1 1)
         ))



On Sun, Sep 17, 2017 at 9:50 AM, Per Bothner <per@bothner.com> wrote:
> On 09/17/2017 09:03 AM, Sonny To wrote:
>>
>> Thanks for the explanation. However, I'm still not clear about
>> compile-time. I'm evaluating this in the TelnetRepl. its interpreted
>> no?
>
>
> Yes and no. "Compile-time" is when the Scheme expression is parsed,
> analyzed, and (normally) translated to JVM bytecode.  On most platforms,
> even when you type an expression into a REPL, it gets translated to bytecode
> and then loaded on-the-fly using java.lang.ClassLoader.defineClass.
>
> Because Android doesn't have ClassLoader.defineClass (because it uses dex),
> we don't translate REPL input to bytecode. Instead, there is an
> interpreter that evaluates to tree (Expression) form of the expression.
>
> Determining when "SAM-conversion" (converting lambda to anonymous class)
> is allowed is done at compile-time.  On most platforms, creating the
> anonymous class is also done at time-time.  On Android, the last step is
> deferred to run-time, using a ProcedurallProxy class, but that only supports
> converting a lambda to an interface, not a class.
>
> It probably wouldn't be difficult to use ProcedurallProxy at run-time to
> convert
> a procedure value to a class instance. However, it would require changes to
> error handling: Instead of compiling a simple cast, we have to compile to a
> more
> complex (and slower) procedure.  There is also a question of what warning
> messages,
> if any to emit.  Perhaps worth revisiting if/when we implement
> "Optional strict typing along with an explicit dynamic type"
> (https://www.gnu.org/software/kawa/Ideas-and-tasks.html#Optional-strict-typing-along-with-an-explicit-dynamic-type).
>
> (The 'dynamic' type is already partially supported.)
>
> --
>         --Per Bothner
> per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: using lambda to implement one method interface
  2017-09-17 18:54         ` Sonny To
@ 2017-09-17 20:02           ` Per Bothner
  2017-09-18  6:35             ` Sonny To
  0 siblings, 1 reply; 13+ messages in thread
From: Per Bothner @ 2017-09-17 20:02 UTC (permalink / raw)
  To: Sonny To; +Cc: Kawa mailing list

On 09/17/2017 11:54 AM, Sonny To wrote:
> this is a big problem for my use case...
> 
> i wouldn't be able to do something like this on android at runtime
> 
> (object (java.lang.Runnable)
> ((run (a ::void))::void
>           (+ 1 1)
>           ))

You can probably work around it with:

(->java.lang.Runnable
   (lambda ()::void (set! i (+ i 1))))

BTW - I assume (a ::void) is just a typo.  Kawa should probably complain about it.
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: using lambda to implement one method interface
  2017-09-17 20:02           ` Per Bothner
@ 2017-09-18  6:35             ` Sonny To
  2017-09-18  8:17               ` Sonny To
  2017-09-18 11:22               ` Sudarshan S Chawathe
  0 siblings, 2 replies; 13+ messages in thread
From: Sonny To @ 2017-09-18  6:35 UTC (permalink / raw)
  To: Per Bothner; +Cc: Kawa mailing list

[-- Attachment #1: Type: text/plain, Size: 726 bytes --]

yes that was an error. copy and paste of testing code.  how would I
implement an interface with multiple methods?


On Sun, Sep 17, 2017 at 11:02 PM Per Bothner <per@bothner.com> wrote:

> On 09/17/2017 11:54 AM, Sonny To wrote:
> > this is a big problem for my use case...
> >
> > i wouldn't be able to do something like this on android at runtime
> >
> > (object (java.lang.Runnable)
> > ((run (a ::void))::void
> >           (+ 1 1)
> >           ))
>
> You can probably work around it with:
>
> (->java.lang.Runnable
>    (lambda ()::void (set! i (+ i 1))))
>
> BTW - I assume (a ::void) is just a typo.  Kawa should probably complain
> about it.
> --
>         --Per Bothner
> per@bothner.com   http://per.bothner.com/
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: using lambda to implement one method interface
  2017-09-18  6:35             ` Sonny To
@ 2017-09-18  8:17               ` Sonny To
  2017-09-18 13:59                 ` Per Bothner
  2017-09-18 11:22               ` Sudarshan S Chawathe
  1 sibling, 1 reply; 13+ messages in thread
From: Sonny To @ 2017-09-18  8:17 UTC (permalink / raw)
  To: Per Bothner; +Cc: Kawa mailing list

It seems implementing single method interface using lambda only works
with methods and not in constructors?

for example, this fails

#|kawa:137|# (java.lang.Thread (lambda ()
                    (+ 1 1)))
#|.....138|# /dev/stdin:137:1: warning - no possibly applicable method
'<init>/valueOf' in java.lang.Thread
gnu.mapping.WrongArguments
        at gnu.mapping.MethodProc.matchFailAsException(MethodProc.java:136)
        at gnu.kawa.reflect.Invoke.applyToObject(Invoke.java:264)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at gnu.mapping.CallContext$ReflectMethodHandle.invokeExact(CallContext.java:726)
        at gnu.mapping.Procedure.applyToConsumerDefault(Procedure.java:75)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at gnu.mapping.CallContext$ReflectMethodHandle.invokeExact(CallContext.java:726)
        at gnu.mapping.CallContext.runUntilDone(CallContext.java:586)
        at gnu.expr.ModuleExp.evalModule2(ModuleExp.java:342)
        at gnu.expr.ModuleExp.evalModule(ModuleExp.java:211)
        at kawa.Shell.run(Shell.java:283)
        at kawa.Shell.run(Shell.java:196)
        at kawa.Shell.run(Shell.java:183)
        at kawa.repl.processArgs(repl.java:714)
        at kawa.repl.main(repl.java:820)

On Mon, Sep 18, 2017 at 9:35 AM, Sonny To <son.c.to@gmail.com> wrote:
> yes that was an error. copy and paste of testing code.  how would I
> implement an interface with multiple methods?
>
>
> On Sun, Sep 17, 2017 at 11:02 PM Per Bothner <per@bothner.com> wrote:
>>
>> On 09/17/2017 11:54 AM, Sonny To wrote:
>> > this is a big problem for my use case...
>> >
>> > i wouldn't be able to do something like this on android at runtime
>> >
>> > (object (java.lang.Runnable)
>> > ((run (a ::void))::void
>> >           (+ 1 1)
>> >           ))
>>
>> You can probably work around it with:
>>
>> (->java.lang.Runnable
>>    (lambda ()::void (set! i (+ i 1))))
>>
>> BTW - I assume (a ::void) is just a typo.  Kawa should probably complain
>> about it.
>> --
>>         --Per Bothner
>> per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: using lambda to implement one method interface
  2017-09-18  6:35             ` Sonny To
  2017-09-18  8:17               ` Sonny To
@ 2017-09-18 11:22               ` Sudarshan S Chawathe
  2017-09-18 14:24                 ` Per Bothner
  1 sibling, 1 reply; 13+ messages in thread
From: Sudarshan S Chawathe @ 2017-09-18 11:22 UTC (permalink / raw)
  To: Sonny To; +Cc: Kawa mailing list

> how would I implement an interface with multiple methods?

I have found that simply defining the methods required by an interface
(with the proper names and type signatures) works, in the sense that the
resulting objects can be used anywhere that requires objects
implementing the interface.

Regards,

-chaw

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: using lambda to implement one method interface
  2017-09-18  8:17               ` Sonny To
@ 2017-09-18 13:59                 ` Per Bothner
  0 siblings, 0 replies; 13+ messages in thread
From: Per Bothner @ 2017-09-18 13:59 UTC (permalink / raw)
  To: Sonny To; +Cc: Kawa mailing list

On 09/18/2017 01:16 AM, Sonny To wrote:
> It seems implementing single method interface using lambda only works
> with methods and not in constructors?
> 
> for example, this fails
> 
> #|kawa:137|# (java.lang.Thread (lambda ()
>                      (+ 1 1)))
> #|.....138|# /dev/stdin:137:1: warning - no possibly applicable method
> '<init>/valueOf' in java.lang.Thread
> gnu.mapping.WrongArguments

Yes and no.  Method selection uses different code than the code that checks
for type compatibility.  It's mostly the same tests, but the former doesn't
handle lambda-to-interface conversion.  It would be non-trivial to change that.

However, this works:

(java.lang.Thread (->java.lang.Runnable (lambda () (newline))))

-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: using lambda to implement one method interface
  2017-09-18 11:22               ` Sudarshan S Chawathe
@ 2017-09-18 14:24                 ` Per Bothner
  2017-09-18 14:31                   ` Sudarshan S Chawathe
  0 siblings, 1 reply; 13+ messages in thread
From: Per Bothner @ 2017-09-18 14:24 UTC (permalink / raw)
  To: Sudarshan S Chawathe, Sonny To; +Cc: Kawa mailing list

On 09/18/2017 04:22 AM, Sudarshan S Chawathe wrote:
>> how would I implement an interface with multiple methods?
> 
> I have found that simply defining the methods required by an interface
> (with the proper names and type signatures) works, in the sense that the
> resulting objects can be used anywhere that requires objects
> implementing the interface.

Not sure I understand what you mean by that.

The problem is defining an instance of an interface:
(1) with multiple methods;
(2) on-the-fly, in a REPL;
(3) on Android, which doesn't (didn't?) have ClassLoader.defineClass.

It should be possible to generalize gnu.kawa.reflect.ProceduralProxy
to handle multiple methods and corresponding implementing procedures.
The tricky is specifying which method is implemented by which procedure.

Perhaps problem (3) above is no longer a problem, at least on Android 8.
https://developer.android.com/reference/java/lang/ClassLoader.html
says that the byte array to defineClass "should have the format of a valid
class file as defined by The Javaâ„¢ Virtual Machine Specification."

So maybe we need to update the compilerAvailable test in ModuleExp.java.
If we now can generate classes on-the-fly then that removes a major
limitation of Kawa on Android.  (At least on newer Android versions.)
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: using lambda to implement one method interface
  2017-09-18 14:24                 ` Per Bothner
@ 2017-09-18 14:31                   ` Sudarshan S Chawathe
  0 siblings, 0 replies; 13+ messages in thread
From: Sudarshan S Chawathe @ 2017-09-18 14:31 UTC (permalink / raw)
  To: Per Bothner; +Cc: Sonny To, Kawa mailing list


Mea culpa.  I temporarily lost sight of the fact that the discussion was
in the context of a REPL on Android.

-chaw

> Subject: Re: using lambda to implement one method interface
> Cc: Kawa mailing list <kawa@sourceware.org>
> From: Per Bothner <per@bothner.com>
> Date: Mon, 18 Sep 2017 07:22:56 -0700
> 
> On 09/18/2017 04:22 AM, Sudarshan S Chawathe wrote:
> >> how would I implement an interface with multiple methods?
> > 
> > I have found that simply defining the methods required by an interface
> > (with the proper names and type signatures) works, in the sense that the
> > resulting objects can be used anywhere that requires objects
> > implementing the interface.
> 
> Not sure I understand what you mean by that.
> 
> The problem is defining an instance of an interface:
> (1) with multiple methods;
> (2) on-the-fly, in a REPL;
> (3) on Android, which doesn't (didn't?) have ClassLoader.defineClass.
> 
> It should be possible to generalize gnu.kawa.reflect.ProceduralProxy
> to handle multiple methods and corresponding implementing procedures.
> The tricky is specifying which method is implemented by which procedure.
> 
> Perhaps problem (3) above is no longer a problem, at least on Android 8.
> https://developer.android.com/reference/java/lang/ClassLoader.html
> says that the byte array to defineClass "should have the format of a valid
> class file as defined by The Java™ Virtual Machine Specification."
> 
> So maybe we need to update the compilerAvailable test in ModuleExp.java.
> If we now can generate classes on-the-fly then that removes a major
> limitation of Kawa on Android.  (At least on newer Android versions.)
> -- 
> 	--Per Bothner
> per@bothner.com   http://per.bothner.com/
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2017-09-18 14:31 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-17 15:32 using lambda to implement one method interface Sonny To
2017-09-17 15:38 ` Sonny To
2017-09-17 15:59   ` Per Bothner
2017-09-17 16:04     ` Sonny To
2017-09-17 16:50       ` Per Bothner
2017-09-17 18:54         ` Sonny To
2017-09-17 20:02           ` Per Bothner
2017-09-18  6:35             ` Sonny To
2017-09-18  8:17               ` Sonny To
2017-09-18 13:59                 ` Per Bothner
2017-09-18 11:22               ` Sudarshan S Chawathe
2017-09-18 14:24                 ` Per Bothner
2017-09-18 14:31                   ` Sudarshan S Chawathe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).