Use Advanced Search to search the entire archive.
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
m²
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