News for hackers. Stuff that matters.
Re:Map[string]interface{} in Go: a user's manual by nixpulvis on Monday July 26, 2021 @02:14PM (#27963013)
> What's the point of interface{}, then, if it doesn't tell us anything about the value? Well, that's precisely why it's useful: it can refer to anything!

An empty interface should be effectively useless. What could it possibly do!? This pattern is much more like a dynamic container with a type tag.

Re:Map[string]interface{} in Go: a user's manual by jhoechtl on Monday July 26, 2021 @03:21PM (#27964077)
This article would be great to be revised once parametric types (AKA "generics") become an official part of the language.

https://go.googlesource.com/proposal/+/master/design/15292/2...

https://go2goplay.golang.org/

Re:Map[string]interface{} in Go: a user's manual by kjksf on Monday July 26, 2021 @03:40PM (#27964364)
map in Go is already generic. If you need map[string]int or map[int]float, you can already do it.

Generics do not obviate the need for interface{} or the described use case of map[string]interface{}

interface{} is like Java or C# object. It packages a type and a value in a single value that can be queried at runtime to extract the underlying value in a type safe matter.

When people use map[string]interface{] it's because they don't know the type of value at compile time.

Re:Map[string]interface{} in Go: a user's manual by cle on Monday July 26, 2021 @04:09PM (#27964737)
I'm not sure why you're being downvoted, the only alternatives I've seen are to use methods or enums, which constrain the types to those supported by JSON, but ultimately you still have to switch on the type at runtime, the tradeoff being between closed enums vs. open interfaces, or the runtime tradeoffs of methods. Rust's serde_json uses enums for this, but the maps are generic in the same way that they already are in Go.
Re:Map[string]interface{} in Go: a user's manual by ibraheemdev on Monday July 26, 2021 @04:24PM (#27964967)
> the maps are generic in the same way that they already are in Go.

Go maps are actually not generic in the same way they are in other languages, there is just a single map struct with type descriptors used to do some compiler magic: https://dave.cheney.net/2018/05/29/how-the-go-runtime-implem...

Re:Map[string]interface{} in Go: a user's manual by cle on Monday July 26, 2021 @05:25PM (#27965698)
Yes I'm aware that there are differences, but it's not clear to me how that's relevant.
Re:Map[string]interface{} in Go: a user's manual by ibraheemdev on Monday July 26, 2021 @05:50PM (#27965929)
Well you said "maps are generic in the same way that they already are in Go", which I took to mean that Go already has monomorphized generics under the hood, they just aren't exposed publicly.
Re:Map[string]interface{} in Go: a user's manual by cle on Wednesday July 28, 2021 @10:10AM (#27983947)
I'm specifically talking about the subset of ways in which they are similar and also relevant to this scenario of handling arbitrary structured data like JSON. There are of course ways in which they are not similar, but I'm not sure how those are relevant to this scenario being discussed....could you elaborate on that?
Re:Map[string]interface{} in Go: a user's manual by cratermoon on Monday July 26, 2021 @04:52PM (#27965305)
Yeah, no. That's not what generics mean. A map of any single type with any type for the key is different from a map using generic types.

For generics what you want is not interface{}, which says nothing, but a type T that has meaningful constraints.

Re:Map[string]interface{} in Go: a user's manual by tptacek on Monday July 26, 2021 @02:16PM (#27963055)
Doing nothing is the point; it serves the same purpose as a `void*` in C, except that there are (runtime-) safe ways to take a value out of `interface{}` and back to its concrete type in Go. The most obvious use for it is heterogenous containers.
Re:Map[string]interface{} in Go: a user's manual by throw_m239339 on Monday July 26, 2021 @02:43PM (#27963469)
> The most obvious use for it is heterogenous containers.

You mean runtime generic container without the benefits of compile-time type checking, opening the developer to runtime type errors purely for ideological reasons...

Re:Map[string]interface{} in Go: a user's manual by earthboundkid on Monday July 26, 2021 @03:09PM (#27963891)
That Go would benefit from generics doesn't change the fact that there are also lots of use for heterogenous containers. As it is, Go already has "slices" for type safe containers. The fair complaint about Go is it's hard to do other type safe container than the built in "slice" and "map" containers. But the problem is on track to be fixed next year, so it's silly to complain about it now.

It's really hard to take people who complain about Go seriously when they're pretty obviously just zealots who don't know much about the language besides "types good" and "Go bad". My stance: types good in moderation; Go a useful tradeoff of engineering attributes.

Re:Map[string]interface{} in Go: a user's manual by throw_m239339 on Monday July 26, 2021 @03:11PM (#27963915)
> so it's silly to complain about it now.

No it isn't, Go has other flaws stemming from the exact same root cause and it has nothing to do with programming...

Re:Map[string]interface{} in Go: a user's manual by mseepgood on Monday July 26, 2021 @03:46PM (#27964434)
> purely for ideological reasons

There are no ideological reasons.

https://github.com/golang/go/commit/dd64f86e0874804d0ec5b713... "Generics may well come at some point."

https://golang.org/doc/faq#generics "A language proposal implementing a form of generic types has been accepted for inclusion in the language. If all goes well it will be available in the Go 1.18 release."

One of the language designers explaining the motivation for adding parametric polymorphism to Go: https://www.youtube.com/watch?v=RIvL2ONhFBI&t=1064s

Explaining the benefits of generics: https://www.reddit.com/r/golang/comments/jditu9/what_do_gene...

From the Featherweight Go paper: https://arxiv.org/pdf/2005.11710.pdf "Recently, the Go team mooted a design to extend Go with generics, and Rob Pike wrote Wadler to ask: Would you be interested in helping us get polymorphism right (and/or figuring out what “right” means) for some future version of Go?"

Re:Map[string]interface{} in Go: a user's manual by ibraheemdev on Monday July 26, 2021 @04:29PM (#27965020)
Yup, it's a common misconception that Go language designers are anti-generics. They wanted to include generics, the reason they were left out is that there was no clear way to include them without significant downsides:

> The generic dilemma is this: do you want slow programmers, slow compilers and bloated binaries, or slow execution times?

> I would be happy to learn about implementations that somehow manage to avoid all three of these bad outcomes, especially if there were good written descriptions (papers, blog posts, etc.) about what was hard and why it's a good approach. I'd also be interested to see good written descriptions of trying one of those approaches and what went wrong (or right).

- Russ Cox (2009): https://research.swtch.com/generic

Re:Map[string]interface{} in Go: a user's manual by paulddraper on Tuesday July 27, 2021 @03:05AM (#27969481)
> do you want slow programmers, slow compilers and bloated binaries, or slow execution times?

Which one did Rust choose?

Re:Map[string]interface{} in Go: a user's manual by mseepgood on Tuesday July 27, 2021 @08:02AM (#27971413)
slow compiler
Re:Map[string]interface{} in Go: a user's manual by tptacek on Monday July 26, 2021 @03:22PM (#27964079)
I think you read my comment as an invitation to debate dynamic vs. static safety checking. That seems like a deeply uninteresting debate. I'm just saying, there's a clear purpose to `interface{}`, and the same pattern shows up (though obviously much less frequently) in Rust.
Re:Map[string]interface{} in Go: a user's manual by tomjakubowski on Monday July 26, 2021 @04:17PM (#27964856)
In the interest of supplying information to the curious, the Rust equivalent is to use an Any trait object with down casting.

https://doc.rust-lang.org/std/any/index.html

Re:Map[string]interface{} in Go: a user's manual by jjnoakes on Monday July 26, 2021 @03:34PM (#27964280)
The two are orthogonal. Even with generics, languages can have an "escape" type like interface{} which is used/necessary for when you do want (or require) run-time type checking.
Re:Map[string]interface{} in Go: a user's manual by earthboundkid on Monday July 26, 2021 @03:08PM (#27963865)
That Go would benefit from generics doesn't change the fact that there are also lots of use for heterogenous containers. As it is, Go already has "slices" for type safe containers. The fair complaint about Go is it's hard to do other type safe container than the built in "slice" and "map" containers. But the problem is on track to be fixed next year, so it's silly to complain about it now.
Re:Map[string]interface{} in Go: a user's manual by a1369209993 on Monday July 26, 2021 @03:04PM (#27963797)
> opening the developer to runtime type errors purely for ideological reasons...

To be fair, there are also language-implementor-laziness reasons.

Re:Map[string]interface{} in Go: a user's manual by nixpulvis on Monday July 26, 2021 @02:42PM (#27963461)
Runtime safe and statically type checked are two fundamentally different things is my point. Interfaces in most typed languages are static concepts, though there are always exceptions.
Re:Map[string]interface{} in Go: a user's manual by strbean on Monday July 26, 2021 @03:01PM (#27963750)
You can think of interface{} like Object in Java.

Interfaces in go are simply saying "this thing satifies these properties". interface{} is an interface that anything can satisfy.

Re:Map[string]interface{} in Go: a user's manual by nixpulvis on Monday July 26, 2021 @03:22PM (#27964082)
I will continue to think of interface{} as Any in Rust.
Re:Map[string]interface{} in Go: a user's manual by ibraheemdev on Monday July 26, 2021 @04:30PM (#27965029)
`interface{}` used as a type is almost exactly `Box<dyn Any>`.
Re:Map[string]interface{} in Go: a user's manual by jrockway on Monday July 26, 2021 @02:25PM (#27963174)
I don't think "empty" is quite the right mental model. It's an object that has at least 0 methods, which is a characteristic of every data type. An actually empty type in Go is struct{} (good for map values when the map represents a set).
Re:Map[string]interface{} in Go: a user's manual by LambdaComplex on Monday July 26, 2021 @03:01PM (#27963748)
To be clear, "empty interface" is the official term: ctrl+f "empty interface" on https://golang.org/ref/spec
Re:Map[string]interface{} in Go: a user's manual by ibraheemdev on Monday July 26, 2021 @04:25PM (#27964980)
Well the interface's method set is empty, not the underlying type.