Re: JDK1.5, improved FOR loop and generics - How?!

Discussion in 'Java' started by Jesper Nordenberg, Apr 2, 2004.

  1. Roedy Green <> wrote in message news:<>...
    > On Tue, 30 Mar 2004 11:50:14 +0200, Hans Kratz <>
    > wrote or quoted :
    >
    > >
    > >If you complain about redundancy you also have to complain about the
    > >other parts of the language, e.g. about having to specify "long" in
    > >"long time = System.currentTimeMillis()".

    >
    > Exactly. I suggest the notion of LIKE. You can declare a temporary
    > variable like some other variable or method result. That way your
    > temporary automatically tracks. e.g. selects long instead of int, when
    > the master template variable is grown or shrunk.


    Yes, it would be nice to get rid of the variable type declaration and
    write for example:

    var x = myObject.getSomething();
    x.someMethod();

    I think the reason why Sun is not likely to add this feature to the
    Java language is that you could potentially run into trouble if you
    change the return type of getSomething() to a class that have a
    someMethod() with different semantics than the original someMethod().
    Today you can only change the return type to a sub class of the
    original class/interface, and thus the someMethod() is guaranteed to
    have the same sematics.

    /Jesper Nordenberg
     
    Jesper Nordenberg, Apr 2, 2004
    #1
    1. Advertising

  2. Jesper Nordenberg

    Phillip Lord Guest

    >>>>> "Jesper" == Jesper Nordenberg <> writes:

    Jesper> Roedy Green <> wrote in
    Jesper> message news:<>...
    >> On Tue, 30 Mar 2004 11:50:14 +0200, Hans Kratz
    >> <> wrote or quoted :
    >>
    >> >
    >> >If you complain about redundancy you also have to complain about
    >> >the other parts of the language, e.g. about having to specify
    >> >"long" in "long time = System.currentTimeMillis()".

    >>
    >> Exactly. I suggest the notion of LIKE. You can declare a
    >> temporary variable like some other variable or method result.
    >> That way your temporary automatically tracks. e.g. selects long
    >> instead of int, when the master template variable is grown or
    >> shrunk.


    Jesper> Yes, it would be nice to get rid of the variable type
    Jesper> declaration and write for example:

    Jesper> var x = myObject.getSomething(); x.someMethod();


    The problem here is that Java's type calculus is not just not clever
    enough and therefore requires an lot of programmer annotation of the
    code to say anything useful.

    What you want is something like this SML. Given this definition of a
    function (calculating the factoral) it tells you....

    fun fact 0 = 1
    | fact n = n * fact(n-1);

    that this function takes an int and returns an int. It knows this
    because of it knows the factoral of 0 is 1 which is an int.

    val fact = fn : int -> int


    Java's type system is just not that rich. Even if you come up with
    specific solutions where you can do omit the type declaration you
    probably can't in general and still have Java give you the guarantees
    that you expect.

    Cheers

    Phil
     
    Phillip Lord, Apr 2, 2004
    #2
    1. Advertising

  3. Jesper Nordenberg

    Hans Kratz Guest

    Phillip Lord wrote:
    > The problem here is that Java's type calculus is not just not clever
    > enough and therefore requires an lot of programmer annotation of the
    > code to say anything useful.


    I don't think that the verbosity mandated by Java is a problem. I see it
    more as an advantage considering that it improves the readability and
    maintainability of source code. Furthermore with modern Java IDEs you
    can add the necessary type declaration with one or two keystrokes.

    When using the advanced type inference mechanism in Standard ML I had to
    constantly ask myself if the result of this or that expression is now a
    list of tuples of lists or a tuple of lists of lists. ;-)


    Best regards,


    Hans
    --
    Hans Kratz
    Omnicore Software
    http://www.omnicore.com
     
    Hans Kratz, Apr 4, 2004
    #3
  4. Jesper Nordenberg

    Roedy Green Guest

    On Sun, 04 Apr 2004 11:46:33 +0200, Hans Kratz <>
    wrote or quoted :

    >I don't think that the verbosity mandated by Java is a problem. I see it
    >more as an advantage considering that it improves the readability and
    >maintainability of source code.


    It is nice to READ, but not to maintain. When a type changes, there
    is no easy way to change all the instances of that type that should
    change and leave the rest intact. Further, when you screw up, you
    often don't find out till the program is running in production.

    --
    Canadian Mind Products, Roedy Green.
    Coaching, problem solving, economical contract programming.
    See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
     
    Roedy Green, Apr 5, 2004
    #4
  5. Jesper Nordenberg

    Hans Kratz Guest

    Roedy Green wrote:
    >>I don't think that the verbosity mandated by Java is a problem. I see it
    >>more as an advantage considering that it improves the readability and
    >>maintainability of source code.

    >
    > It is nice to READ, but not to maintain. When a type changes, there
    > is no easy way to change all the instances of that type that should
    > change and leave the rest intact.


    What kind of "type change" are you referring to? Adding a
    method/field/etc. obviously does not cause any problems. The name of a
    type can be easily changed with a renaming tool. If the return type of a
    method is changed than it seems likely that all invocations have to be
    adapted somehow anyway.

    > Further, when you screw up, you
    > often don't find out till the program is running in production.


    Huh? Java contains all those strong compile-time checks to prevent just
    that.


    Best regards,


    Hans
    --
    Hans Kratz
    Omnicore Software
    http://www.omnicore.com
     
    Hans Kratz, Apr 6, 2004
    #5
  6. Hans Kratz <> wrote in message news:<c4oli9$2jrash$-berlin.de>...
    > Phillip Lord wrote:
    > > The problem here is that Java's type calculus is not just not clever
    > > enough and therefore requires an lot of programmer annotation of the
    > > code to say anything useful.

    >
    > I don't think that the verbosity mandated by Java is a problem. I see it
    > more as an advantage considering that it improves the readability and
    > maintainability of source code. Furthermore with modern Java IDEs you
    > can add the necessary type declaration with one or two keystrokes.


    True, the gains of automatically inferred types of local variables
    would not be substantial. The real gain would be a more powerful type
    system for generic classes and methods. The current Java generics
    suggestion is not very powerful and has a lot of annoying properties.

    > When using the advanced type inference mechanism in Standard ML I had to
    > constantly ask myself if the result of this or that expression is now a
    > list of tuples of lists or a tuple of lists of lists. ;-)


    Of course these kind of problems could also be solved by a good IDE
    that infers the type of a variable while you type and uses that
    information to provide code completion etc., just like a normal Java
    IDE.

    /Jesper Nordenberg
     
    Jesper Nordenberg, Apr 8, 2004
    #6
  7. Jesper Nordenberg

    Phillip Lord Guest

    >>>>> "Hans" == Hans Kratz <> writes:

    Hans> Phillip Lord wrote:
    >> The problem here is that Java's type calculus is not just not
    >> clever enough and therefore requires an lot of programmer
    >> annotation of the code to say anything useful.



    Hans> I don't think that the verbosity mandated by Java is a
    Hans> problem. I see it more as an advantage considering that it
    Hans> improves the readability and maintainability of source
    Hans> code. Furthermore with modern Java IDEs you can add the
    Hans> necessary type declaration with one or two keystrokes.

    It's not the verbosity which is irritating, its the duplication. You
    have to tell Java things that you want it to just know.


    Hans> When using the advanced type inference mechanism in Standard
    Hans> ML I had to constantly ask myself if the result of this or
    Hans> that expression is now a list of tuples of lists or a tuple of
    Hans> lists of lists. ;-)


    This I don't understand. I have this problem when I write lisp, but
    with SML it should tell you whether its a list of tuples of lists...

    I'm not actually advocating SML's type system as perfect. I think its
    just an interesting example of what can be done.

    Phil
     
    Phillip Lord, Apr 8, 2004
    #7
  8. Jesper Nordenberg

    Neal Gafter Guest

    Jesper Nordenberg wrote:
    > Hans Kratz <> wrote in message news:<c4oli9$2jrash$-berlin.de>...
    >
    >>Phillip Lord wrote:
    >>
    >>>The problem here is that Java's type calculus is not just not clever
    >>>enough and therefore requires an lot of programmer annotation of the
    >>>code to say anything useful.

    >>
    >>I don't think that the verbosity mandated by Java is a problem. I see it
    >>more as an advantage considering that it improves the readability and
    >>maintainability of source code. Furthermore with modern Java IDEs you
    >>can add the necessary type declaration with one or two keystrokes.

    >
    >
    > True, the gains of automatically inferred types of local variables
    > would not be substantial. The real gain would be a more powerful type
    > system for generic classes and methods. The current Java generics
    > suggestion is not very powerful and has a lot of annoying properties.


    Can you please be more specific?
     
    Neal Gafter, Apr 8, 2004
    #8
  9. Neal Gafter wrote:
    > Jesper Nordenberg wrote:
    >
    >> Hans Kratz <> wrote in message
    >> news:<c4oli9$2jrash$-berlin.de>...
    >>
    >>> Phillip Lord wrote:
    >>>
    >>>> The problem here is that Java's type calculus is not just not clever
    >>>> enough and therefore requires an lot of programmer annotation of the
    >>>> code to say anything useful.
    >>>
    >>>
    >>> I don't think that the verbosity mandated by Java is a problem. I see
    >>> it more as an advantage considering that it improves the readability
    >>> and maintainability of source code. Furthermore with modern Java IDEs
    >>> you can add the necessary type declaration with one or two keystrokes.

    >>
    >>
    >>
    >> True, the gains of automatically inferred types of local variables
    >> would not be substantial. The real gain would be a more powerful type
    >> system for generic classes and methods. The current Java generics
    >> suggestion is not very powerful and has a lot of annoying properties.

    >
    >
    > Can you please be more specific?


    Type erasure. Prevents a lot of perfectly sensible generic code. No
    generic arrays. No primitive template instantiations. No generic methods
    like (sorry for the C++ syntax, I don't remember the java syntax off-hand):

    template <typename Sequence>
    char charAt(Sequence s, int index)
    {
    return s.charAt(index);
    }

    (This would have been useful pre 1.4 since you can't extend String nor
    StringBuffer.)

    But this was part of the design constraints, I understand. I.e. no
    breaking of backwards compatibility. So in that respect, I think the
    generics are rather nice.
    --
    Daniel Sjöblom
    Remove _NOSPAM to reply by mail
     
    =?ISO-8859-1?Q?Daniel_Sj=F6blom?=, Apr 8, 2004
    #9
  10. Jesper Nordenberg

    Hans Kratz Guest

    Phillip Lord wrote:
    > Hans> When using the advanced type inference mechanism in Standard
    > Hans> ML I had to constantly ask myself if the result of this or
    > Hans> that expression is now a list of tuples of lists or a tuple of
    > Hans> lists of lists. ;-)
    >
    > This I don't understand. I have this problem when I write lisp, but
    > with SML it should tell you whether its a list of tuples of lists...


    If the developer makes heavy use of type inference he omits type
    declarations for local variables, return types and parameters of
    functions (just as in your factorial example). The omitted information
    makes the code much harder to read/maintain especially if functional
    language constructs such as map, foldl, etc. are heavily used.

    Thus I think it is good that the language requires type declaration for
    local variables, method parameters, return types, ...

    This would make it much harder to write ugly code like the following
    snippet taken from an OCR project I coauthored a long time ago. ;-)

    --- snip ---
    local
    fun posOf(x,[])=0|
    posOf(x,y::ys)=if x=y then 0 else 1+posOf(x,ys);
    in
    fun displacement(h1,h2) =
    let val n = (length h1) + (length h2) + 1; val d = length h2 in
    let val list = List.tabulate(n, fn x => histDiff(h1,h2,x - d)) in
    posOf((foldl Int.min (hd list) list),list)-d
    end
    end;
    end;
    --- snip ---


    Best regards,


    Hans
    --
    Hans Kratz
    Omnicore Software
    http://www.omnicore.com
     
    Hans Kratz, Apr 8, 2004
    #10
  11. Jesper Nordenberg

    Roedy Green Guest

    On Tue, 06 Apr 2004 08:10:29 +0200, Hans Kratz <>
    wrote or quoted :

    >What kind of "type change" are you referring to?


    If you changed the name of the type of a Dog collection to Canine, you
    have many Dog temporary variables in your program that need to change
    to Canine, but some of them, not related to the collection need to
    stay at Dog. There is no tight linking of the types of collections
    and the types of the temporaries used to access them.

    --
    Canadian Mind Products, Roedy Green.
    Coaching, problem solving, economical contract programming.
    See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
     
    Roedy Green, Apr 8, 2004
    #11
  12. Jesper Nordenberg

    Roedy Green Guest

    On Tue, 06 Apr 2004 08:10:29 +0200, Hans Kratz <>
    wrote or quoted :

    >Huh? Java contains all those strong compile-time checks to prevent just
    >that.


    With collections (at least in the 1.4 days) you have casts from object
    back to something. You don't find out till run time if you have
    erred. You can never exercise every line of code.


    --
    Canadian Mind Products, Roedy Green.
    Coaching, problem solving, economical contract programming.
    See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
     
    Roedy Green, Apr 8, 2004
    #12
  13. Jesper Nordenberg

    Roedy Green Guest

    On Thu, 08 Apr 2004 22:15:46 +0200, Hans Kratz <>
    wrote or quoted :

    >The omitted information
    >makes the code much harder to read/maintain especially if functional
    >language constructs such as map, foldl, etc. are heavily used.


    It makes it harder to read but easier to maintain since you have less
    to maintain.

    In a SCID situation, you could declare a variable as LIKE something
    else, e.g. like the type of a collection, but it would display as what
    it actually was. The LIKE is really a note to the scid to
    automatically change the type of this variable if the base variable's
    type were changed.

    Then you get he benefit of ease of reading and ease of maintenance.

    --
    Canadian Mind Products, Roedy Green.
    Coaching, problem solving, economical contract programming.
    See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
     
    Roedy Green, Apr 8, 2004
    #13
  14. Jesper Nordenberg

    Neal Gafter Guest

    Daniel Sjöblom wrote:
    >>> True, the gains of automatically inferred types of local variables
    >>> would not be substantial. The real gain would be a more powerful type
    >>> system for generic classes and methods. The current Java generics
    >>> suggestion is not very powerful and has a lot of annoying properties.

    >>
    >>
    >>
    >> Can you please be more specific?

    >
    >
    > Type erasure. Prevents a lot of perfectly sensible generic code. No
    > generic arrays. No primitive template instantiations. No generic methods
    > like (sorry for the C++ syntax, I don't remember the java syntax off-hand):
    >
    > template <typename Sequence>
    > char charAt(Sequence s, int index)
    > {
    > return s.charAt(index);
    > }
    >
    > (This would have been useful pre 1.4 since you can't extend String nor
    > StringBuffer.)
    >
    > But this was part of the design constraints, I understand. I.e. no
    > breaking of backwards compatibility. So in that respect, I think the
    > generics are rather nice.


    I haven't run into a situation in which erasure actually constrained the
    compile-time programming model in any practical sense. Instead of generic
    arrays you have generic collections. We do have generic methods, though for the
    example you suggest they're not needed. The following is perfectly legal in
    Java 1.5, and works with String, StringBuffer, and many other classes, and
    doesn't require generics:

    public static char charAt(java.lang.CharSequence s, int index) {
    return s.charAt(index);
    }

    I still don't see the point of your concerns.

    -Neal
     
    Neal Gafter, Apr 9, 2004
    #14
  15. Jesper Nordenberg

    Phillip Lord Guest

    >>>>> "Hans" == Hans Kratz <> writes:

    Hans> Phillip Lord wrote: When using the advanced type inference
    Hans> mechanism in Standard ML I had to constantly ask myself if the
    Hans> result of this or that expression is now a list of tuples of
    Hans> lists or a tuple of lists of lists. ;-)
    >> This I don't understand. I have this problem when I write lisp,
    >> but


    >> with SML it should tell you whether its a list of tuples of
    >> lists...


    Hans> If the developer makes heavy use of type inference he omits
    Hans> type declarations for local variables, return types and
    Hans> parameters of functions (just as in your factorial
    Hans> example). The omitted information makes the code much harder
    Hans> to read/maintain especially if functional language constructs
    Hans> such as map, foldl, etc. are heavily used.

    Okay I understand your point now.

    As the system could always tell you what the type is, to some extent
    this is a question of tooling. Ideally you should be able to switch
    the display on or off. But I still think that advantage of not
    requiring the programmer to write it is good.

    Phil
     
    Phillip Lord, Apr 9, 2004
    #15
  16. Jesper Nordenberg

    Chris Uppal Guest

    Daniel Sjöblom wrote:

    > [...] No primitive template instantiations. No generic methods
    > like (sorry for the C++ syntax, I don't remember the java syntax
    > off-hand):
    >
    > template <typename Sequence>
    > char charAt(Sequence s, int index)
    > {
    > return s.charAt(index);
    > }
    >


    If I'm not misunderstanding your intent, you /can/ do that kind of thing:

    ======================
    import java.util.List;

    public class Test
    {
    public static <E> E
    nth(List<E> list, int i)
    {
    return list.get(i);
    }
    }
    ======================

    Primitive types are a major disapointment, though*.

    If it helps, don't confuse Java's generics with C++'s templates -- they are
    different beasts. In the same sense that C++ templates are macros dressed up
    in fancy clothes, Java's generics are casts in a short skirt and high heels.

    -- chris

    [*] This sentence can be understood in two way -- I mean both of them ;-)
     
    Chris Uppal, Apr 9, 2004
    #16
  17. Jesper Nordenberg

    Kirk Woll Guest

    Neal Gafter <> wrote in message news:<>...

    > I haven't run into a situation in which erasure actually constrained the
    > compile-time programming model in any practical sense. Instead of generic
    > arrays you have generic collections. We do have generic methods, though for the
    > example you suggest they're not needed. The following is perfectly legal in
    > Java 1.5, and works with String, StringBuffer, and many other classes, and
    > doesn't require generics:
    >
    > public static char charAt(java.lang.CharSequence s, int index) {
    > return s.charAt(index);
    > }
    >
    > I still don't see the point of your concerns.
    >
    > -Neal


    I find type erasure causes generic code to become very unintuitive.
    Take the class:

    class A<T> {
    HashMap map = new HashMap();

    T getElement(String id) {
    Object o = map.get(id);

    // Not allowed; generates a compile-time error !!! {
    if (o instanceof T)
    return (T)o;
    else
    return null;
    // }

    // Not allowed; doesn't do anything {
    try {
    return (T)o;
    } catch (ClassCastException e) {
    return null;
    }
    // }
    }
    }

    Assume the hash map can have any type of object inside. Given that T
    is supposed to (in theory if not practice) represent the type of the
    return method in this example, it's confounding at first and
    frustrating still, to find it is impossible to create a method of this
    sort that will be guaranteed not to throw a ClassCastException on the
    caller of this method.
     
    Kirk Woll, Apr 9, 2004
    #17
  18. Jesper Nordenberg

    Neal Gafter Guest

    Kirk Woll wrote:
    > Assume the hash map can have any type of object inside. Given that T
    > is supposed to (in theory if not practice) represent the type of the
    > return method in this example, it's confounding at first and
    > frustrating still, to find it is impossible to create a method of this
    > sort that will be guaranteed not to throw a ClassCastException on the
    > caller of this method.


    See Collections.checked* methods to see how to do this.
     
    Neal Gafter, Apr 10, 2004
    #18
  19. Neal Gafter wrote:
    > Daniel Sjöblom wrote:
    >
    >>>> True, the gains of automatically inferred types of local variables
    >>>> would not be substantial. The real gain would be a more powerful type
    >>>> system for generic classes and methods. The current Java generics
    >>>> suggestion is not very powerful and has a lot of annoying properties.
    >>>


    (I just want to clarify. I din't write the above. Maybe the OP has
    something more to add.)

    >>> Can you please be more specific?

    >>
    >>
    >>
    >> Type erasure. Prevents a lot of perfectly sensible generic code. No
    >> generic arrays. No primitive template instantiations. No generic
    >> methods like (sorry for the C++ syntax, I don't remember the java
    >> syntax off-hand):
    >>
    >> template <typename Sequence>
    >> char charAt(Sequence s, int index)
    >> {
    >> return s.charAt(index);
    >> }
    >>
    >> (This would have been useful pre 1.4 since you can't extend String nor
    >> StringBuffer.)
    >>
    >> But this was part of the design constraints, I understand. I.e. no
    >> breaking of backwards compatibility. So in that respect, I think the
    >> generics are rather nice.

    >
    >
    > I haven't run into a situation in which erasure actually constrained the
    > compile-time programming model in any practical sense. Instead of
    > generic arrays you have generic collections.


    It is mostly a performance issue. Autoboxed primitives are also slower
    (and require more memory.)

    > We do have generic
    > methods, though for the example you suggest they're not needed.


    No, not anymore, but see below.

    > The
    > following is perfectly legal in Java 1.5, and works with String,
    > StringBuffer, and many other classes, and doesn't require generics:
    >
    > public static char charAt(java.lang.CharSequence s, int index) {
    > return s.charAt(index);
    > }
    >


    But this is not equivalent to my method. That only works on
    CharSequences (which wasn't introduced until 1.4), my example works on
    any class that has a char charAt(int) method. As it is now, we have to
    wait until you guys decide that String or StringBuffer (or any other
    classes for that matter) should implement this or that interface until
    we can use them generically.

    And just creating more and more interfaces to deal with this is not
    really an alternative, as it is often redundant, and it requires
    changing old code, which sometimes cannot be done.

    > I still don't see the point of your concerns.


    Besides the above, java generics also lack many of the aspects of C++
    template metaprogramming, like (partial) template specialization and
    constant value templates. C++ templates are actually Turing complete.
    But this is not something I miss, really.

    But how about templates as template arguments:

    template <template<class> class T, typename T2>
    class SomeClass
    {
    T<T2> templateOfTemplateMember;
    };

    This can be useful at times. But as I said, I quite like the generics,
    but that doesn't mean they are perfect.

    > -Neal
    >

    --
    Daniel Sjöblom
    Remove _NOSPAM to reply by mail
     
    =?ISO-8859-1?Q?Daniel_Sj=F6blom?=, Apr 10, 2004
    #19
  20. Jesper Nordenberg

    Kirk Woll Guest

    Neal Gafter <> wrote in message news:<>...
    > Kirk Woll wrote:
    > > Assume the hash map can have any type of object inside. Given that T
    > > is supposed to (in theory if not practice) represent the type of the
    > > return method in this example, it's confounding at first and
    > > frustrating still, to find it is impossible to create a method of this
    > > sort that will be guaranteed not to throw a ClassCastException on the
    > > caller of this method.

    >
    > See Collections.checked* methods to see how to do this.


    Thanks for the response, Neal, but I'm aware it's possible to
    literally pass the Class type that you are trying to check for and use
    its isInstance method. But the point I was trying to make is
    intuitively, this information should already be present because of the
    generic type (and would be present without type erasure) specified on
    the class.

    The example you sited is a static method that wraps an already typed
    collection (type E) but still requires you to supply the class type.
    Thus, for a collection of strings, you would have:

    Collections.checkedCollection(new ArrayList<String>(), String.class);

    What I find unannoying and unintuitive is the need to supply
    "String.class" when the type of the collection is already supplied via
    "new ArrayList<String>()". I guess ultimately this is just an
    inconvenience, but seeing all this redundant code really clashes with
    the whole spirit of generics.

    Kirk
     
    Kirk Woll, Apr 11, 2004
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Tony Morris
    Replies:
    1
    Views:
    2,711
    =?ISO-8859-1?Q?Daniel_Sj=F6blom?=
    Apr 6, 2004
  2. Michal M
    Replies:
    7
    Views:
    826
    Andrew Thompson
    Aug 2, 2005
  3. Replies:
    3
    Views:
    5,234
    Bjorn Abelli
    Mar 30, 2006
  4. manzur
    Replies:
    5
    Views:
    520
    Chris Uppal
    Nov 9, 2006
  5. Replies:
    0
    Views:
    742
Loading...

Share This Page