Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly partition code in a C# functional library?

As a premise one of a key difference of FP design about reusable libraries (for what I'm learning), is that these are more data-centric that corresponding OO (in general).

This seems confirmed also from emerging techniques like TFD (Type-First-Development), well explained by Tomas Petricek in this blog post.

Nowadays language are multi-paradigm and the same Petricek in its book explains various functional techniques usable from C#.

What I'm interested here and, hence the question, is how to properly partition code.

So I've defined library data structures, using the equivalent of discriminated unions (as shown in Petricek book), and I project to use them with immutable lists and/or tuples according to the domain logic of mine requirements.

Where do I place operations (methods ... functions) that acts on data structures?

If I want define an high-order function that use a function value embodied in a standard delegates Func<T1...TResult>, where do I place it?

Common sense says me to group these methods in static classes, but I'd like a confirmation from people that already wrote functional libs in C#.

Assuming that this is correct and I've an high-order function like this:

static class AnimalTopology {
  IEnumerable<Animal> ListVertebrated(Func<Skeleton, bool> selector) {
    // remainder omitted
  }
}

If choosing vertebrated animal has N particular cases that I want to expose in the library, what's the more correct way to expose them.

static class VertebratedSelectorsA {
  // this is compatible with "Func<Skeleton, bool> selector"
  static bool Algorithm1(Skeleton s) {
    //...
  } 
}

or

static class VertebratedSelectorsB {
  // this method creates the function for later application
  static Func<Skeleton, bool> CreateAlgorithm1Selector(Skeleton s) {
     // ...
  } 
}

Any indication will be very appreciated.

EDIT:

I want to quote two phrases from T. Petricek, Real World Functional Programming foreword by Mads Torgersen:

[...] You can use functional programming techniques in C# to great benefit, though it is easier and more natural to do so in F#. [...] Functional programming is a state of mind. [...]

EDIT-2:

  • I feel there's a necessity to further clarify the question. The functional mentioned in the title strictly relates to Functional Programming; I'm not asking the more functional way of grouping methods, in the sense of more logic way or the the way that make more sense in general.

  • This implies that the implementation will try to follow as more as possible founding concepts of FP summarized by NOOO manifesto and quoted here for convenience and clarity:

  1. Functions and Types over classes
  2. Purity over mutability
  3. Composition over inheritance
  4. Higher-order functions over method dispatch
  5. Options over nulls

The question is around how to layout a C# library wrote following FP concepts, so (for example) it's absolutely not an option putting methods inside data structure; because this is a founding Object-Oriented paradigm.

EDIT-3:

Also if the question got response (and various comments), I don't want give the wrong impression that there has been said that one programming paradigm is superior than another. As before I'll mention an authority on FP, Don Syme, in its book Expert F# 3.0 (ch.20 - Designing F# Libraries - pg.565):

[...] It's a common misconception that the functional and OO programming methodologies compete; in fact, they're largely orthogonal. [...]

like image 532
jay Avatar asked Mar 28 '13 19:03

jay


1 Answers

Note: If you want a shorter, more-to-the-point answer, see my other answer. I am aware that this one here might seem to ramble & go on forever & talk past your issue, but perhaps it will give you a few ideas.

It is difficult to answer your question without knowing the exact relationship between Animal and Skeleton. I will make a recommendation about this relationship in the second half of my answer, but before I do that, I will simply go along with what I see in your post.

First I will try to infer a few things from your code:

static class AnimalTopology
{
    // Note: I made this function `static`... or did you omit the keyword on purpose?
    static IEnumerable<Animal> ListVertebrated(Func<Skeleton, bool> selector)
    {
        …
    }
}
  1. If you have designed that function according to functional principles, it should have no side-effects. That is, its output relies only on its arguments. (And in a semi-object-oriented setting, perhaps on other static members of AnimalTopology; but since you didn't show any, let us ignore that possibility.)

  2. If the function is indeed side-effect-free (and does not access static members of AnimalTopology), then the function's type signature suggests that it is possible to derive an Animal from a Skeleton, because it accepts something that acts on Skeletons and returns Animals.

  3. If this is also true, then let me assume the following for the sake of being able to give an answer:

    class Skeleton
    {
        …
        public Animal Animal { get { … } } // Skeletons have animals!? We'll get to that.
    }
    

Now it is obvious that your function is impossible to implement, since it could derive Animals from Skeletons, but it doesn't receive any Skeleton at all; it only receives a predicate function that acts on a Skeleton. (You could fix this by adding a second parameter of type Func<IEnumerable<Skeleton>> getSkeletons, but...)

In my opinion, something like the following would make more sense:

static IEnumerable<Animal> GetVertebrates(this IEnumerable<Skeleton> skeletons,
                                          Func<Skeleton, bool> isVertebrate)
{
    return skeletons
           .Where(isVertebrate)
           .Select(s => s.Animal);
}

Now, one might wonder why you are guessing animals from their skeletons; and isn't the bool property "is vertebrate" an inherent property of an animal (or skeleton)? Are there really several ways to decide on this?

I would suggest the following:

class Animal
{
     Skeleton Skeleton { get; } // not only vertebrates have skeletons! 
}

class Vertebrate : Animal { … } // vertebrates are a kind of animal 

static class AnimalsExtensions
{
    static IEnumerable<Vertebrate> ThatAreVertebrates(this IEnumerable<Animal> animals)
    {
        return animals.OfType<Vertebrate>();
    }
}

Please note the use of extension methods above. Here's an example how to use it:

List<Animal> animals = …;
IEnumerable<Vertebrate> vertebrates = animals.ThatAreVertebrates();

Now suppose your extension method did more complex work. In that case, it might be a good idea to put it inside its own designated "algorithm type":

interface IVertebrateSelectionAlgorithm
{
    IEnumerable<Vertebrate> GetVertebrates(IEnumerable<Animal> animals);
}

This has the advantage that it can be set up / parameterized e.g. via a class constructor; and you could split up the algorithm into several methods that all reside in the same class (but are all private except for GetVertebrates.)

Of course you can do the same kind of parameterization with functional closures, but in my experience that quickly gets messy in a C# setting. Here, classes are a good means to group a set of functions together as one logical entity.

like image 120
stakx - no longer contributing Avatar answered Oct 09 '22 03:10

stakx - no longer contributing