9 ms·
Abstract Libraries in Go
- Firstmate 13y agoNew to Go still, what kind of caution should one take when using interface{} to store data in structs? It seems to be a catch-all sort of type, I've read how cluttered some code can get when using it (I think it was an HN post related to math in Go, and type-checking against an interface{} type). Thanks
- burntsushi 13y agoA general rule of thumb: don't use `interface{}` unless you have to. With respect to performance, it isn't free. And with respect to type safety, it isn't safe. (It is however memory safe when casting, unlike C's `void *`.) The key is that an `interface{}` is an interface with exactly 0 methods. Since all types in Go have at least 0 methods, any type satisfies `interface{}`. Resorting to using an `interface{}` type is akin to dynamic typing. All of your type errors get pushed to runtime and you lose any performance benefits you might get from the compiler knowing the type of your data. Russ Cox goes into great detail on the representation of interface values.[1] I wrote a blog post a while back on conveniently writing parametric functions in Go using reflection.[2] (Here, "convenience" is a relative term.) [1] - http://research.swtch.com/interfaces http://research.swtch.com/interfaces [2] - http://blog.burntsushi.net/type-parametric-functions-golang http://blog.burntsushi.net/type-parametric-functions-golang
- tuxcanfly 13y agoIs there a chance ty or a similar implementation will make it into Go core? What do you think about Go designers being generally averse to the idea of parametric polymorphism?
- burntsushi 13y ago> Is there a chance ty or a similar implementation will make it into Go core? I hope not! It was purely an experiment. There are significant draw backs, particularly with respect to performance. One could reasonably argue that writing parametric functions with reflection should be hard, so as to discourage users from resorting to it too easily. > What do you think about Go designers being generally averse to the idea of parametric polymorphism? I think the jury is still out. Russ Cox laid out the essential trade offs given to them: 1) slow programmers 2) slow programs or 3) slow compiler. There's a lot of wiggle room in there (what do you mean by "slow"?), but my sense is that they're still looking for a trade off they're happy with. In my experience with the Go community, there isn't a ton of internal complaining about the lack of generics. It's certainly brought up now and then, but it doesn't seem to put people off too much. Now, obviously this could just be confirmation bias, but if the Go community keeps growing despite the lack of generics, it may be difficult to justify generics in the future. (i.e., People will live with the first trade off.)
- NateDad 13y agoMy expectation is that they'll end up giving us something that'll make it easier to work around the lack of generics, but I don't know about getting actually full-on generics. Honestly, I don't want them - they make it way too easy to make overly complex code.... much like class inheritance. I've been developing for 14 years and can count on one hand the number of times I needed something like a tree or graph. Certainly, if you're working on scientific or mathematic projects, you may use them every day of the week, but if so, maybe Go isn't the right language for you, and honestly, it doesn't have to be everything to everyone.
- burntsushi 13y agoI'm skeptical that trees and graphs are the only thing generics are good for, but, I've published research with open source software written in Go.[1] I've also done it for Haskell.[2] I just try not to pigeonhole languages and learn as much as I can about different paradigms. In my experience, they all have something useful to offer beyond trees and graphs. [1] - https://github.com/BurntSushi/cablastp https://github.com/BurntSushi/cablastp [2] - https://github.com/ndaniels/mrfy https://github.com/ndaniels/mrfy
- wyager 13y ago>Declaring Data as interface{} allows a struct to initialize Data, and therefore a node in this graphing library can store anything (including another graph). This is probably one of the most important characteristics of Go. "Declaring Data as Object allows a class to initialize Data, and therefore a node in this graphing library can store anything (including another graph). This is probably one of the most important characteristics of Java." - Probably someone before 2004, when Java programmers hadn't yet realized that using the most general type to do anything is a terrible idea
- danieldk 13y agoDeclaring Data as interface{} allows a struct to initialize Data, and therefore a node in this graphing library can store anything (including another graph). This is probably one of the most important characteristics of Go What? The void pointer has been around since at least the seventies. Ok, Go adds introspection by storing the type in a fat pointer. But... and is why it is part of the reason Go cannot be considered object-oriented [5]. A don't see what this has to do with anything. Pre-generics Java, you'd do the same thing by making a field store Object (the superclass of every class). This also provides introspection like Go's interfaces. Then the Java folks concluded that generics are much nicer :). tl;dr This form of genericity is provided by nearly any OO or imperative language. And in fact it points out a shortcoming in Go: it doesn't support parametric polymorphism.
- masklinn 13y ago> tl;dr This form of genericity is provided by nearly any OO or imperative language. And in fact it points out a shortcoming in Go: it doesn't support parametric polymorphism. OTOH the feature demonstrated here is discriminated unions, he's actually storing different types in the two nodes and is correct that most statically-typed languages don't have good ways to nicely handle that case (at least when the typeset is open, many languages handle the closed case nicely[0]). Not that Go handles it nicely of course, as you would in Java you have to use a cast/type assertion at every fetch, and that operation may fail at runtime. So you end up with val = heap.Pop(key).(*MyType) which may fault at runtime much like Java's val = (MyType) heap.pop(key) or val, ok = heap.Pop(key).(*MyType) if !ok { // handle failure } versus try { val = (MyType) heap.pop(key) } except (ClassCastException e) { // handle failure } [0] http://en.wikipedia.org/wiki/Tagged_union http://en.wikipedia.org/wiki/Tagged_union
- jamesaguilar 13y agoVoid* and java's object both support that idiom, at least to the degree to does. Actually, I'm having trouble thinking of a static language that doesn't support it at least as well as go.
- alimoeeny 13y agoBut, this is against the spirit of go, I mean in the sense that go is typed, to avoid exactly this kind of type ambiguity. and that is why you don't have generic functions ...
- codezero 13y agoWhile I think Go is great and interfaces are great, the author didn't mention that you need to include the type as an additional annotation when reading the variable, so this isn't really great. An example from his own github repo: dcurrent = heap.Pop(n).(*D_Node) So if you are using multiple types, you need to keep track of that, or do more boilerplate in a type switch to pull out what you want, or use reflection, so it's really not quite as elegant as it may seem.
- rdtsc 13y agoYeah noticed that too. Was just talking to a co-worker the other day about how static types are sometimes, and they were saying how any sufficiently large code base written by average developers will have more and more things like that (void*) casts and so on. So then type safety kind of goes out of the window. For languages like Go you look at static types from 2 sides - 1) it is there for safety and reliability (so in this case if it couldn't be circumvented it would that way) or 2) it is there to speed things up. Then Go is like a faster Python but casting things left and right erasing types will make the code blow up. So taking the second approach, I don't see it as terribly. But maybe someone coming from Java or Haskell might be really offended by that line of code.
- NateDad 13y agoA minor nitpick - it's still type safe in Go, you can check the type of what's in interface{} and convert the value to that type. You'll never have to worry about getting complete garbage out. However, it's not pretty, and the boxing to and from interface{} is not free.
- ichinaski 13y agoIn order to catch up with language, I also decided to write a Graph library in Go[1]. Since this seems to be a quite common application, is there any more mature, bigger project implementing these same ideas? A similar concept in the Python community is python-graph[2]. [1] https://github.com/ichinaski/grapho https://github.com/ichinaski/grapho [2] https://code.google.com/p/python-graph/ https://code.google.com/p/python-graph/
- masklinn 13y agoThere are dozens (if not dozens of dozens) of graph-manipulation libraries in python, but the most full-featured one is probably networkx.
- Jhsto 13y agoThis is bit nitpicking, but in Go comments are usually done with two slashes followed by a space. See this for example: http://golang.org/src/pkg/bytes/buffer.go http://golang.org/src/pkg/bytes/buffer.go This is good practice in your own packages as well, as online tools such as GoDoc rely that your code is commented right.
- zerr 13y agoI wander why not start a comment text without a function name? i.e. "reads something" instead of "Read reads something". Can't GoDoc easily extract function names from the code?
- peeyek 13y agostarting comment with function name will much easier run `godoc` with `grep` command. $ godoc regexp | grep parse "If all the doc comments in the package began, "This function...", `grep` wouldn't help you remember the name. But because the package starts each doc comment with the name, you'd see something like this, which recalls the word you're looking for." Effective Go - http://golang.org/doc/effective_go.html#commentary http://golang.org/doc/effective_go.html#commentary
- NKCSS 13y agoThe best part of this article is the (single) comment. > Robert Seaton says: March 6, 2014 at 11:13 pm I wanted to comment, but had nothing to say, so I googled computational complexity jokes. Except there are none. So here you have it. The first joke about computational complexity ever written: “Hey, man, is there something wrong with your mom? Because I graphed her weight and she’s growing faster than a busy beaver function.”