HN2new | past | comments | ask | show | jobs | submitlogin

Nice, congratulations on the release.

I'd really like to see some progress on generics / parametric types. I'm starting to get the impression that it will never happen.



It looks like 1) generics are not very well aligned with the main design goals of Go and 2) it would take a very well thought out design to align them so, if that's possible at all.

From the FAQ: "Generics are convenient but they come at a cost in complexity in the type system and run-time. We haven't yet found a design that gives value proportionate to the complexity, although we continue to think about it. Meanwhile, Go's built-in maps and slices, plus the ability to use the empty interface to construct containers (with explicit unboxing) mean in many cases it is possible to write code that does what generics would enable, if less smoothly.

This remains an open issue."


I've seen this argument several times, and I'm not sure I understand it. The recommended workaround (empty interface and explicit unboxing) is, at runtime, pretty much how Java generics work: the parameter types get "erased", and the bytecode operates on Object (the closest equivalent to Go's empty interface) no matter what they are. But at compile time, the compiler infers the (obviously necessary) typecasts, so, you don't have to explicitly clutter up your source code with them. That strips away a layer of crud which obscures the underlying logic of the code, making it harder both to read and to write.

The other constant line from the Go implementers is something like "generics have proven troublesome in [unnamed] other languages, so we don't want them until we're sure we can get them right". This may be a reference to C++, in which compiling templates turns out to be a real pain. But at this point, the literature is full of better ways to do it.


> the ability to use the empty interface to construct containers (with explicit unboxing)

I'm not versed in Go, but does that mean something similar to (Java-style) Object[] and explicit casting of each value you get out of the list?


Go has so called type assertions, an example:

http://play.golang.org/p/L5hprjhqN_

In this example, one function probes the underlying type by using t.(type), and the other one uses a type assertion by doing a val, ok := t.(int) - The type assertion will return the value of the integer and true if t happens to be an integer (a Go function can return multiple values)

If you pass an object as an "empty interface{}" you can test the underlying type.

edit: Note that you can only use a type assertion with an interface! So, this fails: http://play.golang.org/p/0BtSWfE3f2 but this doesn't: http://play.golang.org/p/tZB4Jivp3z


If you pass an object as an "empty interface{}" you can test the underlying type.

So, the answer is that it is pretty much the same as in Java, since there you also use reflection to get the type of Object:

    if (o instanceof String) {...}
The type assertion is just syntactic sugar.

The difference is that Java stores the type in the actual instance, while Go stores the type in the 'reference' (which is normally a type-pointer tuple). Unfortunately, Go's approach can lead to the situation where nil (null) is not nil, when two references have null as its pointer, but different types.


Is this purely evaluated at runtime or does Go annotates types with its static analysis and restricts the interface in some ways? IOW are default and else cases made optional by Go's static analysis, which would help Go throw its arms up at compile time if an unexpected type is passed?


> Is this purely evaluated at runtime or does Go annotates types with its static analysis and restricts the interface in some ways?

Interfaces in a nutshell:

Go checks at compile-time that any concrete variable passed where in interface is expected satisfies the methods of that interface.

Conversely, Go checks at compile-time that the program never attempts to invoke methods on an interface value that are not guaranteed by the interface.

In this example, there is a compile-time error (not a runtime error), because we attempt to call a non-guaranteed method on an interface value, even though the underlying value satisfies this interface: http://play.golang.org/p/EaQQpv-NAW

This provides type safety: if your program compiles, you know that you will never run into a runtime error by trying to invoke an undefined method.

When you do type assertions, you're using reflection (ie, http://golang.org/pkg/reflect/) to determine the underlying value at runtime.

However, remember that using type assertions essentially sidesteps the benefits of having interfaces. Interfaces allow you to invoke function calls with type safety on values of unknown type, as long as it is known that the underlying type provides the required set of methods.


I think it's purely evaluated at run-time because you can do this:

http://play.golang.org/p/Mtg8A5SzdS


That is exactly what it means.


I'm pretty sure they will never happen. The designers of Go don't seem at all interested in having them, they show no sign that they are actively studying the problem and exploring how other languages solve it. And as Go becomes more and more popular, there is less and less incentive to make a major language-breaking change, so as far as I'm concerned, if you want type parametricity, you're better off looking elsewhere.




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

Search: