Skip to main content

Re: Remove "generic" multiply/divide operations from Quantity

  • From: Werner Keil < >
  • To: " " < >
  • Subject: Re: Remove "generic" multiply/divide operations from Quantity
  • Date: Fri, 17 Oct 2014 21:40:14 +0200

Hi Jean-Marie/all,

I asked the guys from the Eclipse IoT project how they feel about having to
cast based on the current wildcard, if they have a strong opinion, we'll
see.
Could you for the record please both cast your vote on the corresponding
option? I know all points were made here sometimes multiple times, so
having a distinct place in the Doodle seems better[?]

P.s.:

While asType() causes fewer problems now under SE 8, seems, it never
preserved the target type either[?]

This is the original in JScience 5 Physics, it was 100% reused except
PhysicsUnit is called AbstractUnit (both abstract classes implementing
Unit) and PhysicsDimension QuantityDimension, the code looks identical

/**
211.* Casts this unit to a parameterized unit of specified nature or throw a
212.* ClassCastException if the dimension of the specified quantity and
213.* this unit's dimension do not match (regardless whether or not
214.* the dimensions are independent or not).
215.*
216.* @param type the quantity class identifying the nature of the unit.
217.* @throws ClassCastException if the dimension of this unit is different
218.*         from the {@link SI} dimension of the specified type.
219.* @see    SI#getUnit(Class)
220.*/
221.@Override
222.public final <T extends Quantity<T>> PhysicsUnit<T> asType(Class<T>
type) {
223.PhysicsDimension typeDimension = PhysicsDimension.getDimension(type);
224.if ((typeDimension != null) && (!this
.getDimension().equals(typeDimension)))
225.throw new ClassCastException("The unit: " + this + " is not compatible
with quantities of type " + type);
226.return (PhysicsUnit<T>) this;
227.}


Running a ReflectionDemo to get the actual generic type Q (this would only
work with a trick of storing it in the constructor, but that required
concrete classes for every case, no <?> or so) under SE:
https://github.com/unitsofmeasurement/uom-demos/blob/master/console/se/src/main/java/tec/uom/demo/se/ReflectionDemo.java
This is the output:
aUnit: tec.uom.se.unit.BaseUnit<javax.measure.quantity.Length>
interface javax.measure.quantity.Length
m
anotherUnit: tec.uom.se.AbstractUnit<Q>
Q


Naively speaking, one could have expected anotherUnit to have an actual
type argument of Volume, but it it Q instead.
Is that, how asType() should work?


The operation Unit.multiply() works, see "m²" but I was hoping we'd be able
to retrieve the "Volume" somehow, at least via Reflection under SE.

Let's see, what the Eclipse stakeholders say, I hope the question did not
scare them?[?]

Werner

On Fri, Oct 17, 2014 at 9:23 PM, Jean-Marie Dautelle 
< >
wrote:

> Hi all,
> I don't want to reopen a debate you might have closed but reading the
> arguments above unless anybody has contradictory arguments (please speak
> up). I don't see any good reason to use parameterized functions since they
> don't provide any compilation or runtime dimensional checking! I am
> therefore 100 % aligned with Martin on this topic.
> Cheers,
> Jean-Marie.
>
> On Fri, Oct 17, 2014 at 2:53 AM, Martin Desruisseaux <
>  >
>  wrote:
>
>>  Hello Jean-Marie
>>
>> Le 17/10/14 06:49, Jean-Marie Dautelle a écrit :
>>
>> Werner or Martin could you pose the question in simple terms that we can
>> all answer by yes or no.
>>
>> Some are proposing to change the signature of:
>>
>> Quantity<?> multiply(Quantity<?> that)
>>
>>  to (note that this signature express no relationship between T and R):
>>
>> <T extends Quantity<T>,R extends Quantity<R>> Quantity<R> 
>> multiply(Quantity<T> that)
>>
>>  (and similarly for divide, pow, etc.) in order to allow the following
>> to compile without the need to cast:
>>
>> Quantity<Length> length = ...;
>> Quantity<Time>   time   = ...;
>> Quantity<Speed>  speed  = length.divide(time);
>>
>>  But this cause the compiler to also accept:
>>
>> Quantity<Mass>   mass   = length.divide(time);
>> Quantity<Volume> volume = length.divide(time);
>> Quantity<Force>  force  = length.divide(time);
>> // Anything...
>>
>>  The proposed method does not express any real relationship between the
>> quantity types, since the type result of a multiplication is impossible to
>> express in Java. It is also impossible to implement without "*unsafe
>> cast*" warnings on the implementation side that can be proved to be
>> safe. The sole purpose of the proposed method is to trick the compiler for
>> automatically perform *unsafe* cast without warning on the user side. It
>> is equivalent to writing a method foo() in such a way that:
>>
>> List<String> list = foo();
>>
>>  can actually assign to list instances of List<Integer>, or List<Date>,
>> or anything else, without any compiler warning. Argument of promoters of
>> this approach is "the developer should know what he is doing". My argument
>> is: it break the whole purpose of parameterized type (bring us back to the
>> same level of safety as non-existence of parameterized types). Worst: it
>> gives to developer a false feeling of safety. Normally if an expression
>> like:
>>
>> Quantity<Mass> mass = ...,
>>
>>  compiled without compiler error or warnings, then the developer is
>> confident that mass is really a mass or null. The proposed change breaks
>> that confidence: mass could actually be a volume without any warning. I
>> also argue that my worry goes beyond JSR-363 scope: if libraries starts to
>> do that, it breaks the confidence that developers can have in Java
>> parameterized type in general. For this reason I'm 100% sure that this
>> proposal will be considered unacceptable by the JCP or any OpenJDK folk.
>>
>>
>>     Martin
>>
>>
>
>
> --
> It is not the strongest of the species that survives, nor the most
> intelligent. It is the one that is most adaptable to change. - Darwin's
> Origin of Species (digest)
>

Attachment: 329.gif
Description: GIF image

Attachment: 35F.gif
Description: GIF image

Attachment: 347.gif
Description: GIF image



Re: Remove "generic" multiply/divide operations from Quantity

(continued)

Re: Remove "generic" multiply/divide operations from Quantity

Martin Desruisseaux 10/18/2014

Re: Remove "generic" multiply/divide operations from Quantity

Martin Desruisseaux 10/18/2014

Re: Remove "generic" multiply/divide operations from Quantity

Martin Desruisseaux 10/18/2014

Re: Remove "generic" multiply/divide operations from Quantity

Werner Keil 10/17/2014

Re: Remove "generic" multiply/divide operations from Quantity

Martin Desruisseaux 10/18/2014

Re: Remove "generic" multiply/divide operations from Quantity

Martin Desruisseaux 10/17/2014

Re: Remove "generic" multiply/divide operations from Quantity

Werner Keil 10/17/2014

Re: Remove "generic" multiply/divide operations from Quantity

Martin Desruisseaux 10/17/2014

Re: Remove "generic" multiply/divide operations from Quantity

Martin Desruisseaux 10/18/2014

Re: Remove "generic" multiply/divide operations from Quantity

Jean-Marie Dautelle 10/17/2014

Re: Remove "generic" multiply/divide operations from Quantity

Werner Keil 10/17/2014

Re: Remove "generic" multiply/divide operations from Quantity

Martin Desruisseaux 10/18/2014

Re: Remove "generic" multiply/divide operations from Quantity

Werner Keil 10/18/2014

Re: Remove "generic" multiply/divide operations from Quantity

Martin Desruisseaux 10/18/2014

Re: Remove "generic" multiply/divide operations from Quantity

Martin Desruisseaux 10/18/2014

Re: Remove "generic" multiply/divide operations from Quantity

Martin Desruisseaux 10/17/2014

Re: Remove "generic" multiply/divide operations from Quantity

Werner Keil 10/16/2014

Re: Remove "generic" multiply/divide operations from Quantity

Martin Desruisseaux 10/18/2014
 
 
Close
loading
Please Confirm
Close