Try doing that in C/C++.
Maybe a better comparison is to more systems-level applications like you might code up in C. The same benefits carry over to those, without a significant performance hit (usually).
(And to be fair, sometimes C/C++ is the better tool for the job. But give it a shot; Go is pretty handy when you don't need to drop down to lots of unsafe memory and CPU operations.)
By the way, your existing C skills will be very useful in Go. For example, struct fields will still be padded unless you pack them carefully. Your experience with buffers, streams, memory allocation, and data structures will definitely not be wasted in Go.
NodeJS runs on top of C++ :P
With std.
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n424...
"panic: runtime error: invalid memory address or nil pointer dereference"
Just saying, they should probably improve it to be less verbose and more concise.
It's literally (SIGNAL) / (NOISE), so if the noise is larger than the signal, the ratio goes down.
I just wanted to point out that not having to worry about segfaults is clearly wrong.
Go doesn't really take any steps from preventing pointers from being null or forcing you to deal with possibly null pointers, or accessing uninitialized maps or slices.
The parent of this comment said "without worrying about dependencies, dynamic linking, or segfaults".
This is blatantly wrong. Pretty sad what HN has become.
(Disclaimer: Not a Go programmer, just read articles about it.)
Lua.
Put in a less snarky way, C is often way more low-level and tedious than you need.
The great thing about Go is that it lets you blend high-level and low-level programming in the same program, only getting low when you need to. It feels like a great mix of C and Pythonubyerlhphavascript.
I've given many talks on this, e.g. http://talks.golang.org/2014/gocon-tokyo.slide#1
Well, I wouldn't go there (C is antiquated/under-equiped like an abacus) if I was advocating Go.
After all, Go, just like an abacus doesn't have generics, or, besides channels and goroutines, most other facilities modern languages offer for that matter (GC and some basic data structures built-in is so 1980).
If you need mainly a large number of features in order to program, Go probably isn't for you. But from the perspective of a C/C++ programmer, this isn't likely to be an important point. Languages with more features than C have been available for 40 years (depends on what you'd count as a feature), so there were plenty of "better" choices in that regard available for said people.
For me, the lack of some "features" is a great asset for Go, I probably wouldn't have bothered to learn a new language if it had boasted the complexity of Rust or Haskell.
Where are map, reduce, select, filter, fold, zip ...?
I don't consider hand-rolling them in for/range as equivalent. Can I wind up with the same result? Yes. But I could do it with gotos too.
And I've seen "loops are the same as map/reduce etc" advanced as a serious argument by people who weren't, so far as I could tell, trying to tug on my leg.
What gets my hackles up is claiming that "it's just the same".
The same argument works for any language that satisfies the structured programming theorem, including assembler.
"If writing simple BNE $reg gets your hackles up, Assembler is not the language for you."
I look forward to seeing how I can chain multiple operations on a set into a single line of Go.
Also see the aforementioned "the answer is to write a loop".
It is not the same.
Saying "supports higher level and lower level" programming when you don't actually support most higher level programming primitives is also, from my point of view, untrue.
Go's design choices are what they are, which is fine. But I just see a lot of people who argue, in all seriousness, that a loop has the same level of abstraction as map, filter etc. It simply doesn't.
That languages are turing equivalent doesn't mean that they operate at the same level of abstraction; trying to pass one off as being "the same" as another is just silly.
Instead, since Go is a very simple language with very easy learning curve, I encourage you to spend a weekend to check it out. Pick a side project and do it in Go, then you will know if it's the language for you.
I would even argue that the joy of writing Go would be magnified by working as a team and the joy of reading Go would be demonstrated by exploring any Go project from any team. But I would not go that far for a Go novice who just want to check it out
If there's a reason you must be using C rather than another language (require manual memory management, require code to be as fast as possible, etc.), then Go might not be applicable. Otherwise, Go feels like an updated C and I don't see a compelling reason not to invest a little time in checking it out for yourself.
It's also pretty easy to write the performance critical parts of the code in C and call them from Go.
Deployment is where Go shines. You don't need nginx or a specific runtime, or uwsgi. You just deploy the file and run it. It runs its own web server. The web server is on par with nginx for performance, and is as stable as your code is (which is generally very stable, since Go's error handling is very explicit). And of course Go code in general is approximately 10x as fast as python.
> There are no silver bullets with regards to safety in C/++ code; in order to achieve security, the programmer has to pay the price of being forever vigilant.
A lot of the complexity of Rust is for eliminating security pitfalls which are inherent in C/++.
What is unsafe about using atomic reference counting?
> and unsafe shared memory access in Rust.
That should be provided with a safe interface, or an unsafe interface if calling that code is not safe.
As for it being common: I think they are working on minimizing the need for unsafe code.
> This defeats the purpose of this complexity.
Like having a VM implemented in C defeats the purpose of the VM for that language being safe. No, not really - that C code has to be really vetted, just like unsafe code in Rust has to be really vetted.
I guess we might - eventually - be able to formally verify a language implementation, thus really proving that a language is safe (that goes for those managed languages, too). Maybe that will be feasible in a few decades, if ever. Alternatively, you can use the ATS language, where you can prove that unsafe usage of pointers etc. really is being used in a safe way.
> You can't isolate unsafe memory access.
Sure you can - owned and borrowed pointers in Rust are represented as raw pointers at runtime. It's a safe abstraction. And if there turns out to be a bug in that interface, and they aren't really safe, then that will have to be fixed promptly - unlike in C/++, where one would be forced to say "Well, that's your fault for not being careful".
Nothing at all. But sharing objects between threads is unsafe.
> Like having a VM implemented in C defeats the purpose of the VM for that language being safe.
You can prove that VM code is memory safe? Good for you.
> Sure you can - owned and borrowed pointers in Rust are represented as raw pointers at runtime. It's a safe abstraction. And if there turns out to be a bug in that interface, and they aren't really safe, then that will have to be fixed promptly - unlike in C/++, where one would be forced to say "Well, that's your fault for not being careful".
And in C++ we have value and move semantics. Nobody uses pointer arithmetic to implement arrays and strings anymore. std::unique_ptr is a standard way to implement the same semantics as borrowed pointers in rust. Array access can be range checked if you want. So being careful in C++ is easy today, can I say that C++ is safe? :)
If sharing stuff between threads in Rust is unsafe, then that is a bug which you should report.
> You can prove that VM code is memory safe? Good for you.
Uh, that's my point... VM implementations are usually not proved to be safe, any more than unsafe code in Rust is proved to be safe.
> And in C++ we have value and move semantics.
Which aren't bulletproof - if you're not careful, they can be used in an unsafe way. Well, this is second-hand information, so take that for what you will. You could ask pcwalton about it if you want a truly informed opinion.
> So being careful in C++ is easy today, can I say that C++ is safe? :)
Sure you can. You can say, "My code is safe, because I only use feature X, Y, Z / because I avoid this and that...". While someone using Rust should be able to say "My library is safe, since I make no use of unsafe blocks".
> Nothing at all. But sharing objects between threads is
> unsafe.
This is mistaken, as sharing immutable data between threads is trivially safe, and Rust's type system gives you the tools you need to prove that data is actually immutable (good luck sticking anything in an Arc if it contains an Rc (or any other non-Send type) anywhere within it). And sharing mutable data between threads can be safe if you get the locking right: Rust gets the locking right for you, so that you don't have to. > std::unique_ptr is a standard way to implement the same
> semantics as borrowed pointers in rust
No, std::unique_ptr is analogous to the Box smart pointer in Rust, except more onerous to use because move semantics are not the default in C++. C++ has no equivalent to Rust's borrowed references. > So being careful in C++ is easy today, can I say that
> C++ is safe?
Sure, if you're willing to throw out all C++ code written before C++11, and if you're willing to lower your standards of "safety" to "trivially, silently, and often surprisingly unsafe". :) I actually have a higher opinion of C++ than most developers you'll find (PHP too, but that's a different story...), but let's not pretend that safety is at all C++'s forte.Rust is safe by default. You have to opt-out to head into dangerous territory.
That difference may be trivial to some, but to me, it's enormous.
> It is common to use ARC and unsafe shared memory access
> in Rust
This is false. `Arc` is not common, and when it is used, it is to enable safe shared memory access. > You can't isolate unsafe memory access
This is also false. If you get memory unsafety outside of an `unsafe` block, it is a by definition a bug in the compiler.All `unsafe` memory access in Rust performed in separate address space? I'm asking because if it isn't - this can't be called `isolated`.
> If somebody needs memory safety - managed languages with
> GC is the only real option
If I'm in Java, I can call C code via JNI that does whatever garbage I want with the memory of the Java program. There's no isolation there; we are thwarted by the need for FFI. Likewise, `unsafe` in Rust is just a reified FFI: it allows you to do things that Rust doesn't allow you to do, but, crucially, `unsafe` blocks in Rust are still much safer than the C code that you'd otherwise be writing. Thus `unsafe` is a mechanism for making Rust programs safer than they otherwise would be, by avoiding the need to call into C.I'd like to see some evidence if you have any.
Rust has great performance in general - and I also agree that it is an appealing language - but I haven't heard anyone claim better than C++ performance before. I'd be very dubious of anyone making that claim...
Many of the tests boil down to "Does your language have GMP bindings" or "Can you write non-idiomatic code to theoretically make this as fast as something else?"
In other words, I don't find it to be useful, except in the absolute broadest sense.
Exactly one task might be described as boil down to "Does your language have GMP bindings" and that shows:
1) differences with the same language implementation and same GMP binding
2) differences with the same language implementation with/without GMP (for example, Rust #2 and Rust #1)
3) differences with different language implementations' use of GMP.
None of the tasks boil down to "Can you write non-idiomatic code to theoretically make this as fast as something else?" -- if you don't want them to!
If the Rust programs shown on the benchmarks game are "non-idiomatic" it's because so-far that's been the choice of the Rust community.
You know what you mean by "in the absolute broadest sense" but we don't.
For example, look at the history of D being in the game vs. not. Generally speaking, all of http://benchmarksgame.alioth.debian.org/play.html#languagex is incredibly arbitrary. I don't think that the maintainers of the game have some sort of moral obligation to support things they don't want to, but it is an arbitrary line which influences what kind of benchmark it is.
As another, the domain of the examples, which are largely related to numeric computing and/or memory usage. Which is fine, but isn't going to give me information about other use cases.
> None of the tasks boil down to "Can you write non-idiomatic code to theoretically make this as fast as something else?" -- if you don't want them to!
Yes, they do. Because one man is not an island: people use the raw numbers of the Benchmark Game to claim "X is faster than Y", even if the implementation of X and Y are totally different than what their implementation would be.
> that's been the choice of the Rust community.
I'm actually not thinking of Rust here. I'm thinking more of languages like Haskell, who have implementations that look significantly more like C than like Haskell.
But regardless of if the implementations are idiomatic or not, it means that The Benchmark Game is useless for evaluating if a program I write in a language is going to generally be faster or not than if I did it in another. Because this isn't the code that I'd write: it's code that takes advantage of every little last corner to get as small a number as possible.
1) That might be a credible criticism if the benchmarks game claimed to be some kind of exhaustive comparison.
In fact (if it wasn't already completely obvious that the benchmarks game has nothing to say about things it does not show) over & over again the web pages state -- "These are not the only compilers and interpreters. These are not the only programs that could be written. These are not the only tasks that could be solved. These are just 10 tiny examples."
2) You seem to have assumed that because you personally don't know the reasons, there were no reasons.
>>…totally different than what their implementation would be.<<
What does the benchmarks game have to say about those "totally different" programs that are not shown? Nothing.
>>…more like C than like Haskell.<<
http://benchmarksgame.alioth.debian.org/u64q/program.php?tes...
Idiomatic Haskell? Which would that be?
http://www.willamette.edu/~fruehr/haskell/evolution.html
Do you think there's an idiomatic style for programs written as though performance matters or does idiomatic just mean programs written as though performance doesn't matter?
>>…useless for evaluating if a program I write in a language is going to generally be faster or not than if I did it in another.<<
Does the benchmarks game website claim to be useful for that purpose? It sounds like magical thinking to me --
"… but the question is still asked - Will my program be faster if I write it in language X? - and there's still a wish for a simpler answer than - It depends how you write it!"
http://benchmarksgame.alioth.debian.org/dont-jump-to-conclus...
It's magical thinking to say otherwise: just because something doesn't claim to be X (or claims to not be X) doesn't stop popular opinion from thinking X. Maybe popular opinion is wrong, but it exists and it's what we have to contend with.
e: random recent example of someone doing this sort of comparison: https://news.ycombinator.com/item?id=8743698
How could it? Some kind-of black magic?
The benchmarks game is just a resource. In the example you provided a discussion is taking place, and some opinions are being challenged.
> These are not the only compilers and interpreters. These are not the only programs that could be written. These are not the only tasks that could be solved. These are just 10 tiny examples.
etc.
But now you are saying that obviously people will do naive comparisons using the benchmarks game. This validates the dislike of widely publicised one-dimensional benchmarks like the benchmarks game (NB this applies to a lot of benchmarks on the internet, the benchmarks game is just a particularly famous example, please don't get too defensive again).
Sure a discussion is taking place, but essentially any discussion about the benchmark game degenerates into either an argument about why the benchmark game doesn't cause one-dimensional comparisons (with the pro-Benchmarks-Game side consistently being overly defensive), or an argument about why using every unsafe corner of language X to basically mimic the fastest C program is perfectly reasonable, idiomatic and common in the real world.
Please quote my words that you claim say that.
(I.e. literally your paragraph before the thing I quoted in my comment just above.)
Those words say that they do so in-spite of what's shown on the benchmarks game website, not because of what's shown.
Given the comments you have already made, that seems to be a self fulfilling prophesy.
On the other hand, Rust also has specific areas where it is slower by default than C or C++. The most dramatic example here is that array bounds access is checked by default, with an unsafe method call for doing unchecked access. It strives to bypass this restriction by leaning heavily on iterators, which are an abstraction that allow you to safely omit the bounds check.
In the end, all that matters is that both languages offer zero-cost abstractions, so the ultimate arbiter of speed will be the optimizer on the backend. Saying that Rust is "faster than C++" is definitely premature at this point; I'll reserve that judgment for when it at last starts making use of all its free aliasing info.
I also found it's faster to read the library code than the docs. A lot of thought has gone into making the language and library clean and easy to understand.
Usually it's a list of methods on a package.
Beyond that, I would not recommend it. I think a lot of people get caught up in the fact that A) it's hip and new and B) it's managed by Google. Without knowing what you want to do with it, I would recommend any number of languages (Rust, Haskell, Julia, etc.) before learning Go.
(it's going to interesting to see battery life of not running an interpreted language on small devices like Android Wear).
- safe and easy programming (really!)
- no more shooting yourself in the knee with hard to debug problems
- lean but quite complete standard library
- native strings (proper unicode/utf-8 handling)
- very little boilerplate, sane defaults
- concurrency primitives (no tacked-on libraries)
- high performance - not far behind C/C++
- extremely easy and practical documentation features (via comments)
Really, things like concurrency primitives as a point in Go's favor? Running code on several processors at once is where it's good to have a library because there are tons of knobs like priority and scheduling policy for instance; it's been trivial to deadlock or arbitrarily delay an entire Go program just by having GOMAXPROCS busy loops and there's no scheduling control at all last time I checked. Meanwhile shared data locking isn't even in the language despite being at a very fine level where using libraries can be cumbersome.
And Go comments as good documentation is another mind-boggling claim. It's a mostly free-format with few machine-readable parts. Most functions don't even explain what types of errors can be returned, just "err Error". It's so bad it isn't even comparable to JavaDoc or C#. How can you have "safe" programming when you have to dig through sources to even find out what the error conditions are?
There is a good reason to use Go and that's to feel like a pioneer. But few technical reasons.
C# on Mono certainly isn't significantly better performing than Go from my experience, which is substantiated by Go winning all but one of the 'Benchmark Game' benches, typically by quite a wide margin:
http://benchmarksgame.alioth.debian.org/u64q/benchmark.php?t...
And Go is not doing that bad against Java either:
http://benchmarksgame.alioth.debian.org/u64q/benchmark.php?t...
Go should be faster than JVM Java at microbenchmarks due to no dynamic loading and precompilation, instead it's only faster on some really tiny algorithms possibly even due to just fitting in the cache better because the GC runtime is so basic. So if you want to write some simple command line tool Go maybe it'll be slightly faster than Java. On anything that uses much memory JVM destroys Go on performance.
So performance is not a reason to write something in Go -- in fact it's just the opposite. Since you can't control the coroutine scheduling you can't do anything about latency spikes or starvation or anything else that can cause performance problems in multithreaded programs.
I work mostly in Scala, but there's a lot of similarity, and I think the main reason we're seeing it take off now (10 years after originally released) is that the kind of problems where it's really useful are becoming a lot more common. If everything's in the cloud, you need a language that's good at distributed problems. If you need to handle huge volumes of data, you need something more flexible and explicit than traditional languages. If you're using too many layers of technology to understand what they all do, you need a language that can help you keep track of them.
https://news.ycombinator.com/item?id=8332835
https://news.ycombinator.com/item?id=8356677
http://blog.senko.net/learning-go
_________
Books: