C Vs GO - Hacker News

Hacker News new | past | comments | ask | show | jobs | submit login
C vs GO (stanford.edu)
202 points by akg on June 14, 2012 | hide | past | favorite | 175 comments
copx on June 14, 2012 | next [–] I like Go but it's not a replacement or even just competition for C. Garbage collection alone ensures that.

C is for low-level code, where you usually want deterministic, real-time behavior. Go cannot deliver that because of its GC.

You can certainly write web server software in Go (what Go was designed for), but could you write an "AAA" video game in it? Or a mission critical embedded system with real-time requirements?

Also, the author's portrayal of C is misleading. If you have 'naked' malloc() calls all over your code you are doing something wrong. Much C code never calls malloc() or follows the "no allocation after initialization" principle.

If you write C like Python you will run into problems. In C you do not wildly allocate objects on the heap all across the program. E.g. in my current program almost everything comes out of memory pools. E.g.

Object* object = ObjectNew();

..and if I forgot to release it I would know quickly because any "memory leak" would cause the (pre-allocated, fixed size) memory pool to run out of free slots. In C you should manage memory in a systematic fashion.

I think the C standard library should be seen as the very foundation of a program, something you use to build the abstractions which solve the problem, not something you use directly to solve the problem. People often warn about the dangers of strcpy() (an the author uses it). I never use it except at the lowest levels. At the high level robust C code looks more like this:

ObjectSetName(object, newName);

than this

strcpy(object->name, newName);

..the difference is that ObjectSetName() can internally guard against overflow and that the concrete details of the object data structure remain hidden and thus later code changes are easier. It is a very common C idiom to use incomplete types and such functions to achieve a very high level of encapsulation.

luriel on June 14, 2012 | parent | next [–] Your C code looks very unidiomatic to me, but I guess that is relatively a matter of taste (still I don't understand why would somebody use C if they don't like to write code in the 'classic' C style as seen in the original Unix and Plan 9 source).

That aside, in Go you can also do fixed allocations and manage your own memory pools to avoid the GC.

And I would also question how many C programs require real-time behaviour (even the definition of 'real-time' has issues, most things people call 'real-time' aren't).

copx on June 14, 2012 | root | parent | next [–] >Your C code looks very unidiomatic to me, but I guess that is relatively a matter of taste (still I don't understand why would somebody use C if they don't like to write code in the 'classic' C style as seen in the original Unix and Plan 9 source).

Because we learned a lot about writing more robust and maintainable software since the 1970s. Also the original Unix source code was one thing more than anything: small. Really, really small. Mostly because it did not do much compared to a modern OS.

Things like encapsulation, separation of concerns, etc. only become important once the code grows to a certain size. Unfortunately some people think you need at least C++ for that, despite the fact that for example "private" member variables are way less private than incomplete C types. C is old, but that does not mean it is incompatible with modern software development approaches. Or that you have to write code as if your compiler only parsed the first few letters of an identifier. I think C's bad reputation in some circles can be explained by people only ever seeing 1970s style code.

2mur on June 14, 2012 | root | parent | next [–] Do you have any resources / books for writing modern C like this or is it all experiential from the trenches?

nvoorhies on June 14, 2012 | root | parent | next [–] C Interfaces and Implementations: Techniques for Creating Reusable Software is the best thing I've seen on the topic, personally. http://www.amazon.com/Interfaces-Implementations-Techniques-...

wsc981 on June 14, 2012 | root | parent | prev | next [–] I'd say "C programming: A modern approach" (K.N. King) should be a good candidate? Personally I like the book.

copx on June 14, 2012 | root | parent | prev | next [–] >Do you have any resources / books for writing modern C like this

No, sorry.

>is it all experiential from the trenches?

It's mostly about applying general principles of software construction like separation of concerns, encapsulation, robust interfaces, etc.

cantankerous on June 14, 2012 | root | parent | next [–] Maybe you could provide some of your favorite resources to those things, then?

AncientPC on June 14, 2012 | root | parent | prev | next [–] This link gets posted on HN a lot but I've found it useful:

http://c.learncodethehardway.org/book/

look_lookatme on June 14, 2012 | root | parent | prev | next [–] I'm interested in this too.

papsosouid on June 14, 2012 | root | parent | prev | next [–] >Because we learned a lot about writing more robust and maintainable software since the 1970s.

Plan 9 wasn't written in the 70s. OpenBSD is another example, probably a better example given that their sshd is far more important, and running on far more machines than anything you've ever written. So it seems rather disingenuous to suggest that the authors of such software are wrong for writing simple, concise, effective code instead of your bizarre vision of C.

pcwalton on June 14, 2012 | root | parent | prev | next [–] Go is a fine language, but I do have a nitpick here: you do not "avoid the GC" by using memory pools. The GC must still trace through the pool when it does run. The more correct thing to say is that you can reduce allocations with memory pools, which make the GC run less often and make it do less work.

Furthermore, memory pools compromise safety: if you free a pointer to an object in your memory pool and you accidentally had aliases to that pointer, then you'll get subtle bugs when one of those objects gets reused.

luriel on June 14, 2012 | root | parent | next [–] In Go you can also just disable the GC if you really want to, but obviously then you have to be more careful.

vilya on June 14, 2012 | root | parent | next [–] How well does that work if you're using some thirdparty libraries? Just curious - I haven't used Go yet so don't know what happens there.

samnardoni on June 14, 2012 | root | parent | prev | next [–] I think the GC in Go only runs when allocations have been made. No allocations = no GC.

pcwalton on June 14, 2012 | root | parent | next [–] Yes, but that's only true if you get down to zero allocations. Memory pools reduce allocations, but you cannot get down to zero allocations--even if you somehow managed to convert every allocation site into a memory pool (which basically means not using the standard library), you'd still have to allocate the pool (unless it's stored in static memory, but then your maximum number of allocations is fixed).

The only code I've seen that actually had zero allocations in a GC'd language is actually Emscripten-generated code in JS, which is of course not actually JS but C.

nux6 on June 14, 2012 | root | parent | prev | next [–] E.g. any app with [record] button need to meet 'mostly' predicted system latency, that's 'soft-real-time'. Any professional app with [play] and [record] button needs a minimal warranted latency, that's 'hard-real-time'. Go is unsuitable for both.

scott_s on June 14, 2012 | root | parent | next [–] That is not the definition of "hard real-time" that I, and others, use: http://en.wikipedia.org/wiki/Real-time_computing

Hard real-time generally means that you have an actual deadline to finish your computation, and Very Bad Things will happen if you miss that deadline. Both of your examples are soft real time.

jff on June 14, 2012 | root | parent | prev | next [–] Your operating system could very well screw you anyway; a full-on Linux OS (for instance) is very very "noisy". See the FTQ (Fixed Time Quantum) benchmark for more info.

pjmlp on June 14, 2012 | root | parent | prev | next [–] And yet there are sound manipulation tools developed in Java and .NET...

pcwalton on June 14, 2012 | root | parent | next [–] Well, to be fair, Java and .NET have generational, concurrent, incremental garbage collectors.

batista on June 14, 2012 | root | parent | prev | next [–] I fail to see how Go is "unsuitable" for even the pro use case.

Go could do a recording type application with minimal guaranteed latency just fine, and the GC won't stop it doing so.

scott_s on June 14, 2012 | root | parent | next [–] While I agree that Go is suitable for his examples, it's not suitable for hard real-time. As far as I know, its GC does not have bounded latencies. There are GCs that do have bounded latencies (see the Metronome project for Java's GC: http://researcher.ibm.com/researcher/view_project.php?id=174) which then allow them to be used for hard real-time systems.

luriel on June 14, 2012 | root | parent | next [–] This is not really an issue with the language but with the implemetnation and most languages/libraries/OS-es are not suited for "hard real-time" either.

How many people are writing "hard real-time" code? I suspect not many, and yes, for them probably Go is not the right tool at the moment, but also in great part because nobody has needed/wanted to use Go in such environments yet.

scott_s on June 14, 2012 | root | parent | next [–] Requiring garbage collection is a language issue, not just an implementation issue. (Note that I do not think GC is a bad thing, but it matters a great deal in this context.) Making GC work in hard real-time system is a Hard Problem. I think you greatly underestimate how difficult it is, given your final sentence. Read the Metronome project I linked to.

You are correct that not many people write hard real-time code; it's generally found in such things as software controlling planes, power grids or power plants.

it on June 14, 2012 | root | parent | next [–] You can shut off the GC in Go:

import "runtime" ... runtime.MemStats.EnableGC = false https://groups.google.com/forum/?fromgroups#!topic/golang-nu...

jamesgeck0 on June 14, 2012 | parent | prev | next [–] > but could you write an "AAA" video game in it?

Perhaps not, but an extremely large percentage of commercial indie games are written in managed languages.

regularfry on June 14, 2012 | root | parent | next [–] My chief worry over Go at the moment isn't that is has GC (for the most part), but that the GC it does have is relatively dumb.

luriel on June 14, 2012 | root | parent | next [–] The GC in Go 1 is a bit smarter than it used to be, and it is going to be even smarter in Go 1.1, this things take time, and the current GC works quite well for most people. Also Go gives you control over memory layout, which allows you to avoid some GC issues that are much more difficult in languages like Java.

stcredzero on June 14, 2012 | root | parent | next [–] You can avoid those things in Java as well, by adjusting settings. Adjusting eden and generation sizes with generational GC is a bit of an art for all but the simple cases.

eswangren on June 14, 2012 | root | parent | prev | next [–] Yes, but they tend to be relatively trivial (in terms of performance) in comparison to AAA titles.

heretohelp on June 14, 2012 | parent | prev | next [–] No really; I know a number of very talented systems programmers and grew up with C myself.

Your C is not idiomatic even if you're right about avoiding naked mallocs and Go not being appropriate for systems programming.

fingerprinter on June 14, 2012 | prev | next [–] I guess I might be the only one to say this, but is this a joke? Some sort of prank? Not a single Go program is more readable, and I would argue that they are ALL less readable (and I like Go).

I honestly can't tell if he is trolling or if he is serious.

angelbob on June 14, 2012 | parent | next [–] He's picking a bunch of problems C is really good at and then roughly, fairly mechanically translating to Go.

I don't think he's trolling, but I do think he's playing to C's strengths and Go's weaknesses, possibly by accident.

cantankerous on June 14, 2012 | root | parent | next [–] I agree. I don't see anything wrong what he did, but somebody should offer to submit counterpoints that better emphasize what Go is able to do.

jlgreco on June 14, 2012 | root | parent | next [–] I think many counterpoints should be fairly obvious. Anything from "return a return value and an error code from a function" (trivial in both, way nicer in Go though) to "write a webserver from scratch. Which did you just schedule more time for?"

ternaryoperator on June 15, 2012 | root | parent | next [–] Or anything that needed to be run in parallel.

jbooth on June 14, 2012 | parent | prev | next [–] I think Go's strengths over C really start to shine when you're writing programs longer than 100 lines. Not having an exception mechanism, interfaces, single namespace, no attaching methods to structs etc are fine in a small program, but they make bigger programs harder to digest pretty quickly.

Locke1689 on June 14, 2012 | root | parent | next [–] Calling Go's panic/recover system a proper exception mechanism is quite a stretch.

sirclueless on June 14, 2012 | root | parent | next [–] I think he is referring more to go's "defer" functionality and out-of-band error return values more than panic/recover.

Locke1689 on June 14, 2012 | root | parent | next [–] All of these things are just really poor exception mechanisms, in my opinion. It really looks like no one with an up-to-date PLT background was consulted in the design. I agree 100% with Andreas Rossberg (who now, somewhat ironically, works at Google):

It is ironic that their motivation is to tame and restrict the use of exceptions, and then they replace them by something even richer and much less structured. I fail to see any pros of this proposal. It seems mostly equivalent to exceptions, i.e., you can easily express raise/try/finally as syntactic sugar, and likely the other way round. But it is (1) much more ad-hoc -- you cannot give a simple reduction semantics for this, (2) much less orthogonal -- tying `defer' in with function definitions, (3) dependent on mutation -- for recovering and returning alternative results, and implicitly in the semantics of `defer'. One consequence is the loss of beta-convertibility, which means that you as a programmer cannot take an arbitrary piece of code and turn it into a function anymore, or vice versa, eliminate a function by inlining its body. Such abstractions/refactorings are impossible in general under this proposal, or at least require transforming the relevant code in potentially non-trivial ways.

wickedchicken on June 14, 2012 | root | parent | next [–] > It really looks like no one with an up-to-date PLT background was consulted in the design.

"Go is not meant to innovate programming theory. It's meant to innovate programming practice." I really like the out-of-band errors since they make control flow very explicit. With languages that rely on exceptions a lot (python, for example) I feel less in control of my program since 'anything can happen' remotely from my code.

Locke1689 on June 14, 2012 | root | parent | next [–] Sorry, by "out-of-band errors" do you mean the error return value? This is not a terminology I'm familiar with.

For any function which produces values of the form (a -> (b,e)) I'd refer to that as a product type. If this is what you're referring to, this is just a return value. There isn't really an exception system here.

If you think about how return values work in C you'll note that it's usually some subset of the range which is defined for an actual value and some subset defined for an error condition. This is basically the same as (b,e), just worse type safety. Easy and efficient tuple constructions are hard to create in languages with manual memory management.

Edit: Also, I didn't mean that Go should have innovated in PLT, only took advantage of innovations already established.

wickedchicken on June 14, 2012 | root | parent | next [–] > If this is what you're referring to, this is just a return value. There isn't really an exception system here.

Yes, which is awesome.

> If you think about how return values work in C you'll note that it's usually some subset of the range which is defined for an actual value and some subset defined for an error condition.

This would be an 'in-band' error, as opposed to 'out-of-band.' It's terminology borrowed from communications theory. You also see it used to describe an 'out-of-band' console that is a secondary way to SSH into your machine if your network is hosed.

> Also, I didn't mean that Go should have innovated in PLT, only took advantage of innovations already established.

I think the point is that this is intentional. I love super high-level languages, but they're experimental for a reason -- things haven't 'settled down yet' and until they do, it will be difficult for the average person to reason about what is going on. Take garbage collection: this was technology that had been around for decades, but computers and garbage collection algorithms had to be sped up and tuned before general adoption. Large systems demand predictability and integrity on nearly every dimension. Luckily as time goes on, the experimental stuff becomes the expected; advanced programming language theory gets built into larger systems and we all benefit. Go is part of that evolution.

Locke1689 on June 14, 2012 | root | parent | next [–] I think the point is that this is intentional. I love super high-level languages, but they're experimental for a reason -- things haven't 'settled down yet' and until they do, it will be difficult for the average person to reason about what is going on.

No, sorry, I should have been even more explicit: it looks like the designers were not even aware of new advances in PLT. As far as I can see, defer/panic/recover is objectively worse than an exception system for all of the goals which they lay out in their paper.

You like return values--ok, I can see that. I prefer that the type checker actually enforce error checking when using error return values, but fine.

Adding defer/panic/recover is an attempt to add a simpler and more constrained exception-like system to the language, but I think it is objectively (both from a PLT perspective and compiler-design perspective) worse than a more traditional exception system. Breaking beta-reduction is very unfortunate and I can't see a good reason to do it in this case.

wickedchicken on June 14, 2012 | root | parent | next [–] > No, sorry, I should have been even more explicit: it looks like the designers were not even aware of new advances in PLT.

Ken Thompson won a Turing award, dude.

plorkyeran on June 15, 2012 | root | parent | next [–] In 1983, 24 years before starting work on Go. That's a lot of time to fall behind on new research.

azth on June 26, 2012 | root | parent | prev | next [–] http://en.wikipedia.org/wiki/Argument_from_authority

kd0amg on June 14, 2012 | root | parent | prev | next [–] "Go is not meant to innovate programming theory. It's meant to innovate programming practice."

I don't think GP was saying that Go should have provided some advance to programming language research, but that it doesn't show much awareness of advances that have already been made.

redbad on June 14, 2012 | root | parent | next [–]

[Go] doesn't show much awareness of advances that have already been made. Go's response would be to question that the things you're talking about are, in fact, unqualified advances. Especially in the context of large (ie. LOC) systems applications, maintained by large (ie. dozens to hundreds) of developers.

Locke1689 on June 14, 2012 | root | parent | next [–] Java, C#, Python, Lisp, and Erlang would all criticize Go for an unqualified new exception system which has not proven that it can handle itself in the context of large systems applications, unlike all the previous languages.

redbad on June 15, 2012 | root | parent | next [–]

Java, C#, Python, Lisp, and Erlang would all criticize Go for an unqualified new exception system panic/recover is not an exception system in the sense that you mean. Nobody is writing large applications and using panic/recover for error handling. (At least, I hope not!) The idiomatic way of handling errors in Go is returning them explicitly, and checking for them at the call site.

func canFail() (int, error) { ... } value, err := canFail() if err != nil { // handle }

luriel on June 14, 2012 | root | parent | prev | next [–] I disagree that panic/recover is worse than exceptions, I find it a more pleasant and lightweight mechanism, but the big difference is that panic/recover are not used like exceptions at all in Go, they are basically used only for programmer errors.

They can be used for other things, but in those cases they never cross API-calls so you never have to worry about whatever a library you call might panic, you can basically ignore panic/recover exists completely, and do just fine, and that is what most people do most of the time.

Locke1689 on June 14, 2012 | root | parent | next [–] Well, we can argue about whether or not an exception mechanism is the best way to deal with program error conditions, but my first point still stands, which is that Go does not have a proper exception mechanism. If defer/panic/recover were to be used as a true exception system you would run into all the issues Andreas details.

eswangren on June 14, 2012 | root | parent | prev | next [–] Well, the operating system you used to write that comment was probably written in C, so apparently it does in fact work in large projects. It has weaknesses to be sure, but I don't think lack of OO (I.e., structs with functions) is one of them.

jbooth on June 14, 2012 | root | parent | next [–] Duh. "Done" and "easily done" are different things.

Structs with functions isn't the biggest deal, and namespaces can be simulated with a couple underscores. But I have a hard time with error handling if you don't have exceptions, any time I have a call stack more than 3-4 deep I find myself confused about how to treat certain errors. Then there's concurrency.

tedunangst on June 14, 2012 | root | parent | prev | next [–] It's worth noting that the bulk of the code in the kernel comes from 900 different network drivers, each of which could be considered a small program in its own right.

dllthomas on June 14, 2012 | root | parent | prev | next [–] Particularly given that you can write OO code in C, and can decorate structs with functions, it's just messier.

StephenFalken on June 14, 2012 | root | parent | next [–] "Object oriented programming with ANSI-C":

https://ritdml.rit.edu/handle/1850/8544

donnyg107 on June 14, 2012 | parent | prev | next [–] I disagree. After only a brief runthrough of Go, the different types of statements are very recognizable line by line. The sytax includes less obvious breaks and parens, but I think that makes the code a lot more readable because it eliminates the nastier paren nesting you often see in C. I think the first example in chapter 2 gives clear indication of the benefits of eliminating the features of C which are more compact but less readable.

AncientPC on June 14, 2012 | parent | prev | next [–] I've gone ahead and reformatted his code using `indent -kr` and `gofmt`: https://gist.github.com/2932444

dillon on June 14, 2012 | parent | prev | next [–] He is definitely serious.

I do think that all semicolons really shouldn't be used. The only time I ever use semicolons is for error checking in Go.

shadowmint on June 14, 2012 | parent | prev | next [–] Judging by the similarity to his much large section on C (http://crypto.stanford.edu/~blynn/c/) I'd say serious.

Also, who cares what his style is?

If _you_ ever have to work on the code, run gofmt on it; if that's how he likes his go, good for him.

scott_s on June 14, 2012 | root | parent | next [–] Also, who cares what his style is?

Me, because I found it unpleasant to read. Working on such code is beside the point.

drivebyacct2 on June 14, 2012 | parent | prev | next [–] He's not helping by explicitly stating that he's ignoring gofmt style. Those examples would look lengthier but cleaner if he would run gofmt on them.

simias on June 14, 2012 | prev | next [–] Damn. I can't comment on the Go listings, but could he make his C code any less readable?

What's the point of making the code so dense anyway? Without syntax highlighting I gave up pretty quickly.

adobriyan on June 14, 2012 | parent | next [–] The point is to show that Go is superior to C (which obviously is true but not for the reasons mentioned in the article).

Anything counts.

Go code is obviously formatted with gofmt. C code is obviously not formatted with "indent -kr".

Liberal use of comma operator unseen in real world.

Look at example of yes(1) with error-handling.

Author doesn't use strdup(3).

But even if he did, it still doesn't make sense to call fprintf(3) once due to allegedly hard error handling. Error handling is not common path, fprintf(3) doesn't fail!

He concatenates all string into once which makes it O(n^2) because of many many times strlen(3) is called (and kernel copied argv contents before that!).

I bet he did error checking wrong on C side (just checking return value should not be enough). It'd be interesting to see same code on Go side.

Obligatory quote: "considering that bad code can be written in any language, any language comparison performed using examples must be judged by the quality of the examples in each language. it can't be all that hard to write a bad example in language A and a good example in language B, and then proclaim language B to be the winner -- this is how people compare languages all the time, so either those who read them are bad programmers in any language (or are not programmers at all) and don't know how to reject the bad examples, or they already agree with the author of the comparison that language B is better than language A. in either case, it's a waste of anything but marketing money.

...

#\Erik"

akavel on June 14, 2012 | root | parent | next [–] > Go code is obviously formatted with gofmt.

Is not, he also inlined some things, e.g. this:

import ("flag";"fmt") would be expanded to multiline by gofmt, as well as this:

if i>0 { fmt.Print(" ") } As to other things, I can't comment now, as I don't have time to read through all of the article at the moment.

shadowmint on June 14, 2012 | root | parent | prev | next [–] This has been discussed before, so many times.

In fact, in pretty much every thread go turns up in. sigh I'm just going to link to my favourite review now, again (pertinent, and mentioned here only because the author of the original shared a favourite with me): http://www.math.bas.bg/bantchev/misc/on-go.html

Quote: "But I know I am not going to love Go. True beauty evades this language. Go may be practical, but is also eclectic, and has taken some unconvincing or downright ugly design choices. It definitely lacks that subtle but unmistakable touch of elegance that makes a language great."

luriel on June 14, 2012 | root | parent | next [–] I'm not sure how to take that review given that his two main complaints seem to be:

1) That Go has i++ and not ++i. Don't even know what to say to someone who thinks this a major issue, really.

2) That the declaration syntax is 'unattractive' and different from other languages. Yes, the syntax looks a bit strange at first if you are used to C, but it is unquestionably cleaner and better, specially in more complex declarations. This is even covered in the FAQ: http://golang.org/doc/go_faq.html#declarations_backwards

His other complaints seem to be about the name of the language and how much some of the Go documentation acknowledges the influences of certain languages, which as he himself says, is just politics and not really relevant to the language itself.

At the same time there seems to be plenty of people who actually have used Go and love it, including the designers of other languages:

http://go-lang.cat-v.org/quotes

cloudhead on June 14, 2012 | root | parent | prev | next [–] Go is superior to C? Damn, I must have missed the memo!

anon_d on June 14, 2012 | parent | prev | next [–] The C code looks very nice to me. What's the problem?

ralph on June 14, 2012 | prev | next [–] I gave up reading this very early on. The striving for compactness of the source, in both C and Go, makes it misleading to read. Take

if (argc < 2) puts("y"); else { for(int i = 1; i < argc; i++) { if (i > 1) putchar(' '); printf("%s", argv[i]); } putchar('\n'); } A casual skim sees the if followed by an indented block, but that isn't the then-path but the else-path. Now yes, I can read it carefully and follow it, just as if I was debugging someone else's poorly formatted code, but in doing so my attention is being distracted from the main point of the article and frankly I have a huge pile of other things to read that are potentially more rewarding.

luriel on June 14, 2012 | parent | next [–] Yes, his code style is bizarre at best, both for C and Go.

This is particularly jarring in Go when gofmt exists and is used almost universally (I think this is the first time I see non-gofmt'd code in quite a while).

JackdawX on June 14, 2012 | parent | prev | next [–] Your post adds nothing useful to the discussion. There is no point arguing about indenting style in a 7 line program, it's needless pedantry! This is almost exactly the same thing as grammar nazi-ism, and seems to have a similarly negative impact coding related websites.

I think we need to coin a new term - indent-nazi, style-nazi, or something similar - for the purpose of dismissing this kind of post and keeping people on topic.

swdunlop on June 14, 2012 | root | parent | next [–] Actually, "indent-nazism" is a big thing in the Go community. The Gofmt utility, which takes an AST of your code and normalizes it to a common style. Nobody agrees that the style is perfect, a lot of people have religious preferences when it comes to brace placement. But Gofmt ensures that all these people can find a consistent format when it comes time to diff.

GoSublime and go.vim both integrate gofmt into the editor; you start to miss it when refactoring, because you can just shrug and say "gofmt will clean it up when I save" when you move a block to a different function or indent level.

I agree with the grandparent -- seeing non-gofmt code is jarring and deliberately distracting. It's like someone writing an entire Python program with nothing but lambdas.

drivebyacct2 on June 14, 2012 | root | parent | next [–] It's not just diffs, you learn to scan code. The same way that you can't use i++ inline, having consistent indentation and treatment of syntax allows for quicker at-a-glance human parsing.

AncientPC on June 14, 2012 | root | parent | prev | next [–] The author's style is not idiomatic for C or Go. He uses shortcuts for compactness at the cost of readability.

Normally this alone is not an issue, but using non-idiomatic code is a weak argument when trying to describe language readability differences.

plorkyeran on June 14, 2012 | root | parent | prev | next [–] That code is along the lines of #define true false for reader-hostility. When the formatting makes the code look like it does the exact opposite of what it does, then complaining about it is not in any way "needless pedantry".

ralph on June 15, 2012 | root | parent | prev | next [–] I'd just point out that I'm not complaining about something trivial, e.g. open braces on their own line, or a matter of taste, but something fundamentally weird, unexpected, and almost designed to mislead.

gouranga on June 14, 2012 | prev | next [–] Interesting comparisons.

However (not slating Go, which I think is excellent), I genuinely think Go is going to go the same way as plan9 eventually. Unfortunately, its predecessor (C) is good enough, much as UNIX was good enough compared to plan9.

nux6 on June 14, 2012 | parent | next [–] The devil is in details. Go is great for hi-level or simple stuff like that, but is not really usable for system programming. If things are a bit more complicated, the go runtime stays in the way. For those problems, after a while, the bare metal support was removed from the language completely...

pjmlp on June 14, 2012 | root | parent | next [–] Ever heard of Oberon, Modula-2 and Modula-3?

These languages also had OS fully implemented on them, just with tiny bits of Assembly to do the very low level stuff, similar to what C would require anyway.

The only advantage of C is that its runtime is so small, that in practice the OS is the C's runtime.

mkup on June 14, 2012 | root | parent | next [–] It's not the only advantage. Another, more important advantage of C and C++ over Go is a lack of stop-the-world garbage collection (and predictable memory usage under high load).

rwmj on June 14, 2012 | root | parent | next [–] You can predict the time that malloc(3) and free(3) take to run? You know they are backed by very complex data structures that need to manipulated and iterated over?

The point you mention is only valid when using entirely static memory, which is a very rare case in real C code (only really used in a few small embedded codebases).

copx on June 14, 2012 | root | parent | next [–] >You can predict the time that malloc(3) and free(3) take to run?

The correct answer would be: depends on the concrete implementation. There are implementations with real-time guarantees.

However, assuming standard desktop OS malloc()/free() the answer is: No. These functions can execute very quickly.. or very slowly, depending on their current internal state. But you can control when they get called, which can be an important difference.

>The point you mention is only valid when using entirely static memory, which is a very rare case in real C code (only really used in a few small embedded codebases).

Depends on what you mean by "entirely static memory". No malloc() calls at all? Yes, that is rare and pretty much limited to the embedded realm I think. Memory pools however are very common in performance critical code.

gouranga on June 14, 2012 | root | parent | next [–] You speak sense. I tend to use apr pools all the time in critical sections.

pjmlp on June 14, 2012 | root | parent | prev | next [–] > You can predict the time that malloc(3) and free(3) take to run?

Thanks for pointing this out.

This is often a misunderstanding from manual memory management fans. In many cases malloc()/free() also behave non-deterministic.

This is the main reason why for special types of applications, you need to have malloc()/free() implementations specially targeted to the use case at hand.

This is no different from the GC runtimes, which are coded specifically for real time applications, like avionics, for example.

ori_b on June 14, 2012 | root | parent | next [–] It's very different in one significant regard: it's very easy to write your own acceptably performant and deterministic malloc and free, compared to the effort it takes to write a GC that would fit in to those constraints.

pcwalton on June 14, 2012 | root | parent | prev | next [–] malloc and free are much cheaper than a mark-and-sweep. It is a much easier task to write a bounded-latency malloc suitable for real-time applications - for example, dlmalloc has a NO_SEGMENT_TRAVERSAL flag that assures bounded execution. By contrast, making GC with bounded latency is hard.

rwmj on June 14, 2012 | root | parent | next [–] Why are you comparing an API (malloc/free) to an implementation (mark and sweep)?

Anyway, take a look at the OCaml GC. It's simple (probably simpler than glibc's malloc) and very performant particularly if you understand how it works and use it intelligently in your app.

mkup on June 14, 2012 | root | parent | prev | next [–] Not that complex really, if we are talking about buddy allocator or jemalloc. They both have predictable and limited running time.

Default platform malloc(3) and free(3) can be a crap indeed, but they are drop-in replaceable with the above at any time, unlike Go GC - if practical testing suggests such replacement is necessary (e.g. Firefox, Facebook servers)

luriel on June 14, 2012 | root | parent | prev | next [–] > The point you mention is only valid when using entirely static memory

Exactly, and you can also do that in Go to avoid the GC.

vonmoltke on June 14, 2012 | root | parent | prev | next [–] Not sure exactly what you mean by "entirely static", but in the signal processing application I worked on we used an allocate once/deallocate once design where we allocated gigabytes of RAM per node up-front and reused the buffers and data structures during operation. We took over the entire node, essentially, and we were a closed system, so this design didn't cause most of the problems this normally would.

nux6 on June 14, 2012 | root | parent | prev | next [–] Aren't they dead? Seriously. If you write programs at OS level, you need the control over memory, timing, etc. In go you have no control about the runtime at all. Don't get me wrong. Go is fantastic for any kind of gooooogle, cron, at, ... server stuff. At OS or bare level you unfortunately need something other than a sledgehammer.

pjmlp on June 14, 2012 | root | parent | next [–] > Aren't they dead?

Yes, but only because no major OS manufacturer picked them up as the main system language.

The only way a system language can become mainstream is if it is picked up by an OS vendor that makes it the default system language on their OS.

As for the bare level stuff you describe, real systems like Native Oberon proved this is possible. At ETHZ Native Oberon was used for almost everything an OS is used for.

Sadly no major vendor has got interested on the system, even after some industry attempts tried out by ETHZ.

luriel on June 14, 2012 | root | parent | prev | next [–] > For those problems, after a while, the bare metal support was removed from the language completely...

Not really true, you have direct control over the memory layout of your data structures, and if you want to do really tricky stuff there is also the unsafe package.

icebraining on June 14, 2012 | root | parent | next [–] I think nux6 means running Go programs without an OS, directly "on the metal". There was a proof of concept early on, but it was abandoned.

thdn on June 14, 2012 | parent | prev | next [–] Even the pet looks similar hehehe :P

jff on June 14, 2012 | root | parent | next [–] Could be because they were both created by the same person.

Devilboy on June 14, 2012 | parent | prev | next [–] The big win for go over c is the goroutines - cheap and easy multithreading built right into the language.

gouranga on June 14, 2012 | root | parent | next [–] I agree entirely - they are great, but in all the Go I've written (which totals about 50kloc so far as a porting project), I haven't actually used them past anything I would have done with zmq in C.

luriel on June 14, 2012 | root | parent | next [–] Goroutines are great, but I'm not convinced they are the greatest advantage over C.

Go cleans up and fixes pretty much every issue C had, and improves it in many non-obvious areas, from the syntax to the type system.

And when porting an existing project I'm not surprised if goroutines would come up that often given that they probably don't have any equivalent in the original design.

jamwt on June 15, 2012 | root | parent | prev | next [–] zeromq or coroutine libraries like libtask (by a go author!) have greatly reduced this advantage.

gouranga on June 15, 2012 | root | parent | next [–] libtask looks really cool. Thanks for posting.

I suppose that begs the question: if you can built it in the language, should it really be a part of the implementation?

luriel on June 15, 2012 | root | parent | next [–] Plan 9's libthread ( http://man.cat-v.org/plan_9/2/thread ) provides similar CSP-style concurrency to Go. Yet, the authors, after using it for many years, and after having used and built systems where it was part of the language (eg., Inferno/Limbo) decided it was important enough to make it part of the language for it to be usable.

There are also other language features that make it much more usable and that are missing from C, like garbage collection.

I know Rob Pike and Russ Cox have discussed this several times, it might be worth watching this talk by rob about the history of Go's concurrency model you can find here: http://go-lang.cat-v.org/talks/

And Russ Cox's article also about this: http://swtch.com/~rsc/thread/

I'm not sure either covers exactly the reasons why it is a great advantage to make it part of the language, but they are still interesting background.

gouranga on June 15, 2012 | root | parent | next [–] Thanks for the information - I will have a good read this evening :)

delinka on June 14, 2012 | prev | next [–] My complaint about Go centers around its mechanics of code reuse: static linking for all Go code; making anything Really Useful requires using other libraries, which includes those written in C, which require use of a tool to help you write your wrapper ...

If we could get dynamic linking and something less cumbersome for interfacing with existing libs, I could use Go for Serious Work.

luriel on June 14, 2012 | parent | next [–] The C and C++ code Google runs on their servers is always statically linked, and I would call that Serious Work.

In the end, static linking is almost invariably superior to dynamic linking: simpler toolchain, simpler runtime, better reliability, better performance and better security, see:

http://harmful.cat-v.org/software/dynamic-linking/

That said, I think you can do dynamic linking with gccgo, and when linking to C libs with cgo, you do dynamic linking.

comex on June 14, 2012 | root | parent | next [–] > (Remember that the real impetus for adding them to Unix was X11 and its big and badly-factored libraries, which most of us aren't blessed with.)

Really? Today we are very much blessed with quite a few large libraries - not just X but Qt on top of that and KDE on top of that. WebKit. ICU. These come out to dozens of megabytes. Static linking would add somewhat less by eliminating unused symbols, but you'd still end up with massive bloat for your GUI processes; maybe with today's disk and memory sizes and SSDs that's not the end of the world, but it would be a rather pointless performance drag. That's not counting the difference between Go and Plan 9: I count 4,000 odd binaries in my PATH; if they each had the 1 MB overhead of hello world in Go, I'd be out 4 GB, more than I pay for the entire set of libraries on my system (with some redundancy). (And I hope you don't mind waiting for your programs to compile; despite the Go compiler's vaunted speed, it actually takes over 4 times as long to build hello world as clang for the same in C, the vast majority of which is spent in the linker.)

Security? Today's security environment requires frequent patches to library code. If you have a system to automatically re-link all the programs that link against libraries with security updates, great (make sure you don't miss any, such as manually compiled or copied binaries); otherwise, your system is impossible to keep secure.

luriel on June 14, 2012 | root | parent | next [–] > Today we are very much blessed with quite a few large libraries

And with magnitude orders more RAM. And just because there are large libraries doesn't mean they are either necessary or desirable.

> not just X but Qt on top of that and KDE on top of that. WebKit. ICU. These come out to dozens of megabytes.

Interestingly most apps that depend on Qt, WebKit or ICU include their own copies of this libraries.

> Static linking would add somewhat less by eliminating unused symbols

Thanks for reminding me of another benefit of static linking which I forgot to mention.

> I count 4,000 odd binaries in my PATH

I'm a fan of many small tools working well together but I can't help but feel that when you have systems with 4,000 binaries in your PATH, something has gone terribly wrong.

Also, Go's current binaries are large not because they are statically linked but because there has been basically zero optimization of generated binary size. There is no reason why Go binaries couldn't be much smaller, other than so far it has not been a problem for anyone building systems in Go.

> Today's security environment requires frequent patches to library code.

Which is not helped by dynamic linking for reasons both of complexity (see http://harmful.cat-v.org/software/dynamic-linking/versioned-... ) and because most programs anyway use their own version of such 'shared' libs (update your system's ffmpeg and chrome will keep using its own copy). Dll-hell has security implications too.

In practice people end up doing things that either nullify the alleged benefits of dynamic linking, or simply using static linking (Google deploys statically linked binaries, sometimes multiple Gb in size to their servers).

Noughmad on June 14, 2012 | root | parent | next [–] Ok, you have no idea what you're talking about.

> Interestingly most apps that depend on Qt, WebKit or ICU include their own copies of this libraries. So you're not a Linux user, ok. In that case there really are not that much shared libraries. Using a free desktop means that a large majority of all programs you use requires the same set of shared libraries. And as least in KDE and Gnome, there is a large number of small programs running in the background.

> I can't help but feel that when you have systems with 4,000 binaries in your PATH, something has gone terribly wrong. A quick "ls /usr/bin | wc -l" gives me 3135. Considering this is not the whole PATH, I think 4000 is a normal number.

In Linux distributions, programs don't have to ship their own versions of anything. Maybe you should try it.

xyproto on June 15, 2012 | root | parent | next [–] Using something, then reaching a conclusion that is on the "next level" often have surprising similarities to conclusions made by people that haven't started using it at all.

See also: http://www.zenguide.com/zenmedia/index.cfm?id=303

comex on June 14, 2012 | root | parent | prev | next [–] > And with magnitude orders more RAM.

Doesn't mean I want to waste it. Some systems don't really have much RAM to spare, such as the iPhone.

> And just because there are large libraries doesn't mean they are either necessary or desirable.

This is an old argument, but short of rewriting the world there isn't presently much alternative.

> Interestingly most apps that depend on Qt, WebKit or ICU include their own copies of this libraries.

Not sure which system you're talking about. As far as I know, Linux distros tend to link everything against system libraries. Here on OS X, Qt is usually bundled, but WebKit and ICU are part of the system and dynamically linked against. Independently distributed Linux programs are an exception and arguably a bad idea.

> I'm a fan of many small tools working well together but I can't help but feel that when you have systems with 4,000 binaries in your PATH, something has gone terribly wrong.

Most of it I don't use and thanks to MacPorts, I have a lot of duplicate copies of tools. (Maybe not the best system, but disks do have enough room to waste some.)

> There is no reason why Go binaries couldn't be much smaller, other than so far it has not been a problem for anyone building systems in Go.

Fair enough. It is a problem for me mainly because I value very fast compilation of small tools.

> Which is not helped by dynamic linking for reasons both of complexity (see http://harmful.cat-v.org/software/dynamic-linking/versioned-.... )

This does sound awful but I have not really seen it anywhere outside of libcs. OS X libc has only a few switches (UNIX2003, INODE64) and uses them to provide wide backwards compatibility.

> and because most programs anyway use their own version of such 'shared' libs (update your system's ffmpeg and chrome will keep using its own copy).

And indeed this can cause serious problems (I remember a vulnerability report or two about some program shipping an out-of-date library), but luckily you're exaggerating its prevalence. Chrome will keep doing its own thing, but when WebKit gets another of its innumerable security updates, I don't have to redownload the 32 applications I have that link against it.

(ffmpeg might be an exception because it doesn't care about stable releases, but I also remember a blog post complaining about Chrome's (former?) gratuitous forking and bundling of libraries. It's a bad idea.)

> Dll-hell has security implications too.

Only on poorly organized systems. On a Linux distro, the package manager takes care of dependencies and generally gets it right. OS X is uniform (and willing to break backwards compatibility) enough that when there are problems, the developers update their apps.

> In practice people end up doing things that either nullify the alleged benefits of dynamic linking,

in a small minority of cases, yes; in the vast majority of cases where, on a well-organized system, I just want this security or framework update to make it to everything, no.

> or simply using static linking (Google deploys statically linked binaries, sometimes multiple Gb in size to their servers).

Facebook also does the gigabyte binary thing. It's a ridiculous waste of space, but if they don't care, they don't care; servers don't have as many constraints as user-facing computers (they have a fixed workload and expected disk usage), and are often less vulnerable to library security issues, not having to expose the full web stack + PDF rendering + Flash + GL to to any random web site the user navigates to. :)

shadowmint on June 14, 2012 | parent | prev | next [–] I dont see why this got downvoted. It's the biggest issue I have with go as well.

It's a royal pain writing go that talks to C code, compared to say, lua or python, and there just _isnt_ a way to make other languages pickup go libraries and run the symbols from them afaik...

jkn on June 14, 2012 | root | parent | next [–] According to my limited experience (small tools such as a process monitor linking to libproc) it is astonishingly easy and convenient to call C code from Go: no need to write bindings, as Cgo allows to access C symbols directly from Go. I would be interested in what are the difficulties when dealing with larger projects.

For illustration, here's how I call the openproc() function from libproc:

import ( /* #cgo LDFLAGS: -lproc #include <proc/readproc.h> PROCTAB* my_openproc(int flags) { return openproc(flags); } */ "C" ) func parse_procs() { proc := C.my_openproc(C.PROC_FILLUSR | C.PROC_FILLCOM | C.PROC_FILLSTAT) ... } This illustrates one issue I found with Cgo: calling functions with variable number of arguments is not supported. I had to define a new C function "my_openproc" with a fixed number of arguments, which you can see in the metadata of the import statement. It also includes the compiler and Cgo directives that make editing a Makefile unnecessary. The code for the whole tool is contained in one Go file.

luriel on June 14, 2012 | root | parent | prev | next [–] > It's a royal pain writing go that talks to C code, compared to say, lua or python

This is plain wrong, you can pretty much call C code directly, while in Python and the like you really have to write a wrapper.

Of course in Go you will write a wrapper anyway to give the library a more Go-like API, but I don't see how this could be any worse than in any other language.

> there just _isnt_ a way to make other languages pickup go libraries and run the symbols from them afaik...

To get non-Go code to call Go code is trickier (also Go really wants to run your main()), but can be done, and there are even libraries to write Python extensions in Go, see:

http://gopy.qur.me/extensions/

xyproto on June 15, 2012 | root | parent | next [–] Also, there's assembly. http://stackoverflow.com/a/6535590/131264

tedunangst on June 14, 2012 | root | parent | prev | next [–] There's no single definition for Serious Work. It's just an insult to belittle people whose work is different than your own.

delinka on June 15, 2012 | root | parent | next [–] Let me help you out so you don't feel belittled or insulted. Serious Work is anything that will ever leave the confines of my experimental system to be used, viewed, or edited by anyone else. Doesn't matter if it's a trivial script-like tool or if it's a complex app.

thraxil on June 14, 2012 | parent | prev | next [–] My understanding is that the static linking is a temporary measure to keep things simple and let them focus on getting the language stable. Dynamic linking will come later.

0xABADC0DA on June 14, 2012 | parent | prev | next [–] Somebody should write a Google Go to C transpiler. Mostly Google Go features are limitations or different styles in order to 'improve' C, so it should produce fairly readable C code. Then you could use any compiler, linking type, combine with any language, etc. You could probably even use LD_PRELOAD to replace coroutines with pthreads.

For instance Russ Cox did coroutines and channels in his C libtask in a few thousand lines of code. It's not pretty but it works. Include something like it behind an API as 'libgrt.o' with a few other features and the rest of the code transpiles cleanly.

...but say this existed. What would be the point of writing Google Go code? A more compiler-friendly syntax, less flexibility to make simple memory/pointer mistakes? Would that be enough or would you, with perfect C linkage, just end up writing most of the code in C and Lua? It certainly seem the effect of creating their own compiler (worse than gcc), an opaque "go" tool that does everything, project layout and hosting rules, complicated FFI, etc is to make a 'toolchain island' locking you into writing everything in Google Go, where you might not otherwise.

xyproto on June 15, 2012 | root | parent | next [–] You write "worse than gcc", but Go has been included in GCC since version 4.6: http://gcc.gnu.org/gcc-4.6/changes.html

0xABADC0DA on June 15, 2012 | root | parent | next [–] I guess you aren't aware that Google Go has their own compilers based on Plan 9 C compiler called "6g" or "8g" (depends on what architecture). These compilers produce much less efficient code than gcc does.

Yes, gcc now also compiles the language, but they still pimp their own compilers... iirc the "go" tool uses them by default (or maybe exclusively). Why create a new compiler? Why a project management tool that does everything except work with other build systems? Why isolate the language by making it difficult to use with others? I feel those are good questions to ask.

Graphon on June 14, 2012 | prev | next [–] People suggesting that Go is a potential replacement for Python, Lua or Ruby are missing the point. IMO, Go isn't designed to compete with those existing languages for existing opportunities.

The key opportunity in the future is smart devices everywhere. Embedded, connected intellgence, everywhere. Everything is a communication device. Today your phone and your car; tomorrow: Your shoes, your office, the grocery store, your refrigerator. Think of xbox Kinect-type sensors embedded into everything.

Writing solid C code for all those systems will be too hard. We also definitely do not want an serendipitously-designed language (Javascript). Yes, that leaves Python Ruby and so on, which brings us full circle. Go will compete with those languages but not in the domains that are evident today. Not in web browser, and not in a new! improved! web server. It seems to me that Go is a forward-looking design, aimed to meet the challenges of the everything-connected world of tomorrow.

To make tomorrow happen, we need a better C. Go is that.

heretohelp on June 14, 2012 | parent | next [–] Go is highly inappropriate in embedded environments so your pipedream betrays a naivete to systems programming.

xyproto on June 15, 2012 | root | parent | next [–]

* You can turn off the GC. * You can compile with gccgo. * You can call assembly code from Go. What is the major hindrance from using Go in embedded environments?

Graphon on June 15, 2012 | root | parent | prev | next [–] Today's embedded is not tomorrow's embedded.

In 10 years your sunglasses will have more compute power and memory than today's smartphone .

revelation on June 14, 2012 | prev | next [–] I can't do system programming using Go on a platform for which there is no compiler. There is probably a reasonable C compiler for every platform in existence out there.

aperture on June 14, 2012 | parent | next [–] Probably, but realize that at first this wasn't true. Go needs time to grow, just as C grew to different systems.

Looking at other systems such as Haiku shows that porting Go is encouraged, the only issues have to deal with assumptions in the build (in this case, I think /bin/env/bash is included everywhere, there's no global variable to change this definition from different OS types).

One day we may see a change in Go for different platforms, but I don't think it will prove to hinder that many people, only the niche groups. And for all intents and purposes, Go is built for practical application (!! Don't kill me !!), which systems programming on plan9 or haiku may not be considered "practical" at the moment.

EDIT: for clarity.

luriel on June 14, 2012 | root | parent | next [–] > Looking at other systems such as Haiku shows that porting Go is encouraged, the only issues have to deal with assumptions in the build (in this case, I think /bin/env/bash is included everywhere, there's no global variable to change this definition from different OS types).

I think this is not longer a problem with the new build system that is part of Go 1.

Also AFAIK at least the Plan 9 port is almost complete, and is certainly functional.

rwj on June 14, 2012 | parent | prev | next [–] Go is not a replacement for C. As many people have said, Go is not suitable for most purposes where C would currently be the best choice.

Go is a replacement for Python, Ruby, etc. Garbage collection, duck typing, an excellent library. Go is a language with the same level of abstraction of many other "scripting" languages, but is unique because it uses static typing and is compiled.

xyproto on June 15, 2012 | root | parent | next [–] I would say Go is a replacement for C++, Java and C# instead. Python and Ruby are great at quick prototyping, but Go fixes several of the major problems with those three. C++ takes forever to compile, code quickly becomes stale and the modularity isn't great. Java and C# lacks brevity, native compilation and the error handling is overly verbose and is in the way more than it helps.

nakkiel on June 14, 2012 | parent | prev | next [–] Well, back in the days it was pretty much the same thing for C. When someone needed to target a platform it used to mean writing a compiler for the said platform.

pjmlp on June 14, 2012 | parent | prev | next [–] That is what cross-compiling is for.

You use the compiler toolchain in OS A, while generating executables to run on OS B.

With a bootstraping compiler, you can use this technique to bring a native compiler to new platforms.

Devilboy on June 14, 2012 | parent | prev | next [–] Right now there's Go compilers for Windows, Mac and Linux. I'm sure others will follow soon.

vonmoltke on June 14, 2012 | root | parent | next [–] There is more to platforms than operating systems. I worked on an application that had to function on 8 different hardware architectures[0], though on all but one we ran Linux. We also had code that was bare metal (no OS) running on FPGAs and DSPs. Go is a long way from supporting that.

This is not to say Go will not get there eventually, if the language gains popularity. Someone had to write or modify a compiler to target all those architectures for C, after all. This is just a reaction to what I see as assumptions tying operating systems to certain hardware architectures (in this and other discussions). Go can be used on a range of operating systems on two hardware architectures. Very good progress, but the language needs to get that second number up before we can seriously talk about it replacing C.

[0] Only had to perform well on two, fortunately.

dchest on June 14, 2012 | root | parent | prev | next [–] + FreeBSD.

Also, OpenBSD, NetBSD, and Plan 9 in the works.

luriel on June 14, 2012 | root | parent | next [–] OpenBSD and Plan 9 pretty much work already, even if the ports might not be as polished as FreeBSD.

Also there is gccgo, which AFAIK also works on Solaris and probably elsewhere.

4ad on June 14, 2012 | root | parent | next [–] Yes, it works on IRIX and RTEMS (an embedded OS), and the gc suite was also ported on Ethos.

I'd also like to add that the gc compilers support ARM as well as x86 and amd64 and are very, very easy to port to new platforms.

kristianp on June 15, 2012 | prev | next [–] Mods, the title should be "C to Go", Go is not spelled with all-caps.

iamgopal on June 15, 2012 | prev | next [–] err..sarcasm ?

papsosouid on June 14, 2012 | prev | next [–] Go is the best worst language I've used. Most of what I do fits pretty much right in the sweet spot for go, network services and web development. Stuff I would have previously used C and (insert scripting language here) for respectively. Go fits into both of those areas really nicely, and I prefer it over C and scripting language X for these tasks.

But the problem is, I've already tried haskell, which also fits that same area, and is semantically a vastly better language. I just wish go had been more willing to push the envelope and at least try to be somewhat modern and useful instead of being "C with modules, but slow". On the other hand, haskell is a terrible language syntactically, and from a development environment perspective. Go is near enough to perfect in those regards. Having a fast compiler, a simple, working build system, a sane and easily enforced code format all make a huge practical difference. I wish I could use go, as it is much nicer than haskell from a usability perspective. But the language is just too primitive.

eeperson on June 14, 2012 | parent | next [–] Might I suggest Scala[1]? It is a modern languages with mature build tools and development environment. It also has a lot of nice tools surrounding network services and web development[2].

[1] http://www.scala-lang.org/ [2] http://typesafe.com/stack

papsosouid on June 15, 2012 | root | parent | next [–] You certainly can suggest it, I already tried it though. ;)

Scala ends up more like the worst aspects of haskell and go combined, rather than the best aspects of both.

soc88 on June 15, 2012 | root | parent | next [–] Details, please.

papsosouid on June 15, 2012 | root | parent | next [–] Pretty much what I described above. The bad parts of haskell (compile time, memory usage while compiling, bad syntax, terrible dependency/package/module management) are all present in scala, and it is semantically an inferior language to haskell. Scala is certainly a whole lot closer to haskell than go is, and I certainly don't blame anyone involved in the creation of scala for its limitations, the JVM limits how good they can get. But at the end of the day, using scala would solve none of the problems I have with haskell, and leave me with a less powerful language.

eeperson on June 15, 2012 | root | parent | next [–] Out of curiosity, what make the Go dependency management so good? I'm not terribly familiar with this aspect of Go. Based on a what I've read, it doesn't seem dramatically different than what you would do for Scala (except it is packaged with the language rather than an external tool like SBT). Is there something I am missing?

papsosouid on June 18, 2012 | root | parent | next [–] SBT just fails to work correctly on a semi-regular basis. Quite a few scala people ended up resorting to maven instead, which says a lot.

eeperson on June 19, 2012 | root | parent | next [–] That has not been my experience at all. SBT has always worked correctly for me.

When was the last time you used Scala and/or SBT? I know a lot of the tools in the Scala ecosystem were unstable prior to Scala 2.8. However, now they have become pretty good. Even the, previously notoriously bad, Eclipse plugin has become good.

papsosouid on June 20, 2012 | root | parent | next [–] ~6 months ago. I'd certainly say the eclipse plugin has improved a lot, it's better than the intellij one now. It is still quite a ways away from good though.

soc88 on June 16, 2012 | root | parent | prev | next [–] Well, I guess will have to agree to disagree here.

From my perspective Scala solves a lot of problems with Haskell:

- Working module system (From my experience, especially people coming from OO languages are surprised that this is such a huge unsolved problem in Haskell, because all the languages they know have come up with a working solution.) It will be interesting if some OCaml-style module system as currently discussed makes it into Haskell.

- It is much easier to reason about space consumption.

- It benefits from the best general-purpose VM with its superior garbage collection algorithms. (I agree that the lack of VM features is deeply annoying.)

- Tons of tools for monitoring.

- Debuggers. I'm not certain that Haskell will ever have decent debugging capabilities, taking its approach to laziness and compilation into account.

- Exceptions which don't leave the developer wondering where exactly an error has occurred. (Stack-traces, anyone?)

- Libraries for basically everything. Even if you don't use them, you can have a look at how other developers have approached a certain problem.

- Tool support. The Scala IDE alone has 10 people working on it. Compare it to Leksah and EclipseFP.

- Commercial support. Scala has Typesafe (> 30 people) and dozens of partners, consultancies, etc. In Haskell, there is Well-Typed, which is more or less payed by the “Industrial Haskell Group” (which consists of Galois and Amgen).

- The REPL is just a lot more usable.

I don't have any problems with the compile time. When developing in Eclipse there is just no delay between pressing “Run” and the execution of the program. It is instantaneous.

Syntax ... well, that's a completely subjective topic.

“terrible dependency/package/module management” ... SBT delivers a top-notch experience here. Have dependencies as source on sites like GitHub? SBT will fetch and build them without problems. Need to deploy artifacts into the local repo, to Maven Central or other services? SBT will happily do that. Need to cross-compile to different versions? Easy. Want to build software for Android? SBT will compile, jar, proguard, dex and install it on your device in seconds. I would love to hear what you would like to see here!

“semantically an inferior language”: Well, I guess every language is inferior to Haskell. I appreciate the hard work done in Haskell to track side-effects and other things. While I don't think these exact approaches will ever see much adoption, it leads the way to more manageable approaches. I'm pretty sure computer science will come up with some great solution in the next decade and Haskell will play its part here.

“less powerful language”: Well, it depends on what you mean with “Haskell”. “Haskell” == the Haskell standard? Scala is a lot more powerful than that. “Haskell” == GHC with all its proprietary extensions enabled: Yes, probably.

I don't think Go is really comparable with Scala or Haskell. It feels a bit like it was designed in an ivory tower. It is certainly a nice language if you ignored the last 20 years of progress in language design and have never used anything except C.

Let me know what you think and if I missed something!

papsosouid on June 18, 2012 | root | parent | next [–] Most of what you listed as "solved" by scala isn't a problem in haskell in the first place. The JVM is a problem, not a solution to the problem haskell has of "actually working". Listing "our possible semantics are gimped by java" as a feature seems rather bizarre. Debugging? Have you ever tried debugging haskell? It works just fine.

>Tool support. The Scala IDE alone has 10 people working on it. Compare it to Leksah and EclipseFP.

I don't think insulting the people working on the scala eclipse plugin is very productive. Yes they have more people, and yes it is annoying that it is still not as good as haskell's eclipse plugin, but give them some time.

>The REPL is just a lot more usable.

In what way? The fact that it is way slower? You seem to be just listing random things as if you've never tried haskell.

>SBT delivers a top-notch experience here

You are the first person I've ever seen make that claim. Hell, people use maven because SBT is so bad.

>I don't think Go is really comparable with Scala or Haskell. It feels a bit like it was designed in an ivory tower

You might want to look up what "ivory tower" means. That is the most backwards characterization of go I've ever seen.

soc88 on June 20, 2012 | root | parent | next [–] Sorry, I'm not really sure if you're trolling.

papsosouid on June 20, 2012 | root | parent | next [–] I'm pretty sure "post a bunch of obvious nonsense, then call anyone who disagrees a troll" isn't considered appropriate behaviour on HN.

drivebyacct2 on June 14, 2012 | parent | prev | next [–] What have you written in Go that you'd wished you'd written in Haskell?

papsosouid on June 14, 2012 | root | parent | next [–] Everything, and the same in reverse. That's the problem. Using haskell, I wish I was using go because the downsides of haskell bother me. But when I am using go, I wish I was using haskell because the downsides of go bother me.

drivebyacct2 on June 14, 2012 | root | parent | next [–] Ah the quest for the perfect mix of everything. I sympathize but I've generally found that there are some things that are better solved in Haskell and others in Go and have found a generally pleasant balance.

papsosouid on June 14, 2012 | root | parent | next [–] I see. For me I haven't found anything like that, where task X would be better in go and task Y would be better in haskell. Everything I've done was always better in haskell. It was just an annoying pain in the ass the whole time because of super slow compile times, or running out of RAM compiling, or package conflicts from cabal hating me, or .cabal files requiring spaces instead of tabs, or haskell code I want to modify being some giant mess of arbitrarily aligned with a million spaces craziness that makes cool things like "diff" useless. It just feels like rather than "haskell needs to stop being so crazy", the "go needs to gain modern features" approach is more likely to actually be possible.

xyproto on June 15, 2012 | root | parent | next [–] You can create a tool that lets you inline Haskell code in your Go sources. The resulting code could be compiled and called via C, some sort of IPC or even as a network service.

drivebyacct2 on June 14, 2012 | prev | next [–] I've been using Go exclusively in my personal projects for the last 8 months now, am in love with the simplicitly and fun of writing it (and goroutines), but this is a horrid way of introducing the language. To anyone who doesn't appreciate the Go syntax style, this is an instant turn off. There is a reason there is an idiomatic style used by... every single Go project I've ever seen.

Further, these examples are so trivial that one doesn't see an advantage over C and so this comment thread is like every other. Those who've written "Hello World" dismiss it as neither C nor Haskell and most others seem to be generally happy with it.

tubbo on June 14, 2012 | prev | next [–] I mean, the only other living inventor of C is working on Go...

millerfung on June 14, 2012 | prev [–] In my opinion, any new language today should be all beginner friendly, there are large pool of people who are interested and it means a great future of our world.

EliRivers on June 14, 2012 | parent | next [–] "any new language today should be all beginner friendly"

I disagree. I think any new language should be designed to best meet the kind of problem it's being created to deal with. Making it "beginner friendly" (whatever that means - I bet there are lots of different interpretations) is a nice extra, but should not come at the expense of solving the problems.

millerfung on June 14, 2012 | root | parent | next [–] Yes I agree that new language should be developed because of the ever rapidly changing digital world to enhance everyones experience in digital products. I am sure it is going to get more complicated, however, being a beginner friendly language should still be taken into account. In fact, only the one who is more beginner friendly will survive in the long run because in the future there might be a mismatch of demand and supply of coders. Living in this moment of our planet is exciting because of the experience we have having digital products around us everyday, and there are/will be lots of teenagers who wants to get involve as well. In my opinion, coders are like "workers" in manufacturing companies in the future.

EliRivers on June 15, 2012 | root | parent | next [–] "In fact, only the one who is more beginner friendly will survive in the long run"

That makes no sense to me. In any industry with a sizeable number of workers, there is a huge range of tools, from the entry level easy-to-use up to the fantastically intricate and arcane. Tools that are not "beginner friendly" are that way for a reason.

As an example, assembly code is never going away; for the obvious reason that if nobody understands it, nobody can write compilers, and also because there are cases where knowing assembly is useful and helps to make better code, whether it's taking apart the code to really, truly get every last clock-cycle of power out of the thing, or to take apart code in the search for arcane bugs and wonderfully subtle interactions causing unexpected behaviour. Assembly is old, and will never go away, and is (for most meanings of the phrase) not beginner-friendly.

The only advantage to a language being "beginner friendly" is that beginners can learn it fast. What you then get are inexperienced programmers who know just enough to be dangerous (this is not an attack on them; it's the case in any industry with a low barrier to entry, and a stepping stone to being better). One expert, experienced programmer with knowledge of a "beginner unfriendly" language is worth literally dozens of first-day coders wielding their hand-holding, garbage-collecting, counting-begins-at-one modern version of BASIC. That is never going to change, and every first-day coder wants to become that expert.

Even if somehow all the non-"beginner friendly" languages died, the very next day someone who'd been coding in this "beginner friendly" language for a decade would finally get sick of it and start designing a language she can truly express herself in without having all the hand-holding that holds her back.

millerfung on June 17, 2012 | root | parent | next [–] That's a very good argument, I will accept this :) hopefully, at the end, there is a language that is easy to understand at first and therefore people could easily pick it up, like English?

jaybill on June 14, 2012 | parent | prev | next [–] What kind of "beginner"? If you mean someone who has never programmed before, Go is much simpler to learn than C and makes a lot more sense.

If you mean someone that is a programmer and hasn't used go before, I can tell you I went from "never having seen Go before" to "reasonably proficient" inside of two months. Further, my Go code is easier to read and maintain than anything I've done in other languages. (I came largely from Java, so maybe that's not saying much.)

I think that for beginners of either kind, the documentation and community support are just as important as the language itself. I mean, look at something like JavaScript, which is picked up by "beginners" all the time and is, frankly, obtuse as hell. Go has great docs and a really friendly and helpful community.

millerfung on June 14, 2012 | root | parent | next [–] Wow, that is very good. I am total beginner in coding so there is nothing much I could say but I am just saying from a total beginners perspective. What would be your suggestion for me if I am planning to build some social application? Learn C first to gain some fundamental knowledge? And because it is still the most widely used language, if I don't know it I wouldn't be able to find a work in the future?

jaybill on June 14, 2012 | root | parent | next [–] I think that really depends on your goals. If your goal is to bash out a web application and get a startup off the ground, you ought to learn something that is tailored to doing that. Ruby on Rails and Django(Python) aren't bad choices. I'd avoid PHP, but that is my opinion and you'll find lots of people who disagree. Research your options and learn something that makes sense to you and will enable you to bring other people on later.

If you want to launch a career as a systems programmer, which is a fundamentally different goal, then yes, you should learn C, even if you end up using other things.

millerfung on June 14, 2012 | root | parent | next [–] Thanks. Currently, in your opinion, what kind of programmers are high in demand and what skill set does it require?

jaybill on June 14, 2012 | root | parent | next [–] Two part answer. First, I don't know the answer to that off the top of my head. Second, though, is that I don't think it matters. You need to find something you like to do and then get someone to pay you to do it. If you don't do that, the money won't matter, because you'll be miserable.

genwin on June 14, 2012 | root | parent | prev | next [–] That depends on the city. Guage demand by checking out monster.com, indeed.com and other job sites (craigslist?) for the city or cities you're interested in. Job postings tell you the skill sets too (no two of them alike!).

luriel on June 14, 2012 | parent | prev [–] Go is relatively beginner friendly, is simpler and smaller than most languages around (even for example Python). Go code is concise but without dark magic (is easy to see what code does by just looking at it). And you can even read the whole language spec fairly easily.

kibwen on June 14, 2012 | root | parent [–]

> smaller than most languages around I'm not certain that this is specific to Go, insamuch as it's a property of nearly all young languages. After 1.0, language complexity can only ever increase. Even Python has followed this trajectory, although Python should perhaps be commended for being willing to shed some of its complexity along the way (depending on how you view backwards-incompatible changes, some would say it should be denounced rather than commended).

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact Search:

Từ khóa » C Vs Go