What should Map iteration do?

Jason Orendorff jason.orendorff at gmail.com
Mon Feb 6 11:09:14 PST 2012

On Thu, Feb 2, 2012 at 1:35 PM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
>  for (v of arr)  // each element of an Array
>  for (v of set)  // each value in a Set
>  for (k of map)  // each key in a Map, following Python
> Smalltalk defaults maps to the value and Ruby to the key/value pair.  Java
> seems to have no default, you have to explicitly select keys, values or
> items.

Trying to revive this thread...

In C#, a Dictionary<K, V> is an ICollection<KeyValuePair<K, V>>. So,
items by default.

Note also that in Ruby it's not as simple as "defaulting to" key/value
pairs. Actually if you write code like
    obj.each { |v| puts v }
which is what you'd write for walking an Array, that doesn't work with
a Hash. Array#each expects a block with one argument, but Hash#each
expects a block with two arguments. (If you call Hash#each without any
block argument, you do get an enumerator that yields pairs, but that
is not the usual thing to do in Ruby. That is, typical generic
collection algorithms in Ruby do not reach Hashes.)

> The rationale for Smalltalk, is that most generic algorithms that want
> iterate over arbietrary collations are interested in values.  After all,
> some collections don't have keys.

Until Python 2.2, iterating over a dictionary was an error. Python
2.1.3 was the last version where you had to specify keys/values/items,
and in that version of the Python standard library, the numbers are
like this:

    for.* in.*keys():    114 hits, 86 distinct
    for.* in.*items():   110 hits, 85 distinct
    for.* in.*values():   19 hits, 16 distinct

This fits with my experience. When each value is a serious object from
which you can easily get or compute the key, values() is exactly what
you want. Otherwise values() is unhelpful, usually.

I want to do the same experiment on a large body of Java code. Since
Java does not have a default, the results should show what's most
useful (in Java) in practice. I can use Apache commons code, for
example. I'll try to find time this week.

I think the "generic algorithms" perspective should argue for items()
iteration being the default. At issue is what a function like map or
filter should do with a Map; it seems most general to expose all the
information in the Map by default. However: passing a Map to a generic
algorithm is only one use case for Map iteration, and not the most
common in my experience.


More information about the es-discuss mailing list