It's great that FW 3.5 defines a set of generic Action delegates to complement the Func delegates. The cherry on the cake would be a ForEach method in Enumerable:
public static void ForEach <TSource> (this IEnumerable<TSource> source, Action<TSource> action)
foreach (TSource element in source)
Then you could simply go:
Of course, this method is not hard to write for oneself
JoeFriday, November 09, 2007 2:12 AM
I don't believe functional-purist folks would dislike it that much. They'd argue about the name, but not the functionality. After all, this is just a single-use-case scenario of fold (also called reduce and accumulate). Actual purists will take issue with having any side effects from the call, but then, as pointed out, C# isn't a pure functional language in that sense.
List already has this ForEach method. Enumerable also has the Aggregate method, which is exactly the Fold method that functional developers would expect to have, and that could be used here. The only thing is Aggregate must return a value, and takes an extra "accumulator" value, making the usage not as obvious for most.
Currently, we have the triad:
filter = Where
map = Select
reduce = Aggregate
I think there should be a ForEach on Enumerable.Friday, November 09, 2007 3:05 PM
Actually, the specific discussion I witnessed did in fact hinge over functional purity. In an expression, there are frequently assumptions made about not having side-effects. Having ForEach is specifically inviting side-effects rather than just putting up with them.Friday, November 09, 2007 7:04 PM
Interesting, but I'd have to argue about that. There's lots you can do in a ForEach that wouldn't cause side effects (depending on your definition, as I've seen it argued that I/O does cause side effects, and no program can do without I/O). In fact, it's common to see fold used as a ForEach in many functional languages. So, even if I'd buy into the purity argument (which is strange, given that C# isn't a pure functional language), I don't think I'd buy into it being applied as a reason not to have ForEach.
Regardless, who cares what those folks think? C# isn't a functional language (at least not a pure functional language) and not having ForEach is more surprising to current C# developers than it would be for having it to folks who've used pure functional languages. It's too late, I believe, to do anything about it now. But I'd strongly argue for adding it with the next version.Friday, November 09, 2007 7:21 PM
I'll give you half a point there. Only half a point, because the dominant languages in .NET were, and are, non-functional. The .NET libraries are non-functional. Functional languages living in the .NET world are going to have to deal with this fact. So I don't see the fact that they exist really having any bearing on this decision.Friday, November 09, 2007 7:36 PM
I realize this is a very old thread; however, it is still relevant and in my mind there is still an outstanding question of why, o why, doesn't the framework define a ForEach extension for IEnumerable ?!? I have probably written my own IEnumerable ForEach extension about 15 different times for various unrelated projects. And here we are at .Net 4.0 and there still does not exist a framework-defined ForEach extension. Now, in the grand scheme of things, this is rather trivial; it's just one of those little things that would be nice to have and get rid of an unnecessary annoyance. As others have pointed out, C# is not about "functional purity" and I really don't think that's a good argument for not providing it...Thursday, June 10, 2010 1:04 PM