Ask a questionAsk a question
 

General DiscussionSuggestion - Enumerable.ForEach

  • Friday, November 09, 2007 2:12 AMJoe AlbahariMVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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)
                action (element);
        }

    Then you could simply go:

    myQuery.ForEach (Console.WriteLine);

    Of course, this method is not hard to write for oneself Smile

    Joe

All Replies

  • Friday, November 09, 2007 3:11 AMKeith Farmer Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    True.  However, some of the more functional-purist folks out there really dislike the idea of having Enumerable.ForEach.

     

    I'm sure the debate will continue... Smile

  • Friday, November 09, 2007 9:51 AMJoe AlbahariMVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    But C# 3.0 is not a "pure" functional language!  C# is a mixed-paradigm language - and that is arguably one of its strengths.


  • Friday, November 09, 2007 3:05 PMWilliam E. Kempf Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    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 7:04 PMKeith Farmer Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    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:21 PMWilliam E. Kempf Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    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:26 PMKeith Farmer Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    This has nothing to do with C#.  Enumerable's available from any .NET language that can call it, including (for example) F#.

     

     

  • Friday, November 09, 2007 7:36 PMWilliam E. Kempf Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    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.