<div dir="ltr">Sent that message a bit too soon.  Fixed a typo and added 9.0 version for stream methods.<br><div><div><div><div><br><div class="gmail_quote"><div dir="ltr">---------- Forwarded message ---------<br>From: William Burns &lt;<a href="mailto:mudokonman@gmail.com">mudokonman@gmail.com</a>&gt;<br>Date: Tue, Feb 9, 2016 at 3:21 PM<br>Subject: Re: Lambda Serialization<br>To: infinispan -Dev List &lt;<a href="mailto:infinispan-dev@lists.jboss.org">infinispan-dev@lists.jboss.org</a>&gt;<br></div><br><br><div dir="ltr"><div>Also I should note that this is not binary compatible since map/filter and other intermediate operations will need to return a CacheStream instead of a Stream as they do currently.   This is to make sure the terminal operator when invoked is done upon the CacheStream which defines the Serializable interfaces.  Thus it would have to wait until Infinispan 9.0.<br><br></div>This however would be used with [1], which is targeted for 8.2, to allow for much easier way to provide Callable/Runnable instances through lambdas without having to do the ugly casting.<br><br>[1] <a href="https://issues.jboss.org/browse/ISPN-6074" target="_blank">https://issues.jboss.org/browse/ISPN-6074</a><br></div><br><div class="gmail_quote"><div dir="ltr">On Tue, Feb 9, 2016 at 11:36 AM William Burns &lt;<a href="mailto:mudokonman@gmail.com" target="_blank">mudokonman@gmail.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I wanted to propose a pretty simple way of making the lambdas serializable by default that I stumbled upon while working on another issue.<div><br></div><div>I noticed that in the method resolution of the compiler it does some nice things [1].  To be more specific when you have 2 methods with the same name but vary by argument types, it will attempt to pick the most &quot;specific&quot; one.  Specific in this case you can think of if I can cast one argument type to the other but it can&#39;t be cast to this type, then this one is most specific.</div><div><br></div><div>Here is an example, given the following class<br><br></div><div>interface SerializableFunction&lt;T, R&gt; extends Serializable, Function&lt;T, R&gt;<br></div><div><br></div><div>The stream interface already defines:<br></div><div><br></div><div>   Stream map(Function&lt;? super T, ? extends R&gt; mapper);</div><div><br></div><div>But we could add this to the CacheStream interface<br></div><div><br></div><div>  CacheStream map(SerializableFunction&lt;? super T, ? extends R&gt; mapper);</div><div><br></div><div>In this case you have 2 different map methods accessible from your CacheStream instance.  When passing a lambda the Java compiler will automatically choose the most specific one (in this case the SerializableFunction one since Function can&#39;t be cast to SerializableFunction).  This will then make the lambda automatically Serializable.  In this way nothing special has to be done (ie. explicit cast) to make the instance Serializable.<br><br></div><div>This allows anyone using our Cache interface to immediately get lambdas that are Serializable when using Streams.<br><br></div><div>The main problem however would be ambiguity because the Serialization would only be applied assuming you are using a defined class of CacheStream etc.  Also this means there are 2 methods (but that seems fine to me), so it could cause a bit of confusion.  The non serialization method is still helpful if people want to their own Externalizer, since their implementation doesn&#39;t have to implement Serializable then.<br><br></div><div>What do you guys think?  It seems like a decent compromise to me.<br></div><div><br></div><div> - Will<br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div>[1] <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.5" target="_blank">https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.5</a><br><div><br></div><div><br></div></div></div></blockquote></div></div></div></div></div></div></div>