8 ms·
Composition. That is the single biggest thing that has impressed me as my codebase has grown. Concurrency and messaging is nice, but I come from Erlang... I a
by MetaCosm 12y ago
Composition. That is the single biggest thing that has impressed me as my codebase has grown. Concurrency and messaging is nice, but I come from Erlang... I am not easily impressed by concurrency and messaging. Composition, the power of interfaces in complex systems is the key for me. It is what makes me stay with Go, and why I will probably stick around for a long time. It is so obnoxiously useful, without ever getting in my way. Let's talk for a second about the tiny little function
io.Copy(dst io.Writer, src io.Reader)
It reads data from reader and writes to writer... simple. Now what makes this little function so darn useful is it takes anything fulfilling its interfaces (io.Writer and io.Reader). The first way you will probably use it will be to copy between some stream and a file without having to eat up all the memory to store the buffer (not using ioutil.ReadAll for example)... but then you realize you can use a gzip compressor on the writer side, or a network socket, or your own code... and io.Copy works with anything that fulfills its interface.
As you build out a complex application, you start by creating your own functions that take advantage of existing interfaces foo.OCR(dst io.Writer, src img.Image). After that you start building out your own interfaces... like a MultiImage interface that has ImageCount and ReadImage methods that returns the count of images and binary data... but then you realize the images could be big, so you make the ReadImage method return an io.Reader... and now you have gone full circle and are using io.Copy to copy imageX from a stack of images to return to your OCR function that will output the data to an io.Writer which you made actually a gzip writer because text compresses well.
Beyond composition -- obviously, the concurrency and messaging is nice and when you need it vital. The other thing that will help make Go "click" is being very "data oriented" in your design... be vicious and minimal: http://youtu.be/rX0ItVEVjHc http://youtu.be/rX0ItVEVjHc (great talk on data oriented design) and be absolutely pragmatic, focus on getting shit done, always...
- coldtea 12y ago>It reads data from reader and writes to writer... simple. Now what makes this little function so darn useful is it takes anything fulfilling its interfaces (io.Writer and io.Reader). The first way you will probably use it will be to copy between some stream and a file without having to eat up all the memory to store the buffer (not using ioutil.ReadAll for example)... but then you realize you can use a gzip compressor on the writer side, or a network socket, or your own code... and io.Copy works with anything that fulfills its interface And how is that any different than any language with interfaces? (Besides the implicit thing?).
- arnehormann 12y agoBecause of the implicit thing! The api designer doesn't have to write the interface, you can do it yourself. As long as naming conventions are kept to and the signature matches, you can apply this anywhere. Imagine a close() interface in Java. There isn't one - but having a try {...} finally { x.close(); } can be very useful sometimes. But having interface graphs made of granular interfaces makes everything slow and causes a lot of complexity when you try to think about your type hierarchy. That's why interfaces always just grow and you can't use them any longer because other classes only implement part of the api. Something usable for all of awt, swing, file handling, random foreign libraries? Unthinkable. Also, adding something in a later release (like CharSequence in 1.4) can have a wide ranging impact and requires you to change a lot of code. In Go, you just add an interface from the union set of multiple structs api - and you can use it. No matter who wrote those structs. The value is enormous. Think of it as something like dependency injection at compile time.
- raverbashing 12y agoLike duck typing?
- killertypo 12y agoI NEED to work Go into one of my projects, but dammit I love Python so much. it is a warm and safe and comfortable cocoon. :)
- MetaCosm 12y agoThen you need to scale and your library isn't actually built in C... or only runs on 2.x (or 3.x) and the cocoon seals up and you can't escape... you scream but no one can hear you... you look for help, desperately clawing at cython, numpy, jython, pypy and C extensions -- they all require you to leave your cocoon far behind... you struggle and break free... suddenly you are exposed to the big wide world outside of your cocoon... you look back and realize the cocoon was just a cleverly disguised prison. /hackernewsstorytime
- killertypo 12y agohahah well I am very comfortable with C and other languages, but I love python for it's versatility and ease of use! It has some very expressive one liners that are surprisingly coherent for being one liners.
- raverbashing 12y agoJust keep in mind Go IS NOT like python, but instead it's a better C I'd say it's a better C, not a better C++ (or Java/C#)
- lucozade 12y agoAs a language maybe but for usage, not so much. For me, most modern uses of C fall into 3 camps: + extreme portability + complete, low level resource control + foundational libraries And Go doesn't really qualify for any of these. For the latter 2 largely because of the GC. I think in practice, that its engineering bent i.e. no frills language and high quality tooling, will more likely see it being used in the server-side application/middleware space. I guess not surprisingly. So it really is up against Java, Python, Ruby and C++ and is, therefore, interesting in that it isn't trying to compete on lingustic goodies.
- stinos 12y agoComposition I read your comment, but this seems more like A sane standard library with proper interfaces and not a language feature per se (also composition to me sounds like the pattern where you create objects which are composed of other objects but that's not what you mean, right)? What you display here can be done in pretty much any language suporting inheritance (or I'm missing something), so your point is those languages don't have io.Copy out of the box?
- MetaCosm 12y agoNo, io.Copy was just the example that everyone would recognize in Go, and likely the first interface you will touch. My point was implicit, exceptional simple interfaces are sorta magic. They are effortless, and because they are implicit, there is no harm in creating a 1 function interface (or 10 of them). Because your caller is never going to have to do an ... Implements ThingA, ThingB, ThingC, ThingD, ThingE, Thi... it implicitly supports an interface if it fulfills the signature. So your interfaces end up being tiny (just what you need) and pervasive. This means the way your system ends up working tends to be far more aligned along interfaces than anything else. When I speak of composition (in this case the composition of functions) I am speaking of the ability to use functions together rather freely and with little effort. This is a bit hard to explain, but it feels a bit like a modern shell, you can wire together lots of commands (functions), from lots of places that have no awareness of each other with the pipe | operator. In Go, simple, minimalistic interfaces act as the glue and let you compose lots of diverse functions together exceptionally quickly.
- Svip 12y agoI think the point here is implicit inheritance. There are many interfaces in Go, but you don't need to specify which interface you are implementing. So you can easily implement io.Reader and io.Writer among many others, without extending your type declaration for lines on end. This means that many standard types in Go implements either io.Reader and/or io.Writer. That's neat. The implicit interface implementation is definitely a language feature, and the libraries are making good use of it. (That is not to say, you could not do the same in other languages, but you would have to specify the interface they implement rather than just adding a method with a specific layout.[0]) [0] I am not remembering the right term right now.
- _pmf_ 12y ago> Now what makes this little function so darn useful is it takes anything fulfilling its interfaces (io.Writer and io.Reader). I've implemented InputStreams from byzantine transport layers in Java that work with the standard library. I don't quite understand what is special about this concept in Go (maybe it's nice for people coming from typeless, messy dynamic languages or nice languages with horribly inflexible and ad-hoc standard libraries like Python and Ruby).
- MetaCosm 12y agoGo has nothing unique (and maybe that makes it special). I mean that sincerely, everything it has, has been done dozens of times. Interfaces in Go are implicit (which is important, IMHO) and really, tremendously simple. These two features make them exceptional easy to use, and ACTUALLY used. I have used interfaces (or equivalent concepts) in dozens of languages and they always felt like far more of a chore, explicitly using X interface or Y interface, ugly complex declarative specs, etc. Go just makes it painless.
- LBarret 12y agoreplace Go with Python in the text, and you won't see a difference: there are iterable, keyable, file-like interfaces, etc. And creating your own is trivial.
- icebraining 12y agoYes, but Python doesn't compile to a single binary, and usually runs much slower. What people like about Go is its mix of features, not some specific one by itself.
- pjmlp 12y agoDepends on the implementation.
- cma 12y agoPython doesn't verify the interface is met until run time.