Style Question: Is returning Iterable too abstract?

7 views
Skip to first unread message

Eric Winter

unread,
Jun 15, 2009, 10:50:35 AM6/15/09
to Google Collections Library - users list
I love the Google Collections API. I do find, however, that it seems
to encourage returning Iterable as opposed to a List (there is no
Lists.transform/filter or Sets.transform/filter methods).

In many cases that seems appropriate as I usually all I really do with
the returned object is iterate over it using the foreach loop but on
occasion I find later that I need to do something List specific at
which point I just use ImmutableList.copyOf(Iterable) or
Lists.newArrayList(Iterable) but that seems wonky. Unfortunately, GCA
and Java verbage makes it look ugly to have:

Iterable<Foo,Bar> temp = Iterables.transform(myList, new Function<Foo,
Bar>(){...});
return Lists.newArrayList(temp);

Does anyone have an opinion? Is returning Iterable a too abstract?
What is the right level of abstraction? Iterable, Collection, List,
ArrayList is the spectrum. I am used to using List(or Set) level but
I can see more abstract working typically.

Robert Konigsberg

unread,
Jun 15, 2009, 11:14:07 AM6/15/09
to Eric Winter, Google Collections Library - users list
I'd say it's something to evaluate on a case-by-case basis. But I
think there's another question hidden inside your first question,
which is, "Should I let the types used internally in my operations
drive the return value of the public API?" And I think the answer
there is "Absolutely not."

However, in this very particular example you give, I would not return
List, but ImmutableList, and instead of using List.newArrayList, I'd
return ImmutableList.of.

As in:

public ImmutableList<Bar> mymethod(List<Foo> myList) {
Iterable<Bar> temp = Iterables.transform(myList, new Function<Foo,
Bar>(){...});
return ImmutableList.copyOf(temp);
}

> >
>



--
Stop the H8.

Robert Konigsberg
konig...@gmail.com

Jim Andreou

unread,
Jun 15, 2009, 11:27:29 AM6/15/09
to Robert Konigsberg, Eric Winter, Google Collections Library - users list


2009/6/15 Robert Konigsberg <konig...@gmail.com>


I'd say it's something to evaluate on a case-by-case basis. But I
think there's another question hidden inside your first question,
which is, "Should I let the types used internally in my operations
drive the return value of the public API?" And I think the answer
there is "Absolutely not."

I rather disagree there. My first consideration is maintaining optimal performance. Sometimes returning a more abstract type means wasted computation (for example, returning Map instead of Sorted/NavigableMap, or returning Iterable instead of Collection/Set with a fast contains()). If it doesn't harm, then by all means go for the more abstract. But the desicion is made only in that order. (Building an API makes the "If it doesn't harm" question more tricky, since one might perhaps want to be conservative about what could harm or not, unless he knows all his users and their use cases beforehand :)) 

Dimitris

Robert Konigsberg

unread,
Jun 15, 2009, 11:31:52 AM6/15/09
to Jim Andreou, Eric Winter, Google Collections Library - users list
On Mon, Jun 15, 2009 at 11:27 AM, Jim Andreou<jim.a...@gmail.com> wrote:
>
>
> 2009/6/15 Robert Konigsberg <konig...@gmail.com>
>>
>> I'd say it's something to evaluate on a case-by-case basis. But I
>> think there's another question hidden inside your first question,
>> which is, "Should I let the types used internally in my operations
>> drive the return value of the public API?" And I think the answer
>> there is "Absolutely not."
>
> My first consideration is maintaining optimal performance.

You know, it's funny. I wondered whether I was going to mention the
typical "go for readability and optimize later" argument, and then
chose not to.

I agree to disagree. Maybe you and I write very different code, and
with that I stick to my first sentence: evaluate this on a case by
case basis. Still, don't let the internal data structure take control
of your design -- you're in control.

Jared Levy

unread,
Jun 19, 2009, 11:12:34 AM6/19/09
to Eric Winter, Google Collections Library - users list

Actually, the library includes the following methods:

Collections2.filter()
Collections2.transform()
Sets.filter()
Lists.transform()

There isn't a Sets.transform(), since the function could map two distinct elements into the same value, violating the Set contract.

A Lists.filter() method would return a list that lacks random access, since it would have to find the nth element that satisfies the filter. It seems better to omit a method that could inadvertently cause poor performance.

The library includes the filter and transform methods that make sense, except for SortedSet/Map methods that nobody has asked for.

Jared

Tim Harsch

unread,
Jun 20, 2009, 1:03:05 PM6/20/09
to Jared Levy, Eric Winter, Google Collections Library - users list
Should SortedSet/Map not include those methods because nobody has asked for them?  Or should they be there for completeness and for creating an intituitive API.  It may be later that those methods would begin getting wide adoptance and if they should be there for completeness sake, why not add them?  It seems, no one has asked is not a valid reason, especially if your users continue to grow...

Just some thoughts,
Tim

Jared Levy

unread,
Jun 21, 2009, 10:49:42 PM6/21/09
to Tim Harsch, Eric Winter, Google Collections Library - users list
Actually, I hadn't considered the SortedSet/Map methods before sending my earlier email.

Of course, it would take time to implement, test, and maintain any additional public methods. Also, the more public methods that are present, the more difficult it is for people to understand the library and find a particular method of interest. Before adding a new method, we should try to predict whether it would be used much, and user requests are one way of gauging that.

It is plausible to create versions of the following methods that accept and return a SortedSet or SortedMap:

Sets.filter()
Maps.filterEntries()
Maps.filterKeys()
Maps.filterValues()
Maps.transformValues()

If someone wants those methods, they can file an enhancement request.
Reply all
Reply to author
Forward
0 new messages