Generics - Is this possible?

Discussion in 'Java' started by lstephen, Apr 15, 2008.

  1. lstephen

    lstephen Guest

    Hi,

    I'm looking at the signature for something like a 'map' function.

    For List it may be something like:

    List<B> map(List<A> a, UnaryFunction<A, B> f)

    But, I want I'd rather it not be List specific, so I was after
    something like:

    T<B> map(T<A> a UnaryFunction<A, B> f)

    But, the compiler doesn't like this ;)

    Any ideas on how or whether this is possible?

    Thanks,
    Levi
     
    lstephen, Apr 15, 2008
    #1
    1. Advertising

  2. Lew <> wrote:
    > lstephen wrote:
    >> For List it may be something like:
    >> List<B> map(List<A> a, UnaryFunction<A, B> f)
    >> But, I want I'd rather it not be List specific, so I was after
    >> something like:
    >> T<B> map(T<A> a, UnaryFunction<A, B> f)


    If you won't specify anything about T itself, you
    wouldn't be able to do anything at all with it.
    Inside your "map" method, T would be like Object,
    and that has no method to retrieve any "A" from it :)

    > public static <A, B>
    > Collection <B> xform( Collection <A> a, UnaryFunction <A, B> f )
    > (untried, untested, uncompiled, one of several solutions [...])


    Another problem is, that xform has the "burden" of picking some
    implementation of a Collection, an instance of which it then
    returns, filled with all the "B"-objects.

    > If you have a class called 'UnaryFunction', shouldn't it overload its "unary
    > function" method with one that takes a Collection? Having a "friend" method
    > like that shown breaks encapsulation.


    That would just shift the problems from xform to UnaryFunction's
    overloaded(or just additional) method. If "UnaryFunction" was
    an interface, it would mean that any implementation would also
    need to care for an implementation of the Collection-handling
    method.
    Imho "map" or "xform" are rather the type of methods that
    would belong into a "Collections"-like toolkit class.
     
    Andreas Leitgeb, Apr 15, 2008
    #2
    1. Advertising

  3. lstephen

    Jan Thomä Guest

    On Tue, 15 Apr 2008 10:20:11 -0400 Larry A Barowski wrote:
    > If that were possible, java.util.Collections would not
    > need the methods synchronizedList, synchronizedSet,
    > and synchronizedSortedSet. It would only need
    > synchronizedCollection.


    On a side note, something like this is possible in C#:


    // function that creates a T
    public T create<T>() {
    return new T();
    }

    and you can call this like: Foo foo = create<Foo>(); Doesn't work for java
    though, but nicely shows the different approach in C#...
     
    Jan Thomä, Apr 15, 2008
    #3
  4. lstephen

    Guest

    On Apr 15, 2:34 am, lstephen <> wrote:
    > Hi,
    >
    > I'm looking at the signature for something like a 'map' function.
    >
    > For List it may be something like:
    >
    > List<B> map(List<A> a, UnaryFunction<A, B> f)
    >
    > But, I want I'd rather it not be List specific, so I was after
    > something like:
    >
    > T<B> map(T<A> a UnaryFunction<A, B> f)
    >
    > But, the compiler doesn't like this ;)
    >
    > Any ideas on how or whether this is possible?


    I've implemented a functional library that addresses this issue. I
    just use the Iterable<T> type unless the operation specifically
    depends on list ordering. Here's a skeleton of my class declarations
    adapted to your notation. Note, my implementation uses lazy
    evaluation so you can do things like sum up an infinite list.

    For example, I can create a Range class that takes a starting and
    finishing value and implements Iterable<Integer>. I can write code
    like this:

    Range r = new Range(0, Integer.MAX_VALUE);
    UnaryFunction sqr = new Square();

    Iterable<Integer> squares = map( sqr, r );

    for ( Integer x : squares )
    {
    // do something
    if ( x > 100 )
    break;
    }


    Here is the code outline:

    public class UnaryFunction<R, T> {
    public R eval( T arg ) { ... }
    }

    public static <R, T> Iterable<R> map( final UnaryFunction<R, T> f,
    final Iterable<? extends T> list )
    {
    return new Iterable<R>() {
    public Iterator<R> iterator() {
    return map_iterator( f, list.iterator() );
    }
    }
    }

    private static <R, T> Iterator<R> map_iterator( final UnaryFunction<R,
    T> f, final Iterator<? extends T> iterator )
    {
    return new Iterator<R>()
    {
    public boolean hasNext() {
    return list.hasNext();
    }
    public R next() {
    return f.eval( list.next() );
    }
    public void remove() {
    throw new UnsupportedOperationException();
    }
    };
    }
     
    , Apr 15, 2008
    #4
  5. <> wrote:
    > public static <R, T> Iterable<R> map(
    > final UnaryFunction<R, T> f,
    > final Iterable<? extends T> list )


    I'm just curious, why you chose to return an
    Iterable, rather than an Iterator.

    I haven't found any standard class that would
    take an Iterable as argument, so the only thing
    to do with the returnvalue is to obtain an
    Iterator... did I miss something?

    Even if you obtain an Iterator more than once,
    each such Iterator will just recalculate the
    same values.
     
    Andreas Leitgeb, Apr 15, 2008
    #5
  6. Andreas Leitgeb wrote:
    ....
    > I haven't found any standard class that would
    > take an Iterable as argument, so the only thing
    > to do with the returnvalue is to obtain an
    > Iterator... did I miss something?

    ....

    There is one thing you can do with an Iterable but not an Iterator - use
    it in an enhanced for-loop.

    Patricia
     
    Patricia Shanahan, Apr 15, 2008
    #6
  7. lstephen

    Roedy Green Guest

    On Tue, 15 Apr 2008 00:34:07 -0700 (PDT), lstephen
    <> wrote, quoted or indirectly quoted someone
    who said :

    >But, I want I'd rather it not be List specific, so I was after
    >something like:


    What methods are you planning to use inside your map method? If it is
    to be used on List, it must either be the List, Collection or Iterable
    methods. So you must pass something of type of one of those three.

    Java is a strongly typed language!
    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Apr 15, 2008
    #7
  8. Patricia Shanahan <> wrote:
    > Andreas Leitgeb wrote:
    >> ..., so the only thing
    >> to do with the returnvalue is to obtain an
    >> Iterator... did I miss something?

    > There is one thing you can do with an Iterable but not an Iterator - use
    > it in an enhanced for-loop.


    Heck, I really missed *something* :-}

    Thanks also to Peter Duniho.
     
    Andreas Leitgeb, Apr 15, 2008
    #8
  9. Andreas Leitgeb wrote:
    > Patricia Shanahan <> wrote:
    >> Andreas Leitgeb wrote:
    >>> ..., so the only thing
    >>> to do with the returnvalue is to obtain an
    >>> Iterator... did I miss something?

    >> There is one thing you can do with an Iterable but not an Iterator - use
    >> it in an enhanced for-loop.

    >
    > Heck, I really missed *something* :-}
    >
    > Thanks also to Peter Duniho.


    Incidentally, does anyone understand *why* it has to be an Iterable, not
    an Iterator? Of course, an Iterator based for loop would only process
    the elements from the Iterator's current position on.

    Patricia
     
    Patricia Shanahan, Apr 15, 2008
    #9
  10. lstephen

    lstephen Guest

    On Apr 16, 5:34 am, Roedy Green <>
    wrote:
    > On Tue, 15 Apr 2008 00:34:07 -0700 (PDT), lstephen
    > <> wrote, quoted or indirectly quoted someone
    > who said :
    >
    > >But, I want I'd rather it not be List specific, so I was after
    > >something like:

    >
    > What methods are you planning to use inside your map method? If it is
    > to be used on List, it must either be the List, Collection or Iterable
    > methods. So you must pass something of type of one of those three.


    Sorry, I wasn't clear that map would have more than one
    implementation. I'm enjoy playing around with translating concepts
    from one language to others. In this case it's the Functor type class
    from Haskell. So map would be an abstract method of a Functor class.
    Then I could create ListFunctor, SetFunctor, MapFuctor etc. Then to
    take more from Haskell MaybeFunctor, EitherFunctor etc.
    So there is no practical problem to solve, just experimenting.

    >
    > Java is a strongly typed language!


    Yep. I'm trying to express that if you pass in a List<A> you would get
    back a List<B>, pass in Set<A> you get back Set<B>. i.e., the type of
    collection you pass in, is what you get back.


    > --
    >
    > Roedy Green Canadian Mind Products
    > The Java Glossaryhttp://mindprod.com


    Thanks,
    Levi
     
    lstephen, Apr 16, 2008
    #10
  11. lstephen

    lstephen Guest

    On Apr 16, 1:53 am, wrote:
    >
    >
    > I've implemented a functional library that addresses this issue. I
    > just use the Iterable<T> type unless the operation specifically
    > depends on list ordering.


    Thanks for the example. I was experimenting with functional like
    concepts, but I wanted to be more specific that Iterable, i.e., if you
    pass in List<A> you get back List<B>, if you pass in a Set, you get
    back a Set etc. Also I was hoping this would allow map to be used on
    non collection types (e.g., something like Haskell's Maybe or Either
    but translated to Java.)

    As I mentioned elsewhere there is no practical reason for me doing
    this, just experimenting :)

    Thanks,
    Levi
     
    lstephen, Apr 16, 2008
    #11
  12. lstephen

    lstephen Guest

    On Apr 15, 10:49 pm, Lew <> wrote:
    > lstephen wrote:
    > > Hi,

    >
    > > I'm looking at the signature for something like a 'map' function.

    >
    > 'map' is a somewhat unfortunate variable name, since you aren't actually
    > associating it with the wildly popular 'Map' type.
    >
    > > For List it may be something like:

    >
    > > List<B> map(List<A> a, UnaryFunction<A, B> f)

    >
    > > But, I want I'd rather it not be List specific, so I was after
    > > something like:

    >
    > > T<B> map(T<A> a UnaryFunction<A, B> f)

    >
    > > But, the compiler doesn't like this ;)

    >
    > > Any ideas on how or whether this is possible?

    >
    > What you want to accomplish is possible, what you're trying to say isn't.
    > You're trying to indicate a type parameter that takes a type parameter; that
    > doesn't exist.


    By doesn't exist, do you mean not possible in Java?

    > Type parameters exist to restrict the range of acceptable
    > types; what you wrote, 'T<A>', is equivalent to merely 'T'.
    >
    > What is the restriction that you actually want to place on T? Do you want it
    > to be a Collection?


    The restriction I want to place on T is that it's a generic class that
    takes one type parameter.

    >
    > public static <A, B>
    > Collection <B> xform( Collection <A> a, UnaryFunction <A, B> f )
    >
    > (untried, untested, uncompiled, one of several solutions that differ subtly in
    > semantics)


    Yep, I could definately cover the most common case by using Iterable
    or Collection, but I was trying to see how general I could make this.
    >
    > If you have a class called 'UnaryFunction', shouldn't it overload its "unary
    > function" method with one that takes a Collection? Having a "friend" method
    > like that shown breaks encapsulation.


    UnaryFunction wouldn't be passed a collection, it would be passed an
    element form a collection - it wouldn't even know the element was part
    of a collection.

    >
    > --
    > Lew
     
    lstephen, Apr 16, 2008
    #12
  13. lstephen

    lstephen Guest

    On Apr 15, 11:20 pm, "Larry A Barowski"
    <ThisisLarrybarAtEngDotAuburnDotLearninginstitution> wrote:
    > "lstephen" <> wrote in message
    >
    > news:...
    >
    >
    >
    > > Hi,

    >
    > > I'm looking at the signature for something like a 'map' function.

    >
    > > For List it may be something like:

    >
    > > List<B> map(List<A> a, UnaryFunction<A, B> f)

    >
    > > But, I want I'd rather it not be List specific, so I was after
    > > something like:

    >
    > > T<B> map(T<A> a UnaryFunction<A, B> f)

    >
    > > But, the compiler doesn't like this ;)

    >
    > > Any ideas on how or whether this is possible?

    >
    > If that were possible, java.util.Collections would not
    > need the methods synchronizedList, synchronizedSet,
    > and synchronizedSortedSet. It would only need
    > synchronizedCollection.


    Good point. I think this is a strong indication that the answer is no.

    Thanks,
    Levi
     
    lstephen, Apr 16, 2008
    #13
  14. Peter Duniho wrote:
    > On Tue, 15 Apr 2008 15:19:17 -0700, Patricia Shanahan <> wrote:
    >
    >> Incidentally, does anyone understand *why* it has to be an Iterable, not
    >> an Iterator? Of course, an Iterator based for loop would only process
    >> the elements from the Iterator's current position on.

    >
    > Only the language designers could tell you the actual reason why. But I
    > would agree with anyone who felt it wise to not allow user code access
    > to the actual iterator being used for the loop. The potential for
    > adding bugs seems to me to outweigh any potential convenience. It keeps
    > the semantics of the for:)) syntax nice, simple, and easy-to-predict.


    I certainly agree that not allowing user code access to the actual
    iterator would be desirable, if it were possible. It isn't. The
    following, horrible, program prints "1", then "3", then gets a
    java.util.NoSuchElementException.

    import java.util.Arrays;
    import java.util.Iterator;
    import java.util.List;

    public class WildFor {
    public static void main(String[] args) {
    List<Integer> myList = Arrays.asList(1, 2, 3, 4, 5);
    RememberingIterable<Integer> myIterable =
    new RememberingIterable<Integer>(myList);
    for (Integer i : myIterable) {
    myIterable.getLastIterator().next();
    System.out.println(i);
    }
    }

    static class RememberingIterable<T> implements
    Iterable<T> {
    private Iterable<T> baseIterable;

    private Iterator<T> lastIterator;

    public RememberingIterable(Iterable<T> iterable) {
    baseIterable = iterable;
    }

    public Iterator<T> iterator() {
    lastIterator = baseIterable.iterator();
    return lastIterator;
    }

    public Iterator<T> getLastIterator() {
    return lastIterator;
    }
    }

    }
     
    Patricia Shanahan, Apr 16, 2008
    #14
  15. Peter Duniho wrote:
    > On Tue, 15 Apr 2008 16:41:55 -0700, Patricia Shanahan <> wrote:
    >
    >> I certainly agree that not allowing user code access to the actual
    >> iterator would be desirable, if it were possible. It isn't.

    >
    > But it would be if Java supported using an Iterator in the for() statement.
    >
    >> The
    >> following, horrible, program prints "1", then "3", then gets a
    >> java.util.NoSuchElementException.

    >
    > Right. But if you can provide an actual iterator in the for()
    > statement, then the code has access to the iterator implicitly. It
    > wouldn't be nearly so much work to reproduce the example of bad usage
    > you provided if Java allowed an Iterator instead of an Iterable
    > implementation in the for() statement. Your example would instead look
    > like this:

    ....

    The point is that not allowing Iterator does not prevent access to it,
    just makes it a bit harder. Meanwhile, it also makes legitimate uses harder.

    Patricia
     
    Patricia Shanahan, Apr 16, 2008
    #15
  16. lstephen

    thufir Guest

    On Tue, 15 Apr 2008 00:34:07 -0700, lstephen wrote:


    > For List it may be something like:
    >
    > List<B> map(List<A> a, UnaryFunction<A, B> f)



    would you flesh this example out?



    thanks,

    Thufir
     
    thufir, Apr 16, 2008
    #16
  17. Re: Generics - Is this possible? [OT: naming conventions]

    schreef:
    > On Apr 15, 2:34 am, lstephen <> wrote:
    >> <snip request for map>

    >
    > I've implemented a functional library that addresses this issue. I
    > just use the Iterable<T> type unless the operation specifically
    > depends on list ordering. Here's a skeleton of my class declarations
    > adapted to your notation. Note, my implementation uses lazy
    > evaluation so you can do things like sum up an infinite list.


    Very nice, but…

    > private static <R, T> Iterator<R> map_iterator( final UnaryFunction<R,


    Please, please don’t. It hurts me so much to see such beautiful code
    and then not following naming conventions.

    Sorry, had to get this off my heart.

    H.
    --
    Hendrik Maryns
    http://tcl.sfs.uni-tuebingen.de/~hendrik/
    ==================
    http://aouw.org
    Ask smart questions, get good answers:
    http://www.catb.org/~esr/faqs/smart-questions.html


    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v2.0.4-svn0 (GNU/Linux)
    Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

    iD8DBQFIBcy1e+7xMGD3itQRAn38AJwNeBqOsEV551I1HIA+ij+8PronVACfbA4T
    ciBWXRMu15rCQCNiZxiolQ4=
    =ql66
    -----END PGP SIGNATURE-----
     
    Hendrik Maryns, Apr 16, 2008
    #17
  18. lstephen

    lstephen Guest

    On Apr 16, 6:30 pm, thufir <> wrote:
    > On Tue, 15 Apr 2008 00:34:07 -0700, lstephen wrote:
    > > For List it may be something like:

    >
    > > List<B> map(List<A> a, UnaryFunction<A, B> f)

    >
    > would you flesh this example out?


    It would probably be something like (without compiling or testing it):

    public interface UnaryFunction<A, B> {
    B apply(A a);
    }

    public List<B> map(List<A> as, UnaryFunction<A, B> f) {
    List<B> bs = new ArrayList<B>();
    for (A a : as) {
    bs.add(f.apply(a));
    }
    return bs;
    }


    >
    > thanks,
    >
    > Thufir


    Levi
     
    lstephen, Apr 17, 2008
    #18
  19. Re: Generics - Is this possible? [OT: naming conventions]

    Peter Duniho <> wrote:
    > On Wed, 16 Apr 2008 17:44:53 -0700, Lew <> wrote:
    >> There is a standard naming convention in Java, published by Sun in 1999.
    >> Ignore it at your peril.

    > Peril? Something bad will happen to me? What? What bad thing will
    > happen?
    > And I mean, other than Java zealots harrassing me about my naming.


    Zealots are not just here in c.l.j.p, but you may also meet some
    in real world - e.g. those who review your code and rate it poorly.
    The zealots *here* rather help you be prepared for the others :)
     
    Andreas Leitgeb, Apr 17, 2008
    #19
  20. Re: Generics - Is this possible? [OT: naming conventions]

    Peter Duniho wrote:
    > On Wed, 16 Apr 2008 17:44:53 -0700, Lew <> wrote:
    >> Forget it, Pete. Java is a community, not just a language, and the
    >> community has standards.

    >
    > Java _is_ "just a language". There may also be a "Java community", but
    > the language itself doesn't enforce any particular naming convention and
    > there's no requirement to comply with "community standards" in order to
    > be a successful Java programmer.
    >


    This is true but misses the point that if you wish to enlist the help of
    the community in fixing some problem you are having with your Java
    source code, you'll get a better response from the community if your
    source code follows the community conventions that make it easier for
    community members to follow.

    Using underscore connected words instead of camelCase isn't much of a
    hindrance, it's when people use wild indentation or initial upper-case
    for variables that my reading speed tends to slow down dramatically. I
    tend to lose motivation a bit when I think the author is wilfully making
    it harder for helpers to help.

    bI awrl menes beeYidIosYnCRAT.IC wern ryEtAng koid fore eeyore Owen
    prusell Owen Lee.

    When communicating with others, I think it helps to follow the conventions.

    Just my EUR 0.00000002 worth.

    --
    RGB
     
    RedGrittyBrick, Apr 17, 2008
    #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. Juergen Berchtel
    Replies:
    1
    Views:
    6,004
    John C. Bollinger
    May 20, 2005
  2. Markus
    Replies:
    1
    Views:
    472
    Markus
    Nov 22, 2005
  3. Joost Kraaijeveld
    Replies:
    3
    Views:
    747
    Joost Kraaijeveld
    Nov 30, 2005
  4. Replies:
    4
    Views:
    292
    Kenny McCormack
    Feb 21, 2006
  5. Soul
    Replies:
    0
    Views:
    524
Loading...

Share This Page