6

I'm learning functional programming and face the following confusion when applying it to my C# projects:

  • I begin by writing pure, static functions and use function composition.
  • After the code reaches a certain size, I realize some of these functions tend to "cluster" about some types. For example, there exist >5 functions having the same type as parameter.

  • Next step, my object-oriented background takes over and I move these functions to this type (class) as methods. As a result, their signatures simplify and they often become more cohesive. However, I lose the benefits of functional style.

I've grown very fond of functional approach, but I cannot convince myself that my initial code was better above. Which approach would you prefer in this situation (in C# or another mixed language)?

Related: Design in "mixed" languages: object oriented design or functional programming?

class MyType { }

class Functions
{
    public static void X(MyType t) { }
    public static void Y(MyType t) { }
    public static void Z(MyType t) { }
    public static void T(MyType t) { }
    public static void U(MyType t) { }
}

class Class1
{
    public MyType T { get; private set; }
    public Class1(MyType t) { T = t; }
    public void X() { }
    public void Y() { }
    public void Z() { }
    public void T() { }
    public void U() { }
}
21
  • 1
    Why do you "lose the benefits of functional style"? If you need grouping, you can create and nest static classes that group together the related functions. And there's nothing wrong with having multiple functions take in the same type as their parameter, just think about how many methods inside .NET take a 'string' param.
    – GHP
    May 11, 2015 at 12:26
  • 5
    It sounds like you want to do some functional programming in the .NET world. Why not use F#? It's interoperable with the rest of the .NET platform and its resident languages.
    – Andy Hunt
    May 11, 2015 at 12:34
  • @Graham: Lose the benefits => impure functions, need an instance to call the method, etc. Nested static classes => Agreed, I already use them but still cluttered because of the extra parameters in functions. 'string' => Point taken, but I think 'string' is too basic to be an example, for example how many methods take 'DataGridView' as parameter?
    – henginy
    May 11, 2015 at 12:42
  • @AndyBursh Yes, I'm also learning F#. Unfortunately I cannot use it in my projects at work since no one else knows it.
    – henginy
    May 11, 2015 at 12:43
  • 1
    @henginy There is a book, which answers your question: Functional Programming in C# by Oliver Sturm, 2011. isbn 9780470744581 May 12, 2015 at 18:35

3 Answers 3

7

However, I lose the benefits of functional style.

If you always lose the benefits of functional style code when converting bundles of functions to objects, you're doing it wrong (or have an usual idea of what the benefits of functional style are).

After all, instance functions are the same thing as static functions but simply have an additional implicit parameter. If you're making these functions impure, that's your problem, not a problem inherent to OO code. If you make your classes mutable, then yes, you're going to lose functional style benefits.

But if you keep your classes immutable (except for collections/DTOs), I find that you can maintain many of the benefits of functional style coding while getting some OO goodness as well.

9
  • Not always, but yeah, sometimes :). For example the user updates the parameters and I have to refresh the display accordingly; so I just set properties of calculation object to new values and recalculate. I believe my main concern is performance, not that I measured it, but I'm not experienced enough on whether the whole immutability and required .Clone calls in C# will be ok in terms of speed. But thanks for pointing me in this direction.
    – henginy
    May 11, 2015 at 13:44
  • @henginy - what required clone calls? That's not going to be performant, but it also should not be necessary.
    – Telastyn
    May 11, 2015 at 13:46
  • I will eventually need to keep the state somewhere. For example, if the state object has many variables and I just need to update one of them during runtime, I believe I'll have to clone the state with only that variable's value changed.
    – henginy
    May 11, 2015 at 13:54
  • 2
    Instance functions are the same thing as static functions but simply have an additional implicit parameter... and state that is tied to the object, rather than the class. May 11, 2015 at 14:54
  • 1
    @DavidY - no. Just that bags of data tend to be more safe from a functional mindset than classes where behavior is tied to state.
    – Telastyn
    Jun 27, 2021 at 20:40
3

I don't think that simply using static methods makes it Functional

I don't think simply moving your previously static methods to a class makes it OO

If you are doing OO, then your classes should have properties and the methods should change those properties. This makes the 'data object' mutable and functional programming goes out the window

While Static does stop you using properties from the same class, you can still reference other static data or databases etc. Functional programming relies on your methods returning the same result for the same parameters every time.

Going from your Example code:

ive followed your pattern but added a real method

public class MyType
{
    public int ANumber { get; set; }
}

public class StaticFunctions
{
    public static int AddOne(MyType x)
    {
        return x.ANumber + 1;
    }
}

so you convert your static method to OO via this kind of pattern:

public class MyOOClass
{
    public MyType data { get; private set; }
    public MyOOClass(MyType data)
    { this.data = data; }

    public int AddOne()
    {
        return this.data.ANumber + 1;
    }
}

But really this is nothing more than a namespace for your static functions. it arguably makes them harder to use as you have to initiate an extra MyOOClass for every MyType.

If you wanted to make it OO I would change it to something like this:

public class OOClass
{
    public int ANumber { get; private set; }
    public OOClass(int n)
    {
        this.ANumber = n;
    }

    public void AddOne()
    {
        this.ANumber= this.ANumber+1;
    }
}

if you wanted to make it functional i would change it to something like this:

public Func<int, int> AddOne = (x) => x + 1;

My Personal fave though would be ADM

public class AdditionService()
{
    public MyType AddOne(MyType a)
    {
        return new MyType() {ANumber=a.ANumber+1};
    }
}
7
  • When I move the methods, I make them instance methods and set the parameter once in the constructor.
    – henginy
    May 11, 2015 at 14:07
  • What is 'ADM' in your example?
    – henginy
    May 12, 2015 at 5:59
  • anemic domain model, the idea is you have data struct type models and put the logic in service classes. some people consider it 'bad' but I think it will fit your style quite well and allow you to get rid of your statics but keep your methods immutable
    – Ewan
    May 12, 2015 at 8:27
  • I'd very much so contend the claim that OO code implies mutable classes. in fact, most "designer gurus" and books on the subject will tell you to favor immutability for many different reasons. You can certainly do a combination of your last example with immutable objects, e.g. public MyType AddOne() { return new MyType(this.ANumber+1); }. Some would decry this as inefficient and wasteful, but unreferenced objects get GCd and object creation really isn't expensive enough to worry about premature optimizations.
    – sara
    Mar 29, 2016 at 15:53
  • hmm, while immutability is 'a good thing' and I can imagine your example working well for some 'low level' functionality or pattern implementation (event sourcing?). I don't think its very OO. what if you have events on the object for example.
    – Ewan
    Mar 30, 2016 at 9:39
1

You can write functions even when using classes.

You said you created static functions, so there is no "state". When you move those methods to their respective classes, of course they can't continue to be static, they need to be regular instance methods.

But if you don't modify any of the parameters, even the receiver of the message (which is the same as the container of the method), it continues to be functional style. Just don't modify any of the parameters.

The real advantage of the functional style is that the functional style can be functionally executed in a way that is really simple: replace the called code with the body of the ode being called. You can repeat this many times. And therefore you can be sure it produces the desired output.

1
  • Welcome and thank you for your help. The reason why I am moving the methods is to make them instance methods and take advantage of the constructor to set the parameter once, so that the methods do not need a parameter.
    – henginy
    May 11, 2015 at 14:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.