I've been learning and trying out both Clojure and Go recently. While they clearly take very different approaches on many issues, I think they also have a surprising amount in common in their core philosophies. They both focus strongly on simplicity, removing boilerplate, performant and minimalist core data structures, and providing clean abstractions for parallelism.
The split in how each goes about targeting 'simplicity' is quite interesting, and seems close to the heart of each language. In Go, simple seems to mean: obvious, intuitive, unclever, and familiar. Clojure's conception is much headier: simplicity isn't accomplished through familiarity and comfort, but through the power and flexibility to create appropriate abstractions, and the discipline to avoid dangerous ones. The most immediate consequence, for a newbie, is that Go feels a lot easier to learn, while Clojure is more mind-expanding and abstract. In Go, simplicity is easy. In Clojure, the simplicity is deeper and perhaps more theoretically pure, but reaching it can be quite a challenge.
My preliminary feeling so far is that each feels like a very clean, modern language and is basically superior to other languages I've used (Ruby, Python, C, js) by every important metric except maturity of community and libraries, and each will have its place. Go's lack of cleverness probably makes it ideal for more run-of-the-mill systems with a lot of straightforward io, where organization, maintainability, and baseline performance are more important than development of powerful algorithms, while Clojure will be a better fit when cleverness is desired either to solve difficult problems or for rapid feature development (a la pg's Beating The Averages). I could also see them potentially working quite well in tandem for a system that spans both those categories.
One more thought: as much as I like Clojure and understand the pragmatism of targeting the jvm, Go's ultra-simple, ultra-fast runtime, along with libraries and a community that embody a similar spirit, really is such a breath of fresh air compared to the jvm world and even the ruby/python worlds. In this realm I think Go beats Clojure at its own game. Thanks to the more 'difficult' choice of starting a fresh platform rather than leveraging an existing one, Go's whole ecosystem and development experience now share a unifying philosophy, and every aspect of working with Go is suffused with what makes Go great.
gcj (GNU Compiler for Java) can compile JVM class files to machine code.
Technically, the JVM also compiles your Clojure to the native instruction set, via JIT; but I don't think a JIT compiler performs the same level of optimizations (due to time constraints) as a say "gcc -O3".
I am / We are considering using Go, but I'm a bit reticent about its maturity compared to Erlang, which is a very, very solid system. The 32 garbage collection issue is a big question. Arm support is another. Also, all the extras Erlang gives you in terms of writing robust systems look pretty attractive.
That said, I'm about 99% that Erlang will always remain a niche player, along the lines of Smalltalk and Lisp, whereas Go has a shot at 'the big time'. That's something to keep in mind in terms of hiring people and getting other people up to speed on the language. Go is something that other people will look at and 'get' a bit quicker than Erlang.
Go and Erlang have some differences, and I found particularly interesting that pretty much all the issues they have with Erlang don't apply to Go often because of how Go avoided what might seem superficially like a 'feature' in favor of "raw" simplicity.
That said, Erlang probably would be my second choice after Go if I had to build a highly concurrent distributed system, just realize that things are not as rosy as they seem.
BTW, to address your other comments: all the remaining 32bit GC issues should be solved in the upcoming Go 1.1 release (still you will always be much better off using the 64bit port), and the ARM port is in pretty good shape.
> Go and Erlang have some differences, and I found particularly interesting that pretty much all the issues they have with Erlang don't apply to Go often because of how Go avoided what might seem superficially like a 'feature' in favor of "raw" simplicity.
Some of what they discuss simply isn't available in Go, like OTP, so I wouldn't count that as a "win" for Go. Other things like 'heart' are things I want, given that it's going to be for a semi-embedded system.
That's a good video, but all languages have gotchas and things to watch out for, especially mature ones. Go has some advantages in a 'fresh start': some of the biggest Erlang warts are actually the language itself; the syntax, records, some things like that that are just kind of ugly.
For a product currently in development, "should be solved by a future release" is probably too far in the future to matter much. "pretty good shape" sounds a bit worrisome for a semi-embedded device where updates via the internet are not necessarily going to be an easy proposition. 64bit is going to eat more memory, something we'd prefer to avoid if at all possible.
You should really take a look at Scala too. It's actor implementation is inspired by Erlang and very elegant. Plus you've got the whole Java ecosystem so it doesn't really matter if Scala doesn't become (more) mainstream.
"Now that Google has released a stable version, and is deploying support on Google App Engine, it's likely to gain even more traction."
I think what Go actually needs is another popular framework so that the language can be used without depending on Google's App Engine and it's unstable pricing.
The great thing about Go as a web language is that alot of the bones are already there - templates and HTTP handling are already waiting for you in the standard library.
The most popular web frameworks i've seen for Go so far are Web.go (a Web.py clone) and Revel (a Play clone). Frameworks will develop organically over time. The only reason they're not very strong at this stage is because as I said; most of the batteries you need for web development are already included in the standard library.
> The most popular web frameworks i've seen for Go so far are Web.go (a Web.py clone) and Revel (a Play clone).
Unfortunately both web.go and specially Revel were developed by people that were not (yet?) familiar with Go's style, and they simply cloned what they expected from other languages and frameworks they were more familiar with.
Gorilla[1] and pat[2] (by the creator of Sinatra, who is now a Gopher) fit much more with the Go style and philosophy.
App Engine pricing stayed the same for years, then made a big shift as it officially came out of preview. Yes, it was a big change, but it's only happened once.
I'm a novice developer using App Engine and while there are things you can criticize about it (including the cost), "unstable pricing" isn't one.
I don't dislike App Engine. I just don't want to depend on it.
I don't like the idea that I am practically forced to use App Engine if I choose to use Go, since there aren't any viable alternatives as far as I can see. We need the "Django" of Go.
I recall hearing about Don Syme (F#'s creator) talking with the guys working on garbage collection in .NET and when they saw his allocation numbers, they pretty much said that "this much allocation means there's a bug in the program". Different languages with different paradigms and idioms call for different collection strategy; being extremely into the imperative camp, Go programmers tend to hammer away at data structures rather than copy then like is more common in Java (and even more common in functional languages). So I guess that a less polished GC will do an okay job for Go longer than it would for Java.
Do you have a source for that? I could see a purely functional language creating much less garbage than Java and/or providing much easier escape analysis scenarios, leading to better performance, but I'd be very surprised to see them perform better for similar amounts of heap allocation, given all the work that went into the various Java GC algorithms. I mean, those LISP GCs probably predate wide adoption of threading, right?
The JVM has several swappable GCs, both mature and new. There is plenty of documentation out there about them.
Go has (had?) libgc and is going to get a slightly better GC. I believe it's not even generational. Again, there are plenty of articles about that, especially about the recent and prominent bug on 32bit platforms.
First of all; Go is compiled to binary form, it doesn't run on a VM (yet?).
Second of all; the words you're looking for are "get" and "For", not "gets" and "Fore". Sorry to be a grammar nazi, but I'm just calling it as I see it, and this isn't Reddit or 4chan (yet?).
For others wanting to know more about Go's garbage collection, it used a conservative GC up until recently, but heaps of work has been done to make the GC precise, so we don't get leaks on 32-bit platforms. As far as I know this GC change has yet to be released (current release is 1.0.2, and the changes should be in the next release).
That said, if you clone tip and build from there (it's remarkably stable) you should be able to see the differences.
For some people, VM means everything that the language offers to the programmer at runtime. Sometimes libraries, usually GC. Even malloc could be considered VM.
I don't like that Go has builtin generic collections, but doesn't allow programmers to build their own. It feels more like some corporate/"4GL" programming language than a hacker's/"real" programmer's one. Maybe lack of generics is not so important, but it shows designer's attitude towards language users.
This issue has been addressed in the FAQ. They say generics might get added at some point, but they don't want to rush it. C# 1.0 didn't have generics either.
http://golang.org/doc/go_faq.html#generics
I meant that if they use generics in some built-in classes, they should also give that possibility to users. If they cannot give it to users, they shouldn't use it in built-in classes. It feels like they think users are too dumb to implement their own, so they give some created by them.
Maybe they are afraid of introducing some features they would later regret. This is not a hobby project of some lone hacker, it's meant to compile Google's infrastructure.
I really don't see why user code has to have the same capabilities as the runtime. It looks more like a philosophical request than a practical one.
Should all languages also allow users to define flow control structures?
Yes, some languages do this, but there is (as almost always) a trade of between simplicity and flexibility.
I think Go strikes a very nice spot there.
In go the built in datastructures are very carefully selected, and are extremely useful, while when you need to build your own datastructures is both simple and powerful (you have direct control over memory layout), you just can't build magically generic datastructures, but that always comes at a cost, and Go's interfaces also provides ways to write generic code that are quite powerful.
I'd argue that C# didn't become an interesting and enjoyable language until it gained generics.
Generics certainly aren't essential to a language, but once you're used to them it does feel a touch chafing not to have them, as well as it feel a touch strange for them not to be included in a new, statically typed, language. My opinion naturally...
It's seems like there's been a lot of posts about Go lately. Maybe I'm delusional..
I find Go to be nice to work with. I'm just starting out in it so I'm not exactly proficient yet, but it feels a lot easier to program with against say, Java.
In regards to the GC. I saw a post a little while ago made by Rob Pike, I think (could be wrong) about how there are many improvements coming where they see 50% speed ups (sometimes even more). So, as young language I think Go has come pretty far and more is to come.
I wish that the articles submitted about Go were recent, rather than several months old. Go may be stable, but the culture and community are still changing rapidly.
I'd also like to point out that the article contains virtually no information about Go, instead relying on speculation and some hacked up quotes from people who've used it (and one from Rob Pike).
And, apparently, a few people are now pissed that every post isn't about Node.js or Ruby anymore, because I have come across a small group of people that come into every Go thread and spread the same FUD about garbage collection, performance, maturity, and generics.
Means it has hit a level of success then, remember when every thread about Ruby would degenerate into "YEAH! But RoR doesn't SCALE! HAH!"? Level of snark seems proportional to the level of success a language is enjoying.
I must admit, I've not tried Go yet and I'm not overly sold on some of the syntax aspects but it's nice to see a new language doing well against established players.
i've not had a ton of experience with Go, just some coder challenge type stuff, but i love almost everything about the language. it has the feel of old skool C, but greatly improved and upgraded.
the one thing i hate about Go is how it does exported identifiers. in order to make a variable/method available to other packages, you must start the variable name with an uppercase letter. this is the only way to export identifiers which means the exporting is a bit obfuscated.
giving meaning to the first letter of a variable name is filled with potential problems:
1. people will inadvertently export properties simply because they chose to name them with uppercases
2. in some cases, you will need to force this case sensitive language to be case insensitive. ex: a json property named "address" needs to unmarshal into a Go variable named "Address"
3. i don't have this concern personally, but i wonder about coding in languages that don't have uppercases. (actually, it's prolly legit to force them to code in english i suppose)
i've read the Go engineers are extremely happy with this feature, so i guess i'm going to have to get used to it and the bevy of problems it creates if i'm going to continue using it.
Of course, just because this kind of thing can be handled with tags doesn't mean that people will actually know to use them or actually use them correctly.
thanks for that! i wasn't even aware of field tags.
i can see this solution causing other problems too. there can only be one tag per field, right? what happens when another library has a different meaning for the tag?
are we going to see a hacky standard emerge where we have multiple tags in the one field separated by semicolons (with a precursor for each tag like 'json:')?
it feels like an ugly hack to use tags this way, but i guess an ugly hack is what is needed for this right now.
i would much prefer a separate keyword to explicitly export fields. or, since we are already hacking the tag, why not have the compiler export any field with a tag called "export"?
Just out of curiosity, is anyone using Vala? I was asked to do a little bit of research into alternatives to build a cross-platform chat client and, along with the more obvious Java, C++/wx, Objective-C/OSX/GNUStep and C#/.NET/Mono stacks, I found Vala as a possible option.
I think I understand where the Go team is coming from, but there is so much hype from other quarters that I think is at best premature.
I think Go will be a fantastic alternative to C for "systems" programming, once it matures. I think this was one of its most immediate original goals, but really it is not yet ready to do even that. Two main reasons it is not ready for that is that performance is not yet there though I think it will get there; second reason is that it has no support for dynamic linking or code loading. You can't write something like Apache, or even Nagios in a platform that has no support for loadable modules. Still I think there are LOTS of applications where these constraints would not be an issue.
So then we have all this hype and people doing things like building web applications in Go and calling it the next Node.js or Ruby or Python and frankly this is just stupid. Despite some claims it has nowhere near the expressive power of those languages. It is statically typed but has no Generics - and there are quite a few use cases where there is no answer(https://groups.google.com/forum/#!topic/golang-nuts/PYJayE50...) and you will just have duplicate code.
It polymorphism but no inheritance - and the way interfaces and composition works while still fairly powerful is not at all what an OO programmer would expect(http://xampl.com/so/category/software/golang/) just naively reading about this feature. Whatever you want to say about the benefits of simplicity, this is LESS powerful than any OO dynamic language. Go's closures are nice, but aside from that on what basis can any other claims be made about its expressive power?
In fact, the language is intentionally very, very limited. They want large teams of mediocre programmers [1] to produce code that is very supportable. Everytime someone in the lists brings up a "why don't we have" question all the answers revolve around this premise, that the language becomes "too complicated" if you have crazy features like generics. So it seems Go is optimized to satisfy the angst of systems programmers who have to work on C code that is thirty years old and been maintained by dozens of people. I get it, but that doesn't mean its really a good language for hackers to use to build the latest social network for people who like cats.
Ok so concurrency. Yes Goroutines are smart. Channels are smart. These are great features. Scala can do the same thing (and more elegantly) with it's Actor constructs. The same thing can probably be done in other languages such as Ruby (https://github.com/igrigorik/agent). Its nice that this feature is in Go from the beginning, but its going to make its way into other platforms as well.
Performance. Well...lots of blog articles just keep repeating the mantra of "native code" as though it automatically means something. It doesn't. C isn't just fast because it generates native code, it is fast because it's compiler has been optimized for decades. Go doesn't have that today. In fact today, Go is slower than Java and Scala based on both Google's benchmarks (http://www.readwriteweb.com/hack/2011/06/cpp-go-java-scala-p...) and the language shootout (http://shootout.alioth.debian.org/u32/which-programming-lang...). Go will get there almost certainly, or at least very close, but it isn't there today.
Today if you want a static, fast language with good concurrency and an incredible standard library and extended library ecosystem then you want Scala I think. If you want a powerful, expressive language for quickly building web applications then you want Python, Ruby[2] or Node.js or similar. If you want a language is actually very fast and with incredible libraries you want C/C++.
I really do not hate Go. But it is not yet ready to replace hardly anything in my opinion.
edit:
[1]You are right. The "mediocre programmer" comment is really out of line and a major distraction. I guess I actually think this IS a feature of Go: more maintainable code than C/C++ from mediocre developers. I'm bitter and tired ofdebugging twenty-year old C programs and I wish they were all written in Go. I shouldn't read that into Thompson's or Pike's intentions though.
[2]May brain stopped working here - I meant Ruby not Java.
"They want large teams of mediocre programmers to produce code that is very supportable."
I think any argument that uses the phrase 'mediocre programmers' should set off alarm bells by now. Its critique by slander. The creators of the language (who are not mediocre) like simple languages. The desire to make things more transparent and simple is does not reflect on a person's capacity it reflects on their taste (insert Einstein quote, St Exupery etc). Ken Thomson is not an idiot for example but:
"Computer: Your nominators and endorsers for the Kanai Award consistently characterized your work as simple yet powerful. How do you discover such powerful abstractions?
Ken Thompson: It is the way I think. I am a very bottom-up thinker. If you give me the right kind of Tinker Toys, I can imagine the building. I can sit there and see primitives and recognize their power to build structures a half mile high, if only I had just one more to make it functionally complete. I can see those kinds of things.
The converse is true, too, I think. I can't from the building imagine the Tinker Toys. When I see a top-down description of a system or language that has infinite libraries described by layers and layers, all I just see is a morass. I can't get a feel for it. I can't understand how the pieces fit; I can't understand something presented to me that's very complex. Maybe I do what I do because if I built anything more complicated, I couldn't understand it. I really must break it down into little pieces."
Is he an idiot because he couldn't understand it? Or they giving awards to the wrong people? Could it be that to recognise everybodies limitations when working with code day in day out (not just the mediocre people) is actually a valuable insight?
Also this quote explains the design of Go (even thou he said it in the context of Plan9/Inferno)[1]
"Thompson. The aggressive use of a small number of abstractions is, I think, the direct result of a very small number of people who interact closely during the implementation. It's not a committee where everyone is trying to introduce their favorite thing. Essentially, if you have a technical argument or question, you have to sway two or three other people who are very savvy. They know what is going on, and you can't put anything over on them."
Rob Pike says the same thing. "All three of us need to be convinced for a feature to make it into the language"
You are right, Rob Pike said it was for "large teams". In most places (maybe not Google) "large team" will often mean an average skill level that is mediocre. I do not understand why a large team of very skilled programmers can't build large systems that are very maintainable in more powerful and expressive languages. I do not understand the argument that a language is "too complex" in this context.
edit: You are right and I added this to my top-level comment. The "mediocre programmer" comment is really out of line and a major distraction. I guess I actually think this IS a feature of Go: more maintainable code than C/C++ from mediocre developers. I'm bitter and tired ofdebugging twenty-year old C programs and I wish they were all written in Go. I shouldn't read that into Thompson's or Pike's intentions though.
Whenever I hear someone denigrate simplicity in a language as something that caters to 'mediocre' or 'average' programmers, I'm reminded of the surveys where 80% of people think they're an above average driver.
>The creators of the language (who are not mediocre) like simple languages.
They are surely not mediocre programmers (or mediocre contributors to computing).
They are however mediocre in their modern language design skills. What are their language credentials?
Lars Bak is a compiler/language guy. Wirth was a compiler/language guy.
Hejlsberg is a compiler/language guy.
The Go guys? Not so much.
Having designed the best systems language 40 years ago is not a sure sign that you can also design a good systems (or not) language 40 years later. Compiler design has changed a lot since then, but it's not like Go has a lot to show for it (ok, they also wrote 1-2 other ho-hum languages, like the Plan9 one).
Plus, beside the language specs, there is also the compiler. Did those guys ever wrote a top-notch compiler? The original C compiler wasn't the state of the art in the language. It took lots of efforts and different companies to get to the advanced optimized C compilers we have today.
Plan 9 was far more impressive a feat than Go was, and much closer to where the team's skills are.
Fair points but I wrote the response above saying that its not really about ability, its about taste. Neverthelesss I had to assert something about the Go language designer's ability in order to refute the top post about mediocrity. Now you are back to talking about ability and credentials. We could go back and forth all day. The point is that Go is the first mainstream systems language to focus on leaving stuff out. Think about lisp, its beautiful because its really just one thing but you can do everything with that one thing. Go is not the same but the aesthetic is similar. It's a question of taste. Do you like a powerful tool with loads of abstractions? Or do you like to strip everything down to the metal and see what is the minimum you can run with and still retain most of the fire? Some of those things that you leave out may turn out to be those things that have come out of "modern language design".
Scala has many modern language features yet Martin Odersky said, of Go "I like a lot of the design decisions they made in the language. Basically, I like all of them." He can appreciate it because there is also an aesthetic in Scala that focuses on a minimal, simple, consistent core. But Scala has a shell with a bigger surface area. Depending on the context and the kind of person you are you might want one or the other but there is no point in criticising Go by saying "Its missing feature X". That's like criticising a race car because it doesn't have a sat nav. It still does 80% of what a normal car does but it does the core things that a car does really well and its not just that you have less weight its also that you can focus on driving it because there is less to distract you. (Where driving == building cool stuff faster because I'm not constantly getting distracted by thinking about how to make the code more clever ('Hmm maybe I could metaprogram that and save another three lines')). In general the simpler car is also easier to fix and easier to understand (these attributes are more important in programming languages than in cars, no matter what the ability of the programmers (cognitive load)). Of course there is an argument for having a sat nav in other contexts.
There are some rather clever solutions to this problem that don't require the complications inherent in dynamically linked binaries.
It's easy to forget that, even on commodity hardware, Go (`gc`) compiles "Fast (tm)." -- Even for large projects.
Take a look at the Revel framework[1], it's a young project but it aimed to port the Play framework to Go.
Once you dig into the code, you can see the framework hot-loads your web-app by altering the source code of the framework (to add imports for your app) and then recompiling on the fly.
The framework can then do all sorts of things; one that I like in particular is that it seems to be able to catch panics at the top-level, and relay a nice stack-dump to the browser (in debug mode).
All the while you still have a statically linked binary running.
---
tl;dr: There are other solutions to the problems dynamic linking solves, without actually using dynamic linking [2].
The lack of generics makes Go unsuitable to write typesafe, reusable data structures for use in many popular algorithms. That's a fact.
Yes you can hamfist your way around interfaces and empty interfaces, but it's a complete and utter chore and requires a lot of code duplication for each individual type you want.
I like Go in the sense that you can write things quickly and cleanly, but for the use case above, it's not appropriate.
Yes well, I was writing a comment that was already too long. Lots of comments could be better supported. I suppose I could develop this into an original piece with lots of code examples. I guess if I don't do that, I can't write any comments?
You should have picked one point you wished to make and argued it. For instance "Scala can do the same thing (and more elegantly)" could have been demonstrated with a couple of examples. I have not used Scala, but I would be interested to see examples of language-level concurrency other than Go.
First, you're saying Go will be an excellent systems programming language, which is its main stated purpose. To me, it already means that it's something that's worth looking at.
Then, you claim it doesn't work like established alternatives, so it must be over hyped. Like anything new, it's normal to see hype, misinformed opinions, advertising and enthusiasm about it.
I haven't written a line of Go, but it's going to be the next programming language that I learn because I find its concurrency model very compelling.
>you're saying Go will be an excellent systems programming language, which is its main stated purpose
It will be, when it is finished. Without dynamic linking it cannot replace C/C++ for lots of the intended use cases.
>Then, you claim it doesn't work like established alternatives, so it must be over hyped.
No, I claim that it lacks most useful features of the powerful languages it is constantly being compared with. Rob Pike says you don't give up much expressiveness moving from Python/Ruby to Go. This is absurd. Go has a different way of doing things yes, but for many things, that different way is to write more code.
I think in real usage (in my experience), this is very rarely the case. The only thing Generics are really extremely useful for is writing data structures that you can re-use with multiple data types.
Also, I tend to appreciate Go's approach of writing more code in these situations, because in general the code is still far more readable than a C++ Template (for example).
The Go creators have not ruled out adding Generics, they are simply being very careful about how they implement it. I would rather have this situation than something like a generic Java/C#/C++ style generics implementation rammed in because it is demanded by people who have hardly touched the language (or refuse to touch it until said feature is added).
"I think in real usage (in my experience), this is very rarely the case. The only thing Generics are really extremely useful for is writing data structures that you can re-use with multiple data types"
When working in .NET on framework-y code I use generics with reflection a lot because it makes it easy to remove a whole swathe of repetitive code. Mapping from one object to another using a Mapper<TFrom, TTo> with generic constraints, reflection and some over-ridable conventions springs to mind.
Not an argument for adding generics in Go, or against Go itself as I haven't yet found the time to play with it. However I do think generics can be more useful than people give them credit for.
The thing is that Go has generics already for the most common data types: slices (vectors, what Python calls 'lists', others call them 'arrays'), channels (iterators, generators), and maps (dictionaries, hashes). Since there's already a built-in map[T1] T2, so you wouldn't need to build it yourself, which saves even more work.
If what it has are a handful of special cases baked into the language, saying the language supports it is probably overselling (similarly, having types like `float[3]' doesn't mean we consider C as supporting dependent types).
"The only thing Generics are really extremely useful for is writing data structures that you can re-use with multiple data types." Take a look at C++'s STL: a large set of generic algorithms that work with any data structure (built-in or user-written) supporting the standard iterator protocols. Many people think of STL as "a bunch of container classes", and ignore the algorithms.
... it cannot replace C/C++ for lots of the intended use cases
Does Go need to replace C/C++ in all use cases to be a "worthwhile" language? If not, then is there some required percentage of use cases that Go must be better at than C/C++? If not, then what is the point in arguing that there are some things Go is not as good for? Of course, knowing what those deficiencies are is important but it sounds like you are trying to convince people to not use Go. Why?
Yes there is a lot of Go hype around here and I understand your desire to counter that hype.
Choosing programming languages and other technologies and skills is an unfortunately subjective and messy process.
Loadable modules like the way Apache/nginx do, or Nagios or quite a few other basic infrastructure applications.
Another related issue (though not specifically dynamic linking) is with client libraries for server software. For example say you wrote something like Redis in Go. You write a Go client, then you want to start porting client libraries. You will be starting over from scratch because you can't expose your Go code through any kind of native interface. If you write client libraries in C it is pretty easy to create language bindings in all other popular languages. So if I wrote a server in Go that I wanted to distribute widely, I think I'd have to write the reference client in C.
> Loadable modules like the way Apache/nginx do, or
> Nagios or quite a few other basic infrastructure
> applications.
I agree this style of composition is not currently possible in Go, but I do not agree that it is necessarily a good (in the engineering sense) solution to the requirement(s) it solves. There are lots of other ways to communicate between dynamically dispatched blocks of code, and dynamic code loading is by any account fragile.
Or, to put it another way,
> you can't expose your Go code through any kind of
> native interface
I'm not convinced this restriction is anything but good.
But, as Go advocates will tell you any Generics related discussion in the golang list: "just try programming in Go for a while and you'll find you don't need Generics".
Why do they assume that people complaining haven't used the language "enough", is beyond me.
Plus it seems they believe that there is some amount of time of using a language, after which fundamental issues and well understood design issues disappear...
But, by that logic, why abandon C in the first place?
"Just use C long enough, and you'll find out you don't need garbage collection, built-in collections, closures and memory safety".
Or:
"Just use assembly long enough, and you'll find out you don't need all those fancy functions, and variables, and looping constructs, and stuff".
Yes exactly. Although I think with Generics they will probably come around at some point. If you read the link I posted they do recognized there are unsolved cases without Generics and while some people DO say "just rewrite your collections over and over when you can't use maps/slices", others recognize that this will lead to redundant code which is not something you want in a language touted for its maintainability.
Other problems though such as default function parameters are less likely to be addressed (it seems to me). This is a problem because it means lots of code will be written in which there are implicit defaults (just pass 0!) that are not well-understood or guaranteed by the interface. The answer there is "just write another method with a different name and parameters". Ok so now I have to think of sensible names for the methods that are exactly the same as another method except they apply defaults...and write and maintain more code of course - especially if its in an interface you re-use.
Today I was writing a Skein hash function implementation in Go. Skein can be configured for different purposes (e.g. MAC, KDF, stream cipher, etc.), and it can accept >5 optional arguments. I wanted to expose all these configuration option to users, in addition to providing a simple version that will create hash without configuration. Here's how I solved it (there's prior art in some standard libraries).
I exported this struct:
type Args struct {
Key []byte // secret key for MAC, KDF, or stream cipher
Person []byte // personalization string
PublicKey []byte // public key for signature hashing
KeyId []byte // key identifier for KDF
Nonce []byte // nonce for stream cipher or randomized hashing
}
and then provided a function:
func New(outLen uint64, args *Args) *Hash
Users can easily call it like this:
h := skein.New(64, &skein.Args{ Key: someKey, Nonce : someNonce })
I like this design a lot.
Plus, with structs as arguments you can easily provide more than one default configurations. For example, if you want to personalize hash for different usages:
var FileHashConfig = &skein.Args{ Person: []byte("file hash for MyApp") }
var MessageHashConfig = &skein.Args{ Person: []byte("message hash for MyApp sync") }
and use them:
h := skein.New(64, FileHashConfig)
(Note: Args is a bad name for general usage -- I called it like this only because Skein authors call these "arguments", and "configuration" is reserved for something else.)
There are a few specified usages for Skein with arguments, so to avoid making users of my library read the Skein paper, I wrote "constructors" for them:
// NewMAC returns hash.Hash calculating Skein Message Authentication Code of the
// given length in bytes. A MAC is a cryptographic hash that uses a key to
// authenticate a message. The receiver verifies the hash by recomputing it
// using the same key.
func NewMAC(outLen uint64, key []byte) hash.Hash {
return hash.Hash(New(outLen, &Args{Key: key}))
}
// NewStream returns a cipher.Stream for encrypting a message with the given key
// and nonce. The same key-nonce combination must not be used to encrypt more
// than one message. There are no limits on the length of key or nonce.
func NewStream(key []byte, nonce []byte) cipher.Stream {
const streamOutLen = (1<<64 - 1) / 8 // 2^64 - 1 bits
h := New(streamOutLen, &Args{Key: key, Nonce: nonce})
return newOutputReader(h)
}
So depending on the algorithm you are using, you are going to leave some of these fields in the struct as null/empty?
To me this is the whole issue. Of course if we have knowledge outside the method declaration about what values can be left 0, then we can pass the correct ones as needed. But the interface is ambiguous about when that is acceptable, and the implementation can change without changing the interface.
According to the mail lists I've read on the subject, the correct way to implement your algorithms in Go would be for each to be a separate method. And indeed that is the only way in Go to support a fully specified interface.
In most cases (but now all), there are better ways to design API than stuff them with default arguments, which make functions behave unexpectedly if you forget something.
But maybe we should talk about specific cases? What are the examples of functions which need to accept default arguments? Maybe I can try to convert them into something reasonable in Go?
That is awful for anyone attempting to re-implement your API. It is totally unclear what field combinations are valid, and in time the situation is only going to get worse.
There are no invalid combinations of fields in this case, any combination is valid.
If there were invalid combinations, of course, this wouldn't be a nice API.
This post by Russ Cox (a co-inventor of Go) describes leaving parametric polymorphism out as "slowing down programmers".
http://research.swtch.com/generic
I think it's safe to say they are aware of the issue and consider lack of generics a negative (because it slows you down, duplicates code, adds type unsafety, etc.). They don't have a solution they like yet.
I am not cargo-culting. I am saying that it is not invalid to say to someone 'you're doing it wrong, if you just use a different style that does not become a problem.'
I haven't written anything real in Go yet, but there is a lot of articles about it, and many parts of it do appeal to me. I like how they didn't write another language for the JVM, I like the c inspired syntax, I like the concurrency model they have, etc. It also seems to be getting a lot of praise in
web development circles.
But am I the only one that cringes at going back to writing & and * for passing parameters etc. for web development? I know there is sometimes a need for really managing memory but... I'd love a simplistic language built around the ideas of Go (small runtime, fast, type safe, compiled etc.) for building web apps.
It was founded as a Play framework derivative, if you're familiar with that (I wasn't). I've been using it to put together a web service and I like it so far.
Seriously, push your templates, models, and controllers into static client code (html/js) and use any of the dead-simple Sinatra-like clones to quickly scaffold your REST resources. Go is a superb "plumbing" language, in my opinion.
It actually scales better because you're distributing the rendering effort on more machines.
You can serve client-side code on demand, the same way you're serving HTML on demand. There are multiple methods of running a rich client HTML application in a modular fashion. For example, you can load new JavaScript and CSS on demand, or you could do a hybrid approach, by reloading the complete page from module to module. Most MVC frameworks for JavaScript support dynamic loading.
1. It doesn't perform on some browsers which people use (IE7,IE8). I'm not willing to tell these users to go away or stick Chrome frame in as it makes us look like arrogant assholes.
2. It requires a large memory ceiling even with dynamic loading on a client browser. That kills older browsers and mobile devices.
3. It's an absolute bastard to test properly with Selenium or Ranorex as paths through the application require navigating through anchors rather than HTTP endpoints.
4. The entire UI would be dynamically typed shooting a lot of compile time checks that we rely on.
5. Internationalization is a bastard, particularly with multi-currency support, international date support and multiple languages.
6. It would require more state. State is bad. State means bugs.
7. It shifts the security model to an untrusted zone i.e. the client.
8. We have no scalability problems (5% cluster utilisation) and we shift 100 million requests a day.
Sorry but it doesn't cut it. I'd rather shift a WebStart or ClickOnce behemoth than do this with a client side MVC framework.
Yes, these are valid disadvantages of doing rendering code on the client. In your case, and many other similar to yours, using Go with abstract interfacing wouldn't be practical.
This is an interesting comment because I usually think of "scale" as being able to handle high load. Angular itself is itself about 500K (unminified), but still only about twice as big as jQuery (roughly). Regardless, it makes sense that client heavy apps aren't appropriate for all sites.
Like everybody, I've been hearing good things about Go lately. But although I'm curious about the language, its homepage (http://golang.org/) doesn't make a great impression. It looks very amateurish and unappealing.
It might not seem like a big deal, but it would certainly not hurt a language's popularity to have a slightly nicer site. Unless of course these languages don't want to become popular.
Edit: I actually can't find a single language site that looks good. So maybe bashing Go for this is unfair, although I still find the Go site particularly bad.
As someone who created a language that's gotten some momentum in the past year [http://julialang.org/] and also drew the short straw and ended up making the web site, I can say that core contributors to programming languages (especially scientific ones) seem not to be particularly interested in making pretty web pages. So I kept it as minimal as possible, starting from Tom Preston-Warner's blog [http://tom.preston-werner.com].
Could we hire a designer? Sure. But that's so far down our list of priorities, it's not even funny. And who's going to pay for it? Also, even the time spent dealing with a designer (finding one, negotiating cost, signing contracts, providing feedback, etc.) is time I could be spending on making crucial design decisions, closing issues, improving core language functionality, and writing documentation. That's probably why more mature languages tend to have fancier websites. The Go guys are still super busy making Go awesome!
Even if we hired a designer who made a lovely site, then someone has to maintain it. Programming languages are living, evolving things, and their web sites change. You know what's worse than a bare bones web site? A fancy designer-made web site with a bunch of changes subsequently added by an amateur who doesn't know what the hell they're doing (me).
Sometimes nicer is worse. When using the website of a language I want to focus only on information-I am on a mission. Things need to be in the right places, typography should be spartan and correct. It is a usability problem, not about appeal per se. The people coding circles around you often wouldn't notice if the logo of their language was in Comic Sans.
I am not sure what you find unappealing about those websites, but I find Go’s website very easy to navigate and for browsing the standard library. When looking for software to depend on, I think I prefer a visual design that does not attempt to be in any way “mysterious,” but rather simple and predictable.
I made an uneducated guess for why sgdesign disliked golang.org’s web design. I think an unearthly visual design is more appropriate for adventure games, less so for software tools. That does not mean that only “mysterious” visual design is good visual design.
With that being said, I agree with the others...I prefer a simple and easy layout like Go's website over some pretty typography and new hip layout. Most people going to the website are going for API docs I would assume, and you want API docs to be fast loading and minimal.
Though, it's kind of hard to make things look downright bad when you're using bootstrap.
Either way, you're right. Short, readable, organized, and fast to load are the most important things in API docs, and any design candy is (should be) far lower in priority.
As a matter of fact, I am "a graphic designer or something".
And yes, you're right, those sites all look great. In fact I might just print out screenshots of them and hang them on my wall.
But seriously, I know HN is focused on technology, but we can't pretend like there's no such thing as good graphic design and that these sites are just fine.
There are many sites created by graphic designers that look great but have no substance. There are plenty of sites created by engineers that have great information but no style. Luckily, those sites tend to be catered to people who like their pros and don't mind their cons.
"programming to that in a way that is nonblocking".
It is strange that go it compared to Node.js and this sentence is false. Each function has a Sync version to program in "blocking" way.
Sure there are Sync versions, but you almost never want to use them. There's nothing wrong with his sentence. He did not enjoy the Node.JS callback style event loop. I love it.
To be fair, this will change as go becomes more popular and mature, I don't even know why people keep bringing it up.
Is "C" any more searchable? If C was 3 years old, search results would probably be dominated by pages on the letter "C". I remember search results when C# first came out: most search engines presumed you were talking about musical notes. Java searches kept showing me pages about coffee suppliers and distributors.
None of these languages have this problem anymore because they are mature, and the context around them is firmly established.
The accepted name for the language when doing searches is "golang", and Google does a great job at optimising results around this term. Also there's the IRC channel and Google group if you can't find what you need.
I've been trying to examine the suitability of Go as a language for creating video games in, which is extremely difficult to search for, for exactly that reason.
If anyone on HN who is familiar with Go has any thoughts on that, I would love to hear them.
I've been looking at making a 2D game library for Go based on some older Go code, and various people have made similar efforts, but there's nothing yet that's full and complete. The best option in most cases is to use bindings to OpenGL/SDL/SDL2 for 2D, or bindings to a 3D game engine (Horde3D bindings are available, and there's at least one engine built largely in Go)
There's prorbably more stuff around, but this is what I have collected so far. The biggest concern when making games is the GC; you'll either get a choppy framerate from occasional GC runs, or you'll get a consistent overhead from running the GC every frame. If/when the GC becomes concurrent this situation will vastly improve for games.
I can't imagine that searches for "go" ever turned up anything useful, though. I'm guessing that most searches regarding Go/weiqi will have something Go-specific in them. "go tsumego" is probably going to give you something useful, regardless of the existance of the Go language. (And if one's searches are still limited to "go", head on over to Sensei's Library [1] until that is no longer a problem, it's a great resource)
Well, there's really only one official romanization of Chinese, which is Pinyin (in which it would be spelled "weiqi"). The others are obsolete or niche.
The split in how each goes about targeting 'simplicity' is quite interesting, and seems close to the heart of each language. In Go, simple seems to mean: obvious, intuitive, unclever, and familiar. Clojure's conception is much headier: simplicity isn't accomplished through familiarity and comfort, but through the power and flexibility to create appropriate abstractions, and the discipline to avoid dangerous ones. The most immediate consequence, for a newbie, is that Go feels a lot easier to learn, while Clojure is more mind-expanding and abstract. In Go, simplicity is easy. In Clojure, the simplicity is deeper and perhaps more theoretically pure, but reaching it can be quite a challenge.
My preliminary feeling so far is that each feels like a very clean, modern language and is basically superior to other languages I've used (Ruby, Python, C, js) by every important metric except maturity of community and libraries, and each will have its place. Go's lack of cleverness probably makes it ideal for more run-of-the-mill systems with a lot of straightforward io, where organization, maintainability, and baseline performance are more important than development of powerful algorithms, while Clojure will be a better fit when cleverness is desired either to solve difficult problems or for rapid feature development (a la pg's Beating The Averages). I could also see them potentially working quite well in tandem for a system that spans both those categories.
One more thought: as much as I like Clojure and understand the pragmatism of targeting the jvm, Go's ultra-simple, ultra-fast runtime, along with libraries and a community that embody a similar spirit, really is such a breath of fresh air compared to the jvm world and even the ruby/python worlds. In this realm I think Go beats Clojure at its own game. Thanks to the more 'difficult' choice of starting a fresh platform rather than leveraging an existing one, Go's whole ecosystem and development experience now share a unifying philosophy, and every aspect of working with Go is suffused with what makes Go great.