Thanks to everybody who attended my session at DevWeek! I hope you liked it, I certainly had a lot of fun doing it.

First of all, here’s the download of slides and samples from the session: Functional Programming in C# 3.0

Second, I’ve had a little thought about that example I was asked about during the session. It was one of the methods in the first basic example, and it looks like this:

public static IEnumerable GetAllMembersFunctional( ) {
  return AppDomain.CurrentDomain.GetAssemblies( ).SelectMany(
    assembly => assembly.GetTypes( ).SelectMany(
      type => type.GetMembers( )));
}

The question about it is whether this is a “real” functional implementation of the functionality or not, given that GetAssemblies returns information that changes dynamically outside my own function. I first pointed out in the session that the example was of course about the implementation of the method, not necessarily about whether or not you would want to implement a function that does precisely this same thing, especially if you subscribe to the “pure” theory of functional programming. The more important thing about this came to my mind a bit later, but it depends a little bit on perspective. From the perspective of the person who implements this method, I could say “Of course this is entirely valid — I’m simply calling other functions to return information to me (even though those functions don’t take parameters, so perhaps the source of the data is just a little suspect). I’m not the one who makes the decision to actually retrieve the information from what might be considered unreliable shared storage.”

On the other hand, the function in question (GetAssemblies) is a function from my “runtime libraries”, in the form of the .NET framework, and it could equally well be said that I have to be aware of the nature of such functions and whether or not they do something I don’t want to do, and perhaps make the decision not to use them. In the end it all comes down to discipline again. Modern functional programming, especially when applied to real world problems, is rarely “pure”. There’s sometimes a necessity to deal with shared data and external state to solve real-world problems. Modern functional languages recognize that and provide the means to do it, thereby removing restrictions and pushing the problem back into the area of discipline. There are small steps being taken to remind you of that choice you made, like the fact that you need special keywords in F# to create mutable variables. But if it’s your choice to try to live without shared state, it’s also your responsibility to adhere to that choice as much as you can, and decide sensibly about situations where you can’t.