4
$\begingroup$

In C#, one can define a class/method/function with multiple type parameters. For example,

// function
void foo<T1, T2>(T1 x, T2 y) { /*body*/}

// class
class Bar<T1, T2> { /*body*/ }

I understand how to use it, but I don't understand why I need it. So I'm hoping someone can answer the following questions:

1) What is the use case for multiple type parameters?

2) Based on the use case given in Question 1, what are the alternative solutions for that use case if multiple type parameters is not a feature of the language in use?

$\endgroup$
6
  • 2
    $\begingroup$ Cross-posted: cs.stackexchange.com/q/95280/755, stackoverflow.com/q/51348045/781723. Please do not post the same question on multiple sites. Each community should have an honest shot at answering without anybody's time being wasted. $\endgroup$
    – D.W.
    Commented Jul 15, 2018 at 17:07
  • 3
    $\begingroup$ "but I don't understand why I need it." You don't need high-level programming language at all, you can do anything on asm. But somewhy you prefer not to program on asm when you can do it on C#. $\endgroup$
    – rus9384
    Commented Jul 15, 2018 at 17:15
  • 1
    $\begingroup$ @D.W. It depends on the context of the case. If the same question could and should be answered from different perspectives on different sites, it's nothing wrong to post it on both. Another question is whether it should be answered from different perspectives. Computer scientist vs. programmer. $\endgroup$
    – rus9384
    Commented Jul 15, 2018 at 17:17
  • 1
    $\begingroup$ @rus9384, I appreciate your reasoning, but that's not what our community policy says. $\endgroup$
    – D.W.
    Commented Jul 15, 2018 at 17:23
  • 1
    $\begingroup$ @D.W. I believe the example was pretty bad. More robust one would be to ask the same question on philosophy and buddhism. $\endgroup$
    – rus9384
    Commented Jul 15, 2018 at 17:27

1 Answer 1

17
$\begingroup$

Some use cases for multiple type arguments include

  • maps/dictionaries Map<K,V>, where you have one key parameter and one value parameter
  • product types Pair<A,B>
  • sum types, AKA variants Variant<A,B>, which represent a value which might be either of type A or of type B
  • Function-like types Func<A,B> representing a function from A to B
  • "Visitor" objects for parametric types. I.e. a visitor for List<A> is ListVisitor<A,R> where R is the return type of the visitor.

If we did not have multiple type arguments, or any other way to emulate multiple argument types (e.g. nested parametric classes class T<A> { class U<B> { ... which are a sort-of curried version of the two-arguments class), we could not express the examples above in a generic way.

Of course, a programming language could disallow generic classes and still have a specific primitive type for some of the examples above. For instance, Func<A,B> could be a primitive type, instead of a user/library-defined class type.

$\endgroup$
10
  • 3
    $\begingroup$ Multiple types are also redundant if product types are primitive types (e.g. (Int, String)) and the language offers projection operators on these pairs: class Map<T> { /* use first(T) and second(T) as types here */ }. Then one only needs to write Map<(Int, String)>. $\endgroup$
    – ComFreek
    Commented Jul 15, 2018 at 16:03
  • 1
    $\begingroup$ @ComFreek You can't define Map that way. Map is a constructor of kind * -> * -> *. You're approach would make it * -> *, which couldn't enforce the type parameter to be a pair. That's exactly why we have kinds. $\endgroup$
    – gardenhead
    Commented Jul 15, 2018 at 19:28
  • 1
    $\begingroup$ @gardenhead Just create a compiler error when T is not a pair... (at least C++ allows that) $\endgroup$
    – user91718
    Commented Jul 16, 2018 at 1:28
  • $\begingroup$ @gardenhead: I think you're assuming too much about other properties of the language. There's no reason that the language couldn't let Map impose constraints on its type parameter, analogous to Haskell typeclasses, C# where constraints, Java extends bounds, etc. $\endgroup$
    – ruakh
    Commented Jul 16, 2018 at 1:54
  • $\begingroup$ @ruakh That's precisely what kinds are for... imposing constraints on a type constructor. $\endgroup$
    – gardenhead
    Commented Jul 16, 2018 at 2:00

Your Answer

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

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