Prev: Putting passwords in a properties file?
Next: Interview
From: Jeff Higgins on 3 Oct 2009 19:15 John B. Matthews wrote: > In article <ha7fvl$8g0$1(a)news.eternal-september.org>, > Jeff Higgins <oohiggins(a)yahoo.com> wrote: > >> John B. Matthews wrote: >>> In article <7ig1fsF319h9fU1(a)mid.individual.net>, >>> Mike Amling <mamling(a)rmcis.com> wrote: >>> >>>> Surely someone somewhere must have something like this already, with >>>> classes or interfaces for time, distance, mass, etc. >>> JSR-275: <http://jscience.org/api/index.html> >>> >> <https://jscience.dev.java.net/servlets/ReadMsg?list=dev&msgNo=654> > > Thank you for responding. I'm not sufficiently familiar with the process > to understand the import of the discussion you cited. The measure > package was moved to javax.measure in anticipation of standardization as > part of JSR-275. Failing that, the code still seems useful. Is there > some reason to be wary? > The JSR process is opaque. I would rather have seen another development process chosen, and the measure.* packages remain in the jscience namespace. I am not certain what benefit the API of the measure.* packages accrue from becoming a 'standard technical specification'. The code is useful, available, and liberally licensed. The JSR process is opaque.
From: Roedy Green on 3 Oct 2009 19:43 On Sat, 03 Oct 2009 12:54:20 -0700, Roedy Green <see_website(a)mindprod.com.invalid> wrote, quoted or indirectly quoted someone who said : >I think it is time to think of programs as directed graphs, displayed >with filters to show you only what is of immediate interest. Word processing got stuck in a rut for a while, with markup languages like Tek and Wordstar command codes. Once we decided the internal format was no concern of the users, it greatly simplified the process of creating documents. We need to do something similar for programming. -- Roedy Green Canadian Mind Products http://mindprod.com When you can�t find a bug, you are probably looking in the wrong place. When you can�t find your glasses, you don�t keep scanning the same spot because you are convinced that is where you left them. ~ Roedy
From: Roedy Green on 3 Oct 2009 20:12 On Sat, 03 Oct 2009 16:12:16 -0400, Lew <noone(a)lewscanon.com> wrote, quoted or indirectly quoted someone who said : >Generics is not inscrutable. With a little study, as little as reading the >short free chapter on generics from Bloch's /Effective Java/, it's utterly >scrutable. Can you really explain the difference between <?> vs <Dog> vs <? extends Dog> vs <E extends Dog> vs <? super T> in a few paragraphs so that at least 50% of your readers will follow? If you want to make a stab at it, I would love to cannibalise your work for the Java glossary Generics entry. The best I have seen has been explanations of what a few specific examples do. When you find people resorting to examples to explain, You know it is difficult material. I guess it depends on your base point. Generics are scrutable relative to Revelation, but inscrutable compared say with a typical explanation of parameter passing. I found generics the most confusing feature of Java. Look how many posts there are on them, quite often coming from relatively experienced programmers. You might measure a feature in a language by the power it gives you divided by the effort you need to expend to learn it and use it. Generics have a fairly low payback number. I don't know if the complexity was unavoidable, or as a side effect of insisting on type erasure. Generics lack the elegance of other Java features. The syntax is ad hoc, unshaved, irregular, Perlish, unfinished. With most features, you have and ah ha moment, and all falls into place. Everything is as it should be. It could be no other plausible way. You "grok" them in fullness, and no longer need to read a manual to write code. Generics don't do that, at least not yet. -- Roedy Green Canadian Mind Products http://mindprod.com When you can�t find a bug, you are probably looking in the wrong place. When you can�t find your glasses, you don�t keep scanning the same spot because you are convinced that is where you left them. ~ Roedy
From: Joshua Cranmer on 3 Oct 2009 21:34 On 10/03/2009 08:12 PM, Roedy Green wrote: > Can you really explain the difference between > <?> vs<Dog> vs<? extends Dog> vs<E extends Dog> vs<? super T> > in a few paragraphs so that at least 50% of your readers will follow? It helps to explain generics by thinking in terms of containers--most generified types are containers in some form or other. Generified types can be declared thusly: public class Container<T> {} The `T' represents a type. The implementer of Container has no idea what type it is, it's just some type, any type. Since we don't know what it is, all we can guarantee is that it is an Object of some type (all non-primitive types are a subclass of Object, and generics don't use primitive types), so wherever `T' is found in the implementation, you can mentally replace it with `Object' for the same effect. Sometimes, though, we don't want to let people include any old object. To do this, we declare an upper bound on the type like so: public class Container<T extends Number> {} Now only numeric types can be stored in the container. Also, since we know that any given value of `T' has to be a subclass of Number in some fashion, we can replace it with `Number' instead of `Object'. You can also specify a /lower/ bound on the type, by specifying `super' instead of `extends'. The rationale behind this will be made clear slightly later. To use generics, you merely have to replace the appropriate parameter with your class. So an integer container is declared as type `Container<Integer>' (again primitive types are not valid here; this is due to implementation necessities. But don't forget that Java 5+ autoboxes primitive types). An important fact to realize is that subtyping of generic types isn't quite what would be expected at first: if A is a subclass of B, Container<A> is not a subtype of Container<B>. Remember that a container stores it type: you can store any B into a Container<B>, so being able to cast from Container<A> to Container<B> means you can put a B into the Container<A>. The way around this is to state that you don't know what's contained inside in the container. We do this with the type `?' (also known as the wildcard type): Container<?> stores /something/, but we don't know what. Since Container<A> stores objects of type `A', it stores objects of any type, so it is a subtype of (and thus convertible to) Container<?>. Conversely, since we don't know what type a Container<?> holds, we can't store stuff inside the container. However, since we know that all Containers must store Objects, we can treat whatever is in the Container as an Object. In effect, the wildcard turns the Container into a read-only object: you can't write into Container<?>, but you can read from it. This is internally enforced by the special subtyping rules of generic objects; the exact mechanisms require some mathematical theory that I will not delve in here. Similarly to how we limited the storage type of a container with the `extends Number' relationship, we can limit the type of a wildcard. A type `Container<? extends Number>' indicates that the object stores something that is at least of type Number. Once again, that means that instead of viewing it as containing something that is at least an Object, we can see it as containing something that is at least a Number. Types can also be recursive. A recursive type is something of the form class Foo<T extends Foo<T>>. You generally subclass or implement interfaces of these form in the fashion class Bar extends Foo<Bar>. The purpose of a recursive type is to operate on itself in some fashion: think of Comparable's compareTo method. Classes implementing Comparable only compare objects of the same class as them, not of other classes implementing Comparable. Methods can also be generified. The rationale here is for utility methods operating on generic container classes. Here is an example of a generic method definition: public static <T> T move(Container<T> from, Container<? super T> to); Here, you also saw an example of the use of the lower bounds. We want to be able to take an Integer stored in a Container<Integer> and put it into a Container<Number>. Using upper bounds is also possible here, but if we were to do that, we'd be given a Number and not an Integer. The object being moved is already known to be a Number, so we should we unnecessarily restrict the type of return? The other main use of lower bounds is in recursive types. Specifying <T extends A<T>> is generally incorrect: <T extends A<? super T>> is typically more correct. How was that? > The best I have seen has been explanations of what a few specific > examples do. When you find people resorting to examples to explain, > You know it is difficult material. I think that examples are not so much needed to explain, but more to motivate why the developers did things the way they did. Generics are actually rather simple once you understand what they actually mean (what I gave above is roughly how I came to realize their underlying mechanisms), which explains why some operations that would seemingly be safe are actually not safe. Well, rare types (mixing raw types and generics) don't actually make sense in many cases. Suffice to say that I am personally extremely aggravated that List.class is of type Class<List> and not Class<List<?>>, which makes for some particularly annoying typing situtations. > You might measure a feature in a language by the power it gives you > divided by the effort you need to expend to learn it and use it. > Generics have a fairly low payback number. I don't know if the > complexity was unavoidable, or as a side effect of insisting on type > erasure. I wouldn't say that they have fairly low payback. What they increase substantially is compile-time type safety. Having spent considerable amounts of time in languages that have very little compile-time type safety, trust me when I say that the more the compiler complains to you about, the better. > Generics lack the elegance of other Java features. The syntax is ad > hoc, unshaved, irregular, Perlish, unfinished. Actually, the syntax is cribbed from C++ templates. Blame Bjarne Stroustrup. > With most features, you have and ah ha moment, and all falls into > place. Everything is as it should be. It could be no other plausible > way. You "grok" them in fullness, and no longer need to read a manual > to write code. Generics don't do that, at least not yet. To me, generics has had that moment. The best way I can think to explain them is to think of a generic type as containing an object of some type; wildcard objects are ways of saying that you don't know what it contains, but you may have some information. -- Beware of bugs in the above code; I have only proved it correct, not tried it. -- Donald E. Knuth
From: Lew on 3 Oct 2009 21:39
Lew wrote: >> Generics is not inscrutable. With a little study, as little as reading the >> short free chapter on generics from Bloch's /Effective Java/, it's utterly >> scrutable. Roedy Green wrote: > Can you really explain the difference between > <?> vs <Dog> vs <? extends Dog> vs <E extends Dog> vs <? super T> > in a few paragraphs so that at least 50% of your readers will follow? I don't need to. Joshua Bloch and Brian Goetz have already done that. Read their stuff. Really, read it. -- Lew |