16 ms·
5 Weeks of Go
- stcredzero 14y agoThe amazing speed of the compiler means the development cycle is a fast as a scripting language even though full optimizations are always switched on. This is a common misconception of those who work mainly in compiled languages. In some dynamic languages, you don't just have the same edit-test-debug cycle. Advanced users of dynamic languages can conduct mini edit-test-debug within all the parts of the larger scale edit-test-debug cycle. Go is not object-oriented. This, in my opinion, is a massive plus for the language....In the real world, things are fuzzy and they spread across multiple conceptual boxes all at once. Is it a circle or an ellipse? Is she an employee or a homeworker? Classifying things into strict type hierarchies, although seductive, is never going to work. Here, the author is simply wrong. This is another common misconception about OO. You don't need strict type hierarchies. You don't even need classes at all for OO. EDIT: Other than that, an overall good review.
- luriel 14y ago> Here, the author is simply wrong. This is another common misconception about OO. You don't need strict type hierarchies. You don't even need classes at all for OO. There are almost an infinite number of definitions of OO, I suspect the author was referring to the generally accepted and most widespread ones, which include classes and inheritance as some of their most fundamental characteristics. Or as Paul Graham put it ( http://harmful.cat-v.org/software/OO_programming/ http://harmful.cat-v.org/software/OO_programming/ ): "The phrase "object-oriented" means a lot of things. Half are obvious, and the other half are mistakes." Go implements (and improves on) the obvious ones (which by the way mostly have been around for longer than the term OO itself), while avoiding the rest.
- stcredzero 14y agoThere are almost an infinite number of definitions of OO, I suspect the author was referring to the generally accepted and most widespread ones, which include classes and inheritance as some of their most fundamental characteristics. Yes, but everyone I know who does real work with Objects knows that the textbook definitions aren't what people do with real systems. That makes it sound like the author only knows the textbook definitions.
- stock_toaster 14y ago> Yes, but everyone I know who does real work with Objects knows that the > textbook definitions aren't what people do with real systems. That > makes it sound like the author only knows the textbook definitions. Phrases like 'who does real work' and 'people do with real systems' makes it sound a bit like a 'no-true-scotsman'. I imagine that was not your intent. Anyway, I think the point is that the common perception of object systems are likely those commonly used in Java, C++, and C#. I say 'likely' simply because I am guessing that those are the more popular by volume of code written. Go has a different approach than those.
- stcredzero 14y ago...real systems' makes it sound a bit like a 'no-true-scotsman' Isn't there a meta-fallacy here? Sometimes there are things that experienced people don't say, but some, like inexperienced undergraduates, do. Anyway, I think the point is that the common perception of object systems are likely those commonly used in Java, C++, and C#. I say 'likely' simply because I am guessing that those are the more popular by volume of code written. Go has a different approach than those. There may be some selection bias here. "Everyone I know who does real work with Objects" is by happenstance mostly working in Smalltalk. The pragmatic approach most people take there involves quite a bit of duck typing. (And lots of grousing about how those interfaces aren't documented.) There's also a lot of bad legacy code that needs a refactoring cluestick there too, tbh.
- iand 14y agoThanks for the comments. I take your point about OO, but I was aiming at producing a broad overview of Go which necessarily means simplifying in some parts. To 90% of developers today brought up on strongly typed languages such as Java and C#, OO means single inheritance type hierarchies.
- stcredzero 14y agoYes, but people are actually targeting single-inheritance as the predominant means of polymorphism? What happened to interfaces? (Plus things like Strategies.) To me your "simplification" is a bit of a straw man.
- kibwen 14y agoI agree with your decision to not label Go as object-oriented; to too many people that term is simply synonymous with inheritance. But rejection of the term itself doesn't mean we should automatically reject the often-related concepts of encapsulation and polymorphism, both of which we can have without inheritance. Specifically, you say this: I can hear the die-hards screaming already about encapsulation, inheritance and polymorphism. It turns out that these things are not as important as we once thought. And then you proceed to give examples that only attempt to refute the usefulness of type hierarchies, without addressing encapsulation and polymorphism. I'd be curious to know what facilities, if any, Go provides for these concepts.
- iand 14y agoGo doesn't support polymorphic methods but supports polymorphic types through interfaces. Encapsulation is through the private/public naming convention I refer to in the blog post.
- stcredzero 14y agoI can hear the die-hards screaming already about encapsulation, inheritance and polymorphism. Any die-hards screaming about all 3 of those should be viewed with a bit of skepticism. When I talked about this a lot, folks were "meh" about inheritance, especially class-based inheritance. The only thing I see as being worthy of die-hard adherence is polymorphism. Encapsulation is there to help enable polymorphism. I'll note that the degree of encapsulation varies amongst systems that call themselves OO.
- reycharles 14y agoI recently read this[1] article. It explains what OOP really is pretty well I think. The article agrees with you about inheritance. [1]: http://www.cs.utexas.edu/~wcook/papers/OOPvsADT/CookOOPvsADT90.pdf http://www.cs.utexas.edu/~wcook/papers/OOPvsADT/CookOOPvsADT...
- timwiseman 14y agoThe word Go is far too overloaded in the English Language, and the difference is not always clear from context. This title could easily have refferred to the correct meaning of 5 weeks with the programming language Go, 5 weeks playing and studying the game Go, or in a slightly colloquial usage, 5 weeks of constantly doing things and going. And those are just the meanings that make sense in this context. It is also a verb with a wide variety of (related) meanings and forms a command part of a command in multiple computer languages (T-SQL uses Go, goto is infamous in Basic, etc).
- spacemanaki 14y agoWhy is it actually called "Go"? The official FAQ just has a snarky response. http://golang.org/doc/go_faq.html#What_is_the_origin_of_the_name http://golang.org/doc/go_faq.html#What_is_the_origin_of_the_... Is it really just short for "Google"? When I searched for "why is golang called go" Google actually suggests I change "golang" to "google" which is kind of funny.
- JaggedJax 14y agoIt would be helpful to everyone if we made it a habit to always refer to the GO language as GoLang (Instead of just sometimes). It's still quick and easy to say while also being much more specific.
- drcube 14y agoYeah, the name is unfortunate. There's actually another programming language called Go! as well. http://en.wikipedia.org/wiki/Go!_%28programming_language%29 http://en.wikipedia.org/wiki/Go!_%28programming_language%29 It's not the only one. Try Googling for "Processing" and getting relevant programming language results.
- ssmall 14y agoWhoa, I didn't know about being able to import packages from a URL. That is pretty slick.
- supersillyus 14y agoIt is quite neat and mighty convenient, but I sorta live in fear that at some arbitrary point the library will change and my code will just stop working. I konw this isn't a problem unique to Go and there are solutions, but the lack of explicit versioning makes me nervous. Then again, it hasn't bit me yet, and I certainly have benefitted from the ease.
- krakensden 14y agoI think it works out pretty well- if you're working on a Very Serious Project(TM), you point it at a URL that's your project's closely managed fork.
- jemeshsu 14y agoOne solution is to add version to url. Some examples from Google API for Golang (http://code.google.com/p/google-api-go-client/ http://code.google.com/p/google-api-go-client/): code.google.com/p/google-api-go-client/tasks/v1 code.google.com/p/google-api-go-client/books/v1
- technomancy 14y agoThis is absolutely the only right way to do this. It's very unsettling that locking to a specific revision isn't considered the default. Depending on git master is cowboy coding at its most cavalier; build systems should prize repeatability above all else.
- drivebyacct2 14y agoThere are a few things that can be done: 1. Hope that the projects you depend on have a tag that you can reference as your import or that you can acquire specifically with `go get` 2. Fork them and keep track of them yourself. 3. Use the tool (I can't find the link) that manages version dependencies per-project so that you can have different versions for different projects based on your needs (think virutalenv).
- drivebyacct2 14y agoYes, Go is different. Yes, the language designers made a lot of decisions that people will complain about [at first]. Yes, I'd [really] love to have generics (even just for simple code repeat cases). But goodness I love writing Go. Sorry, it's hard for me to be terribly specific outside of, for some reason, I'm very productive with it and I love the standard libraries. And where they're lacking Google Code, Github and IRC/play.golang.org make up for it.
- taliesinb 14y agoI agree that it is a pleasure to use. I also suspect that generics will be forthcoming after everyone understands the 'theory of Go' a little bit better. Unfortunately, the standard libraries that I've sampled have felt inconsistent. Two examples I happen to remember: 1. The strconv package has a Atoi (a wrapper around ParseInt) but no Atof -- instead you use ParseFloat directly, and you have to give it as a second argument one of the integer values '32' or '64' to set the precision it parses at (why not use an enum or two funcs?). 2. The bytes package has versions of Index that search for single bytes (IndexByte) as well as byte slices (Index), a nice performance-friendly touch. However Split only has the byte slice version. SplitByte would probably be twice the speed. If you are going to write a package to stand the test of time, be consistent. (edit: I got Atoi the wrong way round)
- supersillyus 14y agoFor what it's worth, I've looked into the 'Split' case, and the performance difference when specialized to the single-byte case is about 2%, which is mostly because Split already has built-in specialization for the single-byte case, which amounts to a couple extra instructions in a function whose running time is dominated by allocation. I think they made the right choice there; the Go team seems very good about optimizing only where it matters; there's lots of low hanging fruit, but the majority of it isn't very useful fruit.
- taliesinb 14y agoJust for fun, I just looked into it too. Which factor dominates depends on the kinds of strings; for large strings, extra instructions in the loop matter very much. I'm processing very large strings. I did 128 runs on a byte array of length 2^24. It has delimiters placed at positions {2^i, i < 24}. I tested my implementation against both the "bytes" package implementation, and a copy of the relevant portions of the "bytes" package (to account for any odd effects of inlining and separate compilation). I did the set of timings twice in case there was any GC. Here's the wall time in milliseconds for the three implementations, on a 2010 Macbook Air. mine 3313 copy 4709 bytes 5689 mine 3327 copy 4660 bytes 5660 My single-byte implementation is about 40% faster than the local version, and 70% faster than the "bytes" version. Not quite twice, but I wasn't far off. But aside from performance, there is just consistency of interface. Once you've established a 'Byte' variant of some functions, you should do it for all the common functions.
- taliesinb 14y agoI've been using Go for a performance-critical part of a production system and I've been thoroughly enjoying it. But certain things have been odd and frustrating. One trait that I find frustrating is how pedantic Go is about types. For example, if I have a float x and an int y, I can't write x / y, I have to write x / float64(y)†. The intent is to force awareness of type conversions that introduce subtle gotchas, but I don't see how it applies to the case float / int. A better example of the same phenomenon is that alias-style types need to be explicitly cast to their aliased types, which introduces pointless noise into what would otherwise be a nice way of 'marking up' the semantic role of variables and arguments (think type index uint). †Notice there is a common-or-garden 'int' but no common-or-garden 'float', apparently because one should always be aware of precision. Unfortunately, because of the alias type issue I mention above, 'type float float64' doesn't help.
- ori_b 14y ago> but I don't see how it applies to the case float / int Does the int get converted to a float for this calculation? is sizeof(int) == sizeof(float)? Then you can lose accuracy in the conversion; MAX_INT is larger than the largest same-sized float that can be represented without rounding error.
- taliesinb 14y agoFair point, although for the garden-variety int (int32) and float64, this isn't the case. In an ideal world, the compiler would be smart enough to know this, and complain appropriately.
- kibwen 14y ago"Names imported from a package are accessed by using the last component of the package name as a prefix (rather than the horrendous full package prefix that you often see in Java and similar languages)" import "image/color" x := color.RGBA{255, 255, 255, 0} Perhaps I'm naive, but I thought you could do this in basically any language, including Java (it's been a while). EDIT: Not sure why this was downvoted, but it's a trivial Google search[1] to show that this is indeed something that you can do in Java: import javax.swing.JOptionPane; class ImportTest { public static void main(String[] args) { JOptionPane.showMessageDialog(null, "Hi"); System.exit(0); } } Which, without the import, would force you to use the full name as the author alludes: class ImportTest { public static void main(String[] args) { javax.swing.JOptionPane.showMessageDialog(null, "Hi"); System.exit(0); } } I'm not intending to bash Go (it has the largest quantity of awesome features of any language I've seen in a long time), nor necessarily to defend Java. It just seems a bit disingenuous to claim that this is exceptional behavior. [1] http://www.leepoint.net/notes-java/language/10basics/import.html http://www.leepoint.net/notes-java/language/10basics/import....
- iand 14y agoThe difference is that javax.swing.JOptionPane is a class whereas image/color is a package containing functions and types. x := color.RGBA{255, 255, 255, 0} is instantiating an RGBA type from the image/color package
- yummyfajitas 14y agoIn Java: import org.somelib.colors.* x = new RGBA(255, 255, 255, 0); where RGBA is some class defined in the org.somelib.colors package.
- ssmoot 14y agoI think they're looking for: import org.somelib.* x = new colors.RGBA(255, 255, 255, 0); So you don't have to bring all the classes into scope, but you don't have to write out the full path to use them either. Just the last bit of the package-name as a qualifier.
- exim 14y agoCould someone point out, what is the reasoning of putting types after variable names? i.e. why not `int i` instead of `var i int` ?
- drivebyacct2 14y agoThis is mentioned somewhere but it removes the ambiguity and bugs that can be introduced by pointer types. Consider: int* i, j (or rather int *i, j)
- to3m 14y agoWell, there's no ambiguity in this case, because "int" is a keyword, known to the compiler, and will always be interpreted as a type. But if you had something like "x*y,z", then the meaning of this would depend on whether x is a type or not.
- singular 14y agoI think this is more in reference to the common C error of:- int* x, y; when you meant to declare both x and y as int pointers, here only x will be a pointer and y will be a straight int. Obviously the go designers could have chosen to simply make this mean that both x and y are pointers, however this would be somewhat confusing for those familiar with C. As iand says, there is a rather good article on this which goes into a lot more detail - http://golang.org/doc/articles/gos_declaration_syntax.html http://golang.org/doc/articles/gos_declaration_syntax.html
- deleted 14y ago[deleted]
- iand 14y agoSee http://golang.org/doc/articles/gos_declaration_syntax.html http://golang.org/doc/articles/gos_declaration_syntax.html
- qznc 14y agoIt is more readable, if have multiple declarations, since the names are aligned instead of the types. var x int var foo map[string]int var dummy []int compared to var int x var map[string] int foo var []int dummy
- taliesinb 14y agoThe tools are also really nice. "go build", "go run", "go get", etc. Building dependency management and build management built into the language - even if it is not super sophisticated yet - is a great idea.
- nextparadigms 14y agoSo, any chance we'll see Android using Go anytime soon?
- rogerbinns 14y agoYou can run shared libraries on Android very easily. The shared libraries can do OpenGL (video) and OpenSL (sound), plus most regular libc stuff. Most of the Android APIs are exposed as Java and you can use JNI to call into the shared library (ultimately it is C). As far as I can tell you can't generate a shared library from Go so this "normal" approach is off the cards. (There are also issues like how the Dalvik garbage collector and Go GC would interact.) To have a pure binary would effectively require a reimplementation of the framework of Dalvik and all the various classes/methods and would be a huge undertaking. It would be extremely unlikely to install on existing Android versions and would only be in a future version. Or in other words it would be many many years before you could depend on it being on Android devices even if this was done for the next Android version. The shared library thing is the biggest problem though. Android applications are really mashups of components from the same app or others (see Activities, Services, Content Providers, Receivers). There isn't actually a main() method or equivalent. Instead the components are loaded and called as needed.
- rogerbinns 14y agoI'd be interested in hearing more about the exceptions side. The usual derision is that some top level unrelated code ends up handling them, but that seems silly. A far more normal example would be a routine that has to get some resources and calls various retrieval routines which may end up accessing the filesystem, databases, or the network. Those routines could go several calls deep before throwing an exception. The top routine can then find alternatives, use cached versions, return an error etc. I do like exceptions in Python where their use is ubiquitous and there is garbage collection. I detest checked exceptions in Java because you are forced to handle things at a level you often don't want to. I'm 65% certain Go made a mistake not using exceptions, but would love to hear from others.
- zmj 14y agoGo uses the Error type and multiple returns in the scenario you describe. Code might be something like this: foo, err := GetDataFromDatabase() if err != nil { foo, err = GetDataFromLocalFilesystem() } if err != nil { foo, err = GetDataFromNetworkFilesystem() } return foo, err There is an exception-like mechanism called 'panic', but it shouldn't be used as a control flow tool. Panic is reserved for unrecoverable errors, not mundane situations like a failed query.
- stickfigure 14y agoThis seems extraordinarily painful. I usually have five or six stack frames between GetDataFromDatabase() and code that can raise error dialog to user or return HTTP error code. This means every single one of those stack frames are going to duplicate this annoying if err != null sequence. The article author is quite wrong when he says "exceptions are broken by design because they force errors to be handled at points far away from the cause". Exceptions don't force you to handle errors at any particular location; they allow you to handle errors anywhere in the stack. On the other hand, return values do force you to handle errors then-and-there, which 90% of the time is a half-dozen stack frames away from your handler.
- iand 14y ago
- ssmoot 14y agoThis is a stupid question, but it's beyond difficult to search for an answer (I've really tried!): Can I import Java libraries into Go? If I can't find a Go library to do what I need, what are my options besides messaging to another process, or (presumably) finding a equivalent C library (I don't trust my C skills enough to make wrapping something a confidence inspiring no-brainer). Is there general language/library interop details out there any golangers could point me towards?
- koenigdavidmj 14y agoSwig (http://www.swig.org/ http://www.swig.org/) can take C++ libraries and let them be accessed from Go.
- jbarham 14y ago> Can I import Java libraries into Go? No. Go compiles to machine code, not the JVM. Go's built in cgo tool makes it very easy to wrap C code. See http://golang.org/doc/articles/c_go_cgo.html http://golang.org/doc/articles/c_go_cgo.html. Crucially, you can write most of the wrapper in pure Go and the C boilerplate code is generated automatically.
- tinyjoe 14y agothe only thing i'm looking forward in Go is inheritance
- gringomorcego 14y agoI don't get why the compiler speed is such a big deal. http://en.wikipedia.org/wiki/Incremental_compiler http://en.wikipedia.org/wiki/Incremental_compiler
- JadeNB 14y agoI don't understand this sentence: > Enforcing a brace placement style and other conventions means the compiler can be super fast. Surely the lexical-analysis phase is not the bottleneck in compilation? (The context strongly suggests that 'other conventions' means 'other lexical conventions'.)