<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 7 Nov 2016, at 23:42, Hendrik Ebbers &lt;<a href="mailto:hendrik.ebbers@me.com" class="">hendrik.ebbers@me.com</a>&gt; wrote:</div><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class="">Let’s say we have the following 2 interfaces:<br class=""><br class=""><font face="Courier New" class="">public interface&nbsp;CachedValue&lt;V&gt; {<br class="">&nbsp; &nbsp;&nbsp;V getCachedValue();<br class="">}<br class=""><br class="">public interface&nbsp;RealValue&lt;V&gt; {<br class="">&nbsp; &nbsp;&nbsp;V getRealValue();<br class="">}</font><br class=""><br class="">Based on this interfaces we can easily create a new class that implements both interfaces:<br class=""><br class=""><font face="Courier New" class="">public class&nbsp;CachableValue&lt;V&gt;&nbsp;implements&nbsp;CachedValue&lt;V&gt;, RealValue&lt;V&gt; {<br class=""><br class="">&nbsp; &nbsp;&nbsp;private&nbsp;V&nbsp;cachedValue;<br class=""><br class="">&nbsp; &nbsp;&nbsp;@Override<br class="">&nbsp; &nbsp;&nbsp;public&nbsp;V getCachedValue() {<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return cachedValue;<br class="">&nbsp; &nbsp;&nbsp;}<br class=""><br class="">&nbsp; &nbsp;&nbsp;@Override<br class="">&nbsp; &nbsp;&nbsp;public&nbsp;V getRealValue() {<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;V realValue = receiveValueFromServer();<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;cachedValue&nbsp;= realValue;<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;realValue;<br class="">&nbsp; &nbsp;&nbsp;}<br class=""><br class="">&nbsp; &nbsp;&nbsp;private&nbsp;V receiveValueFromServer() {<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return ServerConnector.getCurrentValue(); //Some fake code<br class="">&nbsp; &nbsp;&nbsp;}<br class="">}</font><br class=""><br class="">Let’s try to add a constraint annotation to validate the content of such a CachableValue:<br class=""><br class=""><font face="Courier New" class="">private&nbsp;CachableValue&lt;@NotEmpty String&gt;&nbsp;myValue;</font><br class=""><br class="">Based on this definition you have absolutely no idea if the @NotEmpty annotation is defined for the real value, the cached value or both values. From my point of view this is a big problem.&nbsp;Until now its was always easy to see how the validation of a model should work based on the validation information (annotations) in the model. With this new approach you have no idea&nbsp;what will happen.<br class=""><br class="">The most simple solution would be to add the support only to some special container / wrapper classes like collections, JavaFX properties, etc. I think this is a bad idea since new default&nbsp;might come to future versions of JavaSE and JavaEE (or maybe Spring) and that won’t be supported. Based on this I think that it will be a must to support all wrapper types.&nbsp;<br class=""></div></div></blockquote></div><br class=""><div class="">Interesting.</div><div class=""><br class=""></div><div class="">I did think about extractors of subtypes but not extractors of parallel types.</div><div class="">I have been thinking about it and explored a few paths:</div><div class="">- validating all parallel extractors</div><div class="">- use one</div><div class="">- validate none</div><div class="">- fail</div><div class=""><br class=""></div><div class="">In the end, I think the cleanest solution is to follow what Ceylon and Java do for default methods, they don’t allow ambiguous use and force a redefinition.</div><div class=""><a href="http://stackoverflow.com/questions/16764791/how-does-java-8-new-default-interface-model-works-incl-diamond-multiple-inhe#16788295" class="">http://stackoverflow.com/questions/16764791/how-does-java-8-new-default-interface-model-works-incl-diamond-multiple-inhe#16788295</a></div><div class=""><br class=""></div><div class="">In practice for us, if&nbsp;there are extractors for&nbsp;CachedValue and for&nbsp;RealValue, then CachableValue should fail and require the definition of an explicit&nbsp;CachableValue extractor.</div><div class="">What is interesting in this case is that&nbsp;CachableValue extractor can be see as either:</div><div class="">- a&nbsp;ManyContainerValuesExtractor that will return getCachedValue and getRealValue just like a Collection would return get(0) and get(1). This approach does not reflect the path difference though</div><div class="">- or two SingleContainerValueExtractor from the same container type and the same value type (*)</div><div class=""><br class=""></div><div class="">(*) this is something we do not allow for the moment, we have a unique extractor per container + value type. We need to think about how to make that work and still allow people to override extractors.</div><div class=""><br class=""></div><div class="">So back to your original concern of uncertainty, I think forcing a more specific extractor solves the uncertainty that you mentioned. Granted, the user would have to know the extractor(s) behavior but in many ways, people do need to know about that regardless.</div><div class=""><br class=""></div><div class="">Thoughts?</div><div class=""><br class=""></div><div class="">Emmanuel</div></body></html>