API's that Suck

November 29, 2009

Functional Purity, IEnumerators, and IEnumerables

Filed under: Uncategorized — Grauenwolf @ 3:05 am

I’ve been playing with Code Contracts and something about purity keeps coming up. In terms of side effects, what exactly is the guarantee offered by IEnumerable and IEnumerator?

IEnumerators are, by the very nature, impure objects.  Being more like the index variable in a loop than real objects, they should be used once and discarded. ILists, on the other hand, are generally durable objects. You can iterate through them as often as you like with no ill effects. So our first two rules are clear. Any function that takes an IEnumerator is impure while any that takes an IList is, assuming read-only access, pure. IEnumerable is the tricky case.  There is nothing in the contract that says GetEnumerator has to be free from side-effects, but off hand I can’t think of anything where it would be a problem.

This is important for API design because it changes what signatures need to be exposed. If you can’t trust GetEnumerator to be pure, then any classes that accept IEnumerator should also accept arguments of type IList.

Advertisements

3 Comments »

  1. Could you elaborate, what guarantees the purity and durability of IList?
    Can’t IList.Item(int) and IList.GetEnumerator() have same side effects as IEnumerators and IEnumerables?

    B.B.

    Comment by bbzippo — December 5, 2009 @ 12:58 am

    • In order to read all the information in an IEnumerator, you have to mutate the enumerator by calling MoveNext.
      When reading all the information in an IList, there is a semantic assumption that you never mutate the list itself. You may mutate an index variable or a enumerator, but that’s ok because they are not visible outside your function.
      I was wondering if IEnumerators, like IList, had the same implied guarantees and if those guarantees would become explicit with Code Contracts. As I haven’t been able to find a IEnumerator that is mutated when an Enumerator is used against it, I think it is a safe assumption.

      Comment by grauenwolf — December 5, 2009 @ 1:39 am

  2. I see. I know little about Code Contracts. Let me describe my view on the subject. Enumerator mutation is in many cases the desired effect. MoveNext will typically trigger state change on a whole bunch of objects in order to lazy-evaluate the result. Sometimes the caller doesn’t care about this, and sometimes it does. E.g. because of speed considerations, responsibility for exception handling, state integrity concerns, etc. If the caller wants to stay away from all of that, it should rather accept Lists and not enumerators.
    What do you think?

    Comment by bbzippo — December 5, 2009 @ 8:13 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: