<html> <head> <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"> </head> <body bgcolor="#FFFFFF" text="#000000"> <p>Hello Otavio</p> <p>I agree with Werner. My objections against <tt>QuantityOperation</tt> proposal:</p> <ul> <li> <p>It blur the separation of concern between two distinct operations: multiplication (or division) and casting. I think that many peoples will be surprised by a multiplication operation not doing just a multiplication.</p> </li> <li> <p>While not wrong, it is not the spirit of Java parameterized type. The goal of Java parameterized type is to guarantee that you will never get <tt>ClassCastException</tt> at runtime if your code compiled without warnings, except in a few clearly identified places like <tt>Class.cast</tt>, <tt>Class.asSubclass</tt> or (in our case) <tt>asType</tt>. I think it is a better design to keep the potential <tt>ClassCastException</tt> isolated in as few "hotspots" as possible, in our case <tt>asType</tt> only.</p> </li> <li> <p>It imposes an unnecessary limitation on what the user can do. A user may have no idea about the actual quantity type and just want <tt>Quantity<?></tt>. For example he may implement a very generic operation working on any kind of quantity, and not being interested in its actual type. In such case, if <tt>QuantityOperation</tt> requires a <tt>Class<Q></tt> argument value and the user do not have this information, he would not be able to use the multiply operation.<br> </p> </li> <li> <p>It is a performance problem: we do not want to cast everytime. For example one may want to do:</p> </li> </ul> <blockquote> <pre>Quantity<Force> f = mass.multiply(speed).divide(time); </pre> </blockquote> <blockquote> <p>In this example, casting the result of <tt>mass.multiply(speed)</tt> is a waste of CPU because it is not yet the final result.<br> </p> </blockquote> <br> <br> Martin<br> <br> <br> <br> <div class="moz-cite-prefix">Le 03/11/14 08:53, Werner Keil a écrit :<br> </div> <blockquote cite="mid:CAAGawe28MfNg5U==G1M= " type="cite"> <div dir="ltr">Sorry, but it looks horribly overengineered and artificial<img src="cid:part1.00060008.02080202@geomatys.fr" goomoji="322" style="margin: 0px 0.2ex; vertical-align: middle;"> <div><br> </div> <div>People simply want to do</div> <div><font face="courier new, monospace">Quantity.multiply(Quantity)</font></div> <div><br> </div> <div>Not some artificial </div> <div><font face="courier new, monospace">Quantity.multiply(QuantityOperations)</font></div> <div class="gmail_extra"><br> </div> <div class="gmail_extra">And while Martin must be sleeping now in Asia, I am pretty sure, he recogizes the earlier approach to "trick" the compiler into something wrong.</div> <div class="gmail_extra">It just looks far more complicated and not intuitive that way.<br clear="all"> <div> <div class="gmail_signature"> <div dir="ltr"><span style="font-family:arial,sans-serif"> <p style="margin:0px;font-size:13px;border-collapse:collapse"><span style="color:rgb(0,0,0);text-transform:none;text-indent:0px;letter-spacing:normal;word-spacing:0px;white-space:normal;border-collapse:separate;font-size-adjust:none;font-stretch:normal"><span style="font-family:Helvetica"><span style="font-family:Calibri;font-size:12px"></span></span></span></p> <div><font face="Arial"><span style="font-family:arial,sans-serif"> <p style="margin:0px;font-size:13px;border-collapse:collapse"><br> </p> <p style="margin:0px;font-size:13px;border-collapse:collapse"><span style="font-family:Calibri" lang="EN-US"><br> </span></p> <p style="margin:0px;font-size:13px;border-collapse:collapse"><span style="font-family:Calibri" lang="EN-US">Werner</span></p> </span></font></div> </span></div> </div> </div> <br> <div class="gmail_quote">On Mon, Nov 3, 2014 at 12:38 AM, Otávio Gonçalves de Santana <span dir="ltr"><<a moz-do-not-send="true" href="mailto: " target="_blank"> </a>></span> wrote:<br> <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> <div dir="ltr"> <div>If we create a model to do this operations:</div> <div><br> </div> <div>/**</div> <div> * This interface represents operations to Quantity that needs verification</div> <div> * ( {@link Quantity#divide(Quantity)} and {@link Quantity#multiply(Quantity)}).</div> <div> * @author otaviojava</div> <div> *</div> <div> * @param <Q> to do the operation with Quantity<Q></div> <div> * @param <E> to verify and cast using Class<E></div> <div> */</div> <div>public interface QuantityOperations<Q extends Quantity<Q>, E extends Quantity<E>> {</div> <div><br> </div> <div> /**</div> <div> * The {@link Quantity} to do the operations</div> <div> * @return the quantity to operation</div> <div> */</div> <div> Quantity<Q> getQuantity();</div> <div><br> </div> <div> /**</div> <div> * Class to do the verification</div> <div> * @return the Class to verification</div> <div> * @see Unit#asType(Class)</div> <div> */</div> <div> Class<E> getQuantityClass();</div> <div><br> </div> <div>}</div> <div><br> </div> <div><br> </div> <div><font size="4"><b>In Quantity change the method to:</b></font></div> <div><br> </div> <div><T extends Quantity<T>, E extends Quantity<E>> Quantity<E> multipy(QuantityOperations<T, E> operation);</div> <div><br> </div> <div><br> </div> <div><font size="4"><b>The implementation:</b></font></div> <div><br> </div> <div> @Override</div> <div> public <T extends Quantity<T>, E extends Quantity<E>> Quantity<E> multipy(QuantityOperations<T, E> operation) {</div> <div><br> </div> <div> QuantityOperations<T, E> operation = supplier.get();</div> <div> return (Quantity<E>) multiply(operation.getQuantity())</div> <div> .asType(operation.getQuantityClass());</div> <div><br> </div> <div> }</div> <div><br> </div> <div><br> </div> <div>I believe this way, we will use the generics and can verify, so everyone happy <img src="cid:part3.04000303.04090008@geomatys.fr" goomoji="330" style="margin:0px 0.2ex;vertical-align:middle"></div> </div> <div class="gmail_extra"> <div> <div class="h5"><br> <div class="gmail_quote">On Sun, Nov 2, 2014 at 7:50 AM, Jean-Marie Dautelle <span dir="ltr"><<a moz-do-not-send="true" href="mailto: " target="_blank"> </a>></span> wrote:<br> <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> <div dir="ltr">Hello all, <div><br> </div> <div>I understand your points, but I have the feeling that we are making things more difficult than they need to be. </div> <div><br> </div> <div>We should not forget that the main subject is the unit-api not the "quantity-api".</div> <div><br> </div> <div>Let's put ourselves in the shoes of the user and see what he might want to do: </div> <div><font face="courier new, monospace"><br> </font></div> <div><font color="#741b47" face="courier new, monospace">public void wait(Time delay) { ... }</font></div> <div><font color="#741b47" face="courier new, monospace">Mass m = parcel.getWeight();</font></div> <div><font color="#741b47"> </font><br> </div> <div>I would assume that until that point everyone agree... <img src="cid:part5.03080608.01000008@geomatys.fr" goomoji="35C" style="margin:0px 0.2ex;vertical-align:middle"></div> <div> <div><br> </div> <div>Let's go deeper, we might want to do also:</div> <div><br> </div> <div><font color="#741b47" face="courier new, monospace">Length x = ...</font></div> <div><font color="#741b47" face="courier new, monospace">Time t = ...</font></div> <div><font color="#741b47" face="courier new, monospace">Velocity v = x.divide(t);</font></div> <div><br> </div> <div>If we can do that then I believe that even more people will be happy (especially if it does not involve reflection) <img src="cid:part3.04000303.04090008@geomatys.fr" goomoji="330" style="margin:0px 0.2ex;vertical-align:middle"></div> <div><br> </div> <div>... And YES, it is possible! </div> <div><br> </div> <div>The first thing we see is that some of the quantities interfaces will have extra methods.</div> <div><font color="#741b47" face="courier new, monospace"><br> </font></div> <div><font color="#741b47" face="courier new, monospace">interface Length extends Quantity<Length> {<br> </font></div> <div><font color="#741b47" face="courier new, monospace"> Area multiply(Quantity<Length>); // Overloading.</font></div> <div><font color="#741b47" face="courier new, monospace">}</font></div> <div><font color="#741b47" face="courier new, monospace">interface Area extends Quantity<Area> {</font></div> <div><font color="#741b47" face="courier new, monospace"> Volume multiply(Quantity<Length>); </font><span style="color:rgb(116,27,71);font-family:'courier new',monospace">// Overloading.</span></div> <div><font color="#741b47" face="courier new, monospace">}</font></div> <div><font color="#741b47" face="courier new, monospace">Length x = ...</font></div> <div><font color="#741b47" face="courier new, monospace">Volume v = x.multiply(x).multiply(x);</font></div> <div><br> </div> <div>There is no combination explosion since the number of predefined quantities is bounded. Furthermore, all these are convenient (optional) methods, the asType(Class<Q>) method can be used for complex cases.</div> <div><br> </div> <div>The question now is how do we create these Quantity instances?</div> <div><br> </div> <div>For this problem, the abstract factory pattern (GoF) is a perfect fit. All quantities coming from the same factory will work well together and this approach allows for many many optimizations under the hood !</div> <div><br> </div> <div><font color="#741b47" face="courier new, monospace">// Unit-API</font></div> <div><font color="#741b47" face="courier new, monospace">interface QuantityFactory {</font></div> <div><font color="#741b47" face="courier new, monospace"> Length lengthOf(double, Unit<Length>);</font></div> <div><font color="#741b47" face="courier new, monospace"> Mass massOf(double, Unit<Length>);</font></div> <div><font color="#741b47" face="courier new, monospace"> ...</font></div> <div><font color="#741b47" face="courier new, monospace">}</font></div> <div><font color="#741b47" face="courier new, monospace"><br> </font></div> <div><font color="#741b47" face="courier new, monospace">// Unit RI</font></div> <div><font color="#741b47" face="courier new, monospace">abstract class Quantities {</font></div> <div><font color="#741b47" face="courier new, monospace"> public static QuantityFactory DOUBLE = ...;</font></div> <div> <div><font color="#741b47" face="courier new, monospace"> public static QuantityFactory BIG_DECIMAL = ...;</font></div> </div> <div><font color="#741b47" face="courier new, monospace">}</font></div> <div><font color="#741b47" face="courier new, monospace"><br> </font></div> <div><font color="#741b47" face="courier new, monospace">Length x = DOUBLE.lengthOf(2.4, METER);</font></div> <div><font color="#741b47" face="courier new, monospace">Length two_x = x.add(x);</font></div> <div><font color="#741b47" face="courier new, monospace">Area x_square = x.multiply(x);</font></div> <div><br> </div> <div>(Note: I would have preferred plus, minus, time, divide but I can live with that <img src="cid:part7.00080905.05050106@geomatys.fr" goomoji="324" style="margin:0px 0.2ex;vertical-align:middle">)</div> <div><br> </div> </div> <div>There is no need for a Measurement class (and MeasurementConverter).</div> <div><br> </div> <div> <div>The quantity base class will be very close to what we have now except it does not implement any interface. </div> </div> <div><br> </div> <div><font color="#741b47" face="courier new, monospace">public interface Quantity<Q extends Quantity> {</font></div> <div><font color="#741b47" face="courier new, monospace"> Unit<Q> unit();</font></div> <div><font color="#741b47" face="courier new, monospace"> Number value();</font></div> <div><font color="#741b47" face="courier new, monospace"> double doubleValue(Unit<Q>); // To avoid boxing/deboxing.</font></div> <div><font color="#741b47" face="courier new, monospace"> Quantity<Q> add(Quantity<Q>);</font></div> <div><font color="#741b47" face="courier new, monospace"> ... </font></div> <div><font color="#741b47" face="courier new, monospace">}</font></div> <div><br> </div> <div>Of course if we can converge on this solution I would be really really happy (JScience has many types of numbers such as Rational, Complex for which this approach is a perfect fit) !!!</div> <div><br> </div> <div>Best regards,</div> <div>Jean-Marie.</div> </div> </blockquote> </div> <br> <br clear="all"> <div><br> </div> </div> </div> <span class="">-- <br> <div> <div dir="ltr">Otávio Gonçalves de Santana <div> <div style="text-align:center"><br> <div style="text-align:left"><font face="Tahoma">blog: </font><a moz-do-not-send="true" href="http://otaviosantana.blogspot.com.br/" style="text-align:center" target="_blank">http://otaviosantana.blogspot.com.br/</a></div> <div style="text-align:left">twitter: <a moz-do-not-send="true" href="http://twitter.com/otaviojava" target="_blank">http://twitter.com/otaviojava</a></div> <div style="text-align:left">site: <span style="text-align:center"><font color="#0000ee"><u><a moz-do-not-send="true" href="http://about.me/otaviojava" target="_blank">http://about.me/otaviojava</a></u></font></span></div> <div style="text-align:left">55 (11) 98255-3513</div> <div style="text-align:-webkit-auto"><br> </div> </div> </div> </div> </div> </span></div> </blockquote> </div> <br> </div> </div> </blockquote> <br> </body> </html>
Attachment:
gif4CekoapX6H.gif
Description: GIF image
Attachment:
giftU2R8G4OjN.gif
Description: GIF image
Attachment:
gifROmCLzZIKW.gif
Description: GIF image
Attachment:
gifdmqctm_hH5.gif
Description: GIF image
Re: Proposal |
(continued) | |
Werner Keil | 11/02/2014 | |
Jean-Marie Dautelle | 11/02/2014 | |
Jean-Marie Dautelle | 11/02/2014 | |
Werner Keil | 11/02/2014 | |
Jean-Marie Dautelle | 11/02/2014 | |
Otávio Gonçalves de Santana | 11/02/2014 | |
Werner Keil | 11/02/2014 | |
Otávio Gonçalves de Santana | 11/03/2014 | |
Otávio Gonçalves de Santana | 11/03/2014 | |
Martin Desruisseaux | 11/03/2014 | |
Re: Proposal |
Martin Desruisseaux | 11/03/2014 |
Martin Desruisseaux | 11/03/2014 | |
Werner Keil | 11/03/2014 | |
Otávio Gonçalves de Santana | 11/17/2014 | |
Martin Desruisseaux | 11/17/2014 | |
Werner Keil | 11/17/2014 | |
Otávio Gonçalves de Santana | 11/17/2014 | |
Werner Keil | 11/17/2014 | |
Otávio Gonçalves de Santana | 11/17/2014 | |
Werner Keil | 11/17/2014 | |
Otávio Gonçalves de Santana | 11/17/2014 |