C# Generics – Why Out Type is Generally Last

cgenerics

This is a bit of a subjective question I guess but I was hoping for opinions on either side of the argument.

So take this for example in C#:

public interface IFactory<Tin, Tout> : IFactory
{
    Tout Create(Tin param);
}

Now as you can see we take an input type and an output type, however a lot of frameworks often have a raft of different generics in these sort of cases where you often end up having TinOne, TinTwo etc to cope with multiple use cases. So even in the C# source it generally does <all input types, output type> however when you actually go to look at the implementations of interfaces like this, you generally (again subjective) want to know what the return type is, as that is often the contract you care about for the rest of the program, so it often makes it harder to find these interfaces in code due to the output type being last in the list not first.

So why was this approach taken? as personally I would find output being first being more logical, but I am sure there is a good reason why.

Best Answer

That's the way function types are normally written:

a → b

is a function that takes an a and returns a b.

(a, b) → c

is a function that takes a tuple of (a, b) and returns a c.

a → b → c

is a function that takes an a and returns a function that takes a b and returns a c (which is the curried version of the second function above).

In all these cases, the inputs come first, then the output. And it makes sense: data flows from input to output, types flow from input to input to output, and we read from left to right.

It also matches with declarations for subroutine prototypes in many languages. E.g. Scala:

// method:
def add(a: Int, b: Int): Int

// function:
(a: Int, b: Int) ⇒ { //body of the function, return type is inferred }

Go:

func add(a int, b int) int

Haskell:

add :: (Int, Int) → Int
-- or more idiomatically:
add :: Int → Int → Int

And so on.