Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Can someone explain in terms to someone who hasn't really used a static typed language what "generics" are? I've only used javascript and ruby.


Consider this function signature:

func SomeAdditionFunction(arg1 int, arg2 int) { fmt.Println("Sum:", arg1 + arg2) }

This function will only accept a pair of integers. In order to perform addition on floats or int64s or any other number type, you would need a separate function.

Go has the concept of an empty interface (interface{}) which can accept any type. But this is not really a generic because you have to assert that it is a specific type in order to be sure what it actually is at runtime. This function for example, will not compile:

func SomeAdditionFunction(arg1 interface{}, arg2 interface{}) { fmt.Println("Sum:", arg1 + arg2) }

But this will:

func SomeAdditionFunction(arg1 interface{}, arg2 interface{}) { fmt.Println("Sum:", arg1.(int)+arg2.(int)) }

In a language like Java, I could write this function to accept any type for which the + operator is valid, and it would still be type safe at compile time. I would not need to assert the types like I did above.


> In a language like Java, I could write this function to accept any type for which the + operator is valid, and it would still be type safe at compile time. I would not need to assert the types like I did above.

Really? No. Not in Java.

  static <T extends Number> void someAdditionFunction(T arg1, T arg2) {
    System.out.println("Sum:", arg1 + arg2);
  }
"error: bad operand types for binary operator '+'"


That's because + is a java built-in unavailable to normal types. Usually something like an add method is used instead. It does not detract from the underlying point.


Yeah, it works with methods, but unfortunately arg1 + arg2 isn't implemented by calling a method on Number.


In a static language, functions, classes, and types are often parametrized by other types.

For example, with a function: imagine you wrote a `sum(array)` function. In Ruby that's not a problem, because array can contain any types, as long as they support the + operator (aka duck typing). Any function can also return any type of object.

In a static language, however, an array that holds floats has a different type than an array that holds integers or an array that holds strings. The return value of the function sum() will also be different, depending on the type of the array, because if it's an array of floats, the sum will be a float.

So generics allow you to sort of implement duck-typing in static language:

T sum(array<T>) // Pseudocode

Now the sum function will take an array of any type T, and return a result of the same type T.

Similar idea for classes and other types. The classic example is a container. A linked-list in Ruby can contain any type or mixture a types, since the language is fully dynamic. However, in a static language, a linked-list of strings has a different type than a linked-list of ints. So you write something like (pseudocode):

class List<T> { T head_val() { return head.val; } }

Now you write the List<T> class once, and use it for any type T, so it's DRY when you may have any number of types T that your program stores in a list.


Awesome, so this makes sense. So I guess people are against it because they like the explicit simple nature of Go rather than some sort of abstraction magic?


I can't speak for all of them, but generics do tend to add a bunch of rules to a language, and make it more complex than before.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: