Live data from Hacker News

Go Data Structures: Interfaces (2009)

research.swtch.com

11–20 of 80 posts

Re: Go Data Structures: Interfaces (2009)

#11
The comparisons to python are a bit dated now. All of the examples can be implemented in python using typing extensions [0] and statically checked before runtime using mypy [1].

[0] https://docs.python.org/3/library/typing.html (from Python 3.5 - released Sep 2015)

[1] https://github.com/python/mypy (v0.1 released Sep 2009)

Re: Go Data Structures: Interfaces (2009)

#12
post #2

A quirk of Go is that I can cast a `[]string` to `interface{}`, but I cannot cast `[]string` to `[]interface{}`. This blog post is my go-to explanation for why the second is not possible but the former is.

Because the latter would incur a hidden O(n) computation.

Re: Go Data Structures: Interfaces (2009)

#13
post #6
post #4

Earlier quoted context omitted.

Is that really a "quirk" of specifically Go? I am pretty sure Java--the implementation of which defined a lot of how numerous languages handle this kind of thing--has the same behavior: you can cast String[] to Object, but not Object[].

C# allows casting string[] to object[], but this requires the compiler to insert runtime type checks each time the array elements are modified: object[] array = new string[10]; // throws a run-time exception array[0] = 10;

Note that array covariance is largely considered a design mistake and if .NET was to be redone it wouldn't have one (and a bunch of smaller things that are an artifact of generics getting introduced in C# 2.0 and not 1.0, well, the problem is much worse in Go heh).

Other data structures like List, Span, etc. do away with covariance. There's an upcast for ReadOnlySpan but only because it's zero-cost and does not introduce the issues stemming from covariance.

Luckily, you almost never see someone use array covariance beyond occasional object[] upcasts (and the compiler is also good at reasoning whether to insert covariance checks or not).

Re: Go Data Structures: Interfaces (2009)

#14
post #10
post #7

If you are mindful of performance, one thing to be careful of, is that interfaces often prevent inlining and can cause performance issues. Generally speaking the Go compiler seems to have trouble with inlining, PGO (profile guided optimization) can help though.

Storing concrete values into interfaces often cause allocations, which has a larger impact on performance than inlining.

Yeah I was really surprised by how much of a performance difference it made when calling variadic functions that support `args ...interface{}`. Literally every since call is going to be an allocation of multiple parameters when passing structs without a pointer

Re: Go Data Structures: Interfaces (2009)

#15
post #7

If you are mindful of performance, one thing to be careful of, is that interfaces often prevent inlining and can cause performance issues. Generally speaking the Go compiler seems to have trouble with inlining, PGO (profile guided optimization) can help though.

> Go compiler seems to have trouble with inlining not "have trouble", a deliberate design to keep compile times fast and (emitted) code size reasonable

Ah yes, whichever it is, always design.

Re: Go Data Structures: Interfaces (2009)

#16
post #7

If you are mindful of performance, one thing to be careful of, is that interfaces often prevent inlining and can cause performance issues. Generally speaking the Go compiler seems to have trouble with inlining, PGO (profile guided optimization) can help though.

You have to manually collect and then apply the profile though (very few teams do this). A proper solution is doing a whole program view optimization (at least like the one done by .NET's NativeAOT). But typically of Go design philosophy, a stop-gap solution was chosen instead.

Re: Go Data Structures: Interfaces (2009)

#18
post #6

Earlier quoted context omitted.

C# allows casting string[] to object[], but this requires the compiler to insert runtime type checks each time the array elements are modified: object[] array = new string[10]; // throws a run-time exception array[0] = 10;

Note that array covariance is largely considered a design mistake and if .NET was to be redone it wouldn't have one (and a bunch of smaller things that are an artifact of generics getting introduced in C# 2.0 and not 1.0, well, the problem is much worse in Go heh). Other data structures like List , Span , etc. do away with covariance. There's an upcast for ReadOnlySpan but only because it's zero-cost and does not int…

Well, .NET only exists in first place because of Sun's lawsuit, Ext-VOS was designed with J++ in mind.

Thus having high compatibility with how Java used to be was a big factor designing C# 1.00

Re: Go Data Structures: Interfaces (2009)

#19
post #5
post #2

A quirk of Go is that I can cast a `[]string` to `interface{}`, but I cannot cast `[]string` to `[]interface{}`. This blog post is my go-to explanation for why the second is not possible but the former is.

> I can cast a `[]string` to `interface{}`, but I cannot cast `[]string` to `[]interface{}` Surely that's just contravariance, though? You can't cast []string to []any because that would allow you to write non-strings to it.

Yeah, I have plenty of criticisms of Go, but this is something that it got right.

For those who aren't familiar with the issue, in Java you can assign an array of a subclass to a variable declared as an array of the superclass, which leads to issues if you actually try to mutate it. Imagine if Cat and Dog both inherit from Animal, assigning a Dog[] to an Animal[] is totally valid, but then setting one of the elements to a Cat will throw an an exception.

Re: Go Data Structures: Interfaces (2009)

#20

The comparisons to python are a bit dated now. All of the examples can be implemented in python using typing extensions [0] and statically checked before runtime using mypy [1]. [0] https://docs.python.org/3/library/typing.html (from Python 3.5 - released Sep 2015) [1] https://github.com/python/mypy (v0.1 released Sep 2009)

One thing I like about Go is that you can read a decade-old blog and still find it somewhat relevant.

Python was the first language I made money with. However, these days, I struggle to read and make sense of type-ridden, generic-filled, Pydantic-infested Python code.

Post reply on HN