Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Out of mild concern over the title (not that it ought to be changed, TFA doesn't really have a meaningful title), I'd like to preemptively defuse any potential flame war.

Go and Rust are not really competing. There may be some overlap in domain, but they occupy different niches and will likely appeal to different crowds. Go will appeal more to people who prefer its focus on conceptual simplicity and its "opinionated" nature (very much like Python). Rust will appeal more to people who prefer "functional" trimmings (algebraic datatypes, pattern matching, liberal use of higher-order functions, Scheme-style macros) as well as folks fed up with C++ who aren't willing to give up complete control over memory and performance characteristics. The fact that both languages are built around a similar concurrency model is just convergent evolution.

It's tempting to cast Go vs. Rust as Google vs. Mozilla and/or Chrome vs. Firefox, but there's no practical reason that both languages cannot peacefully coexist and thrive.



The two languages aren't really in the same space in the first place. Go is a simpler language that leans more heavily on garbage collection. Rust is a more complex language that can be safely used without the GC at all.

Go is a great language -- I greatly admire its simplicity -- and for its domain it's fantastic. Rust is in a different domain: low-level systems programming in which abstractions must be zero-cost and control over the machine is crucial.


Go actually provides what I believe to be zero cost abstractions that map straight to the c memory model, making it very easy to use for systems programming.

If you want a fixed size array of bytes, for for it. Zero overhead. If you want a slightly smarter list you can use a go slice, which is also pretty low overhead. I've personally verified that if I create a struct in go it takes up the exact same amount of memory as the same c structure.

As a concrete example, I recently built an interface to kernel crypto apis using pure go (no cgo). There's no magic to go data structures, you can define structs in go and pass pointers directly to syscalls (through the syscall package) and everything just works. Dealing with large arrays of binary data is similarly straightforward. So go does give you complete control over memory layout if you choose to use it.

The elephant in the room is that go does have garbage collection, and that ain't free. Practically you can minimize it's impact by managing your own memory. In fact that's what Brad Fitzpatrick is doing with his go based memcached implementation.

It all boils down to how you define systems programming. I guess if you mean is go suitable to write a kernel in, the answer is probably no, (but it would sure be fun to try). If systems programming requires having the complete ability to interact with the operating system and all syscalls + tight control over memory layout, then maybe go is the way to go.

https://github.com/shanemhansen/gocryptodev/

[edit]

with respect to python and garbage collection, did you know you can actually turn it off? If you have no cycles in your program you can turn off gc and let the ref counter clean up all your data, similar to Objective-C's ARC.

http://docs.python.org/library/gc.html


There is a lot more to zero-cost abstraction than memory layout. If you do manual memory management in Go, then you get no safety. It is also difficult to use the standard library with manual memory management. Furthermore, interfaces in Go are not zero-cost; you incur virtual dispatch whenever you use them.

The article is about doing safe manual memory management. That's something that's unique to Rust.


FWIW, Rust's arrays and structs are also laid out in memory exactly as C's are.


> The elephant in the room is that go does have garbage collection, and that ain't free.

Since HN is Lisp country, it has to be said that having GC isn't an "elephant in the room" - though a slow GC implementation may be.


> If you want a fixed size array of bytes, for for it. Zero overhead.

There's the overhead to check the bounds on operations in that array, which you don't have in C.


Simplicity is absolutely the most crucial aspect of a language used for successful commercial application in my space (15-30 mil annual). That's what I like about Go. Don't know much about Rust, but if it's being designed by a small group of engineers who think oop is still awesome, then successful commercial software developed in Rust will be just as costly to maintain as the 500k to 5 mil line codebases I run across today, written in currently available languages.

Speaking in general:

You get all this wonderful language functionality, and I promise you that you will write some shitty code at some point just to keep up with the daily pressures presented by a successful software package (clients screaming, salespeople breathing down your neck, etc), I don't care how good of an engineer you think you are. What's really funny is that, because everything has gotten so much more complicated (dev tools, business, cost of bugs going up, how to make money with software, whatever), the successful software I work on today is not making any more money than the successful software I worked on back in the late 80's running under DOS. Back then, the oop free tools and the target os were simple enough that we really could become SME's on our domains as well as on the dev tools we used to write code for those domains.

C# and java are definitely not the solution for new applications which are expected to generate revenue for the next 10 years. If Rust is just trying to be smarter at what these languages already do, I'm not interested. Something has got to come along which simplifies development, especially concurrency, and allows programmers of varying skill levels to write productive code in. Then after 5 mil loc, programmers coming and going on a project, an app doesn't end up looking like a fragile mess.


Rust is not particularly object-oriented; idiomatic Rust code leans more toward the functional style as opposed to the OO style.

The language is designed to make it harder to write buggy code at the cost of some amount of language complexity. Whether this is an acceptable tradeoff will depend on your particular situation.


>C# and java are definitely not the solution for new applications which are expected to generate revenue for the next 10 years.

That doesn't even make sense. Both C# and Java (and JVM, CLR languages) will be used in new billion generating applications in the next 10 years and more.


I should have said "generate competitive revenue." Sorry about that.

If you're still using C# or java in 10 years time for a commercial app, the only reason you will not be at a competitive disadvantage is because all the other competitors in your space are using the same languages.


> programming in which abstractions must be zero-cost and control over the machine is crucial

How well does Rust do in this zero (or low) cost department? In C++ STL there's the same goal, but it compiles to code very far from what you would write in assembly without abstractions.

Eg. how are code compactness and data layout optimizations?


Not sure what you mean here. Rust tends to be pretty dependent on inlining optimizations, just as C++ is. As for code compactness, the way we do task failure leads to significant code bloat at the moment (though that's on track to be fixed, and the code is off to the side and not executed unless you actually fail). As for memory layout, the rules follow C; struct fields are laid out in the order you specify them in the code, and so on.


For what it's worth, I like Rust because I like Python. Python does strive to have one "obvious way to do it", but that ends up meaning it has a very colorful toolbox full of different ways to solve different problems, much like Rust. Generators, context managers, metaclasses, decorators, and descriptors are all very different mechanisms, but they all work together well.

Hell, I keep discovering that Rust has already implemented language features I'd independently thought up half-baked versions of.

And not to encourage a flamewar, but I believe there's a gigantic unspoken niche that Rust and Go will be fighting over: people like me who stay away from systems programming because it's a pain in the ass. C is tedious, C++ is bozotic, D is obscure—so the lowest I've bothered to go for a while is Cython. But now there's Rust, and I'm genuinely enjoying it, and I see other people who've mainly been sticking to Ruby or Python who are enjoying Go. This will be interesting to watch. And regardless of what I think of Go, I'm glad there's finally some activity in this space again. :)


I have not had time yet to look into rust more closely, but do you know if it would be able to export a Rust module in a dlopen-able library, accessible from C ? Writing python extensions in Rust instead of C would be pretty exciting


This is not quite possible yet, but will be at some point.

Rust does currently depend on a language runtime which expects to control the execution of all Rust code (in particular managing the task scheduler), and the runtime does not have an embedding story yet. Even with an embeddable runtime though, the process would be more involved than loading a library through `dlopen` and executing a function.

As part of the effort to rewrite the remaining bits of C++ runtime code in Rust (almost all of Rust is written in Rust), there are further plans to make Rust code runnable without an underlying runtime and without split stacks. After that it will be feasible to write code in Rust and just call it like any C function.


Ha, I was just thinking about how Rust bindings to Python might look.

I haven't actually tried this, but since Rust libraries just compile to .so's and it's possible to declare a Rust function with a C signature, I bet it'd be a simple exercise to write a CPython-compatible extension module.


"I haven't actually tried this"

Please remedy this immediately. I'll even provide a highly-imaginative name: "Prusty".


Prusty comes closes to "Prusti" which is the bulgarian word for "fingers", and "prust" meaning "finger", but also "soil"


Apparently it won't work yet! Tragic. In the meantime, I can deliberate on whether or not to call it FOXDIE.


Surely "Pyrite"?


Awesome :)

For those with even less of a chemistry background than I have: rust is iron oxide, and pyrite is iron sulfide. It's a good analogy because oxygen and sulfur are in the same group (column) in the periodic table, so they have some chemical similarities.


There was a music software language called Pyrite. It ran inside of Max graphic programming environment. It then evolved into SuperCollider which is now one of the most used music programming languages in experimental and academic music. Http://github.com/supercollider

But that pyrite hasn't been active for a long time.


Awesome.


Would be interesting to read a comparison with D. And no, "obscure" is not a meaningful description when comparing it to a language still at v0.3.


I have used D but no Rust yet. They look superficially similar.

On the Rust side, algebraic data types, an AST macro system, saner tuples, non-nullable and immutability by default. I'm a bit skeptic about the different pointer types and how they will interact with meta-programming.

On the D side, many good things like unittest(), best-in-class overloading support, compile-time everything, etc.

http://laser.inf.ethz.ch/2012/slides/Alexandrescu/2-D%20cour...


That's fair. I'm conjecturing somewhere into the future: D never really took off, but I'm hoping Rust will.


Rust has three different ways of allocating memory. And you can't pass things allocated one way to functions that expect something allocated the other way.

A Python replacement, this ain't. More like C++ on quaaludes.


No, Rust has two ways of allocating memory (on the task heap or on the exchange heap), and most functions take borrowed pointers, which accept both kinds of memory.

(Edit, re below reply: It depends how you define "allocation"; it's either two or three. I wasn't considering the stack as allocation, but you're right that Rust takes the traditional stack/heap distinction and expands it to stack/exchange heap/task heap. We should update the tutorial to make it clear that borrowed pointers work for the stack as well as both heaps.)

I agree that the language is not designed to be a Python replacement, however. No language is suitable for every task.


from http://dl.rust-lang.org/doc/tutorial.html

"7.3 What to be aware of

Rust has three "realms" in which objects can be allocated: the stack, the local heap, and the exchange heap. These realms have corresponding pointer types: the borrowed pointer (&T), the shared box (@T), and the unique box (~T). These three sigils will appear repeatedly as we explore the language. Learning the appropriate role of each is key to using Rust effectively."

It's 3 different types, not 2.


Rust statically prevents leaks and double-frees, warns about implicit copies of large structures, and has GC built in if I want to use it. It's certainly more familiar to a Python dev than C++. The whole trait system is even like a built-in and vastly simpler zope.interface.


Of course they compete. People aren't born with a gene that puts them into exactly one of the camps you describe. These ideas compete and so do the languages, provided they can be used for largely the same tasks, which seems to be the case.


Does Go not have higher order functions and pattern matching? If not, are they on the roadmap?


Go does not have pattern matching. There are type assertions, but obviously that's not the same thing.

Go has higher order functions in some sense, and the standard libraries use them for some things. But I wouldn't say they're nearly as ubiquitous as they are in Ruby or your average functional language. My read is that Go is pretty firmly grounded in imperative-land.

Regardless, since Go 1 came out relatively recently, I doubt they're going to make substantial changes to the language anytime soon. Obvs I don't speak for them, etc etc.


Go has full closures and first-class functions, and their use is as idiomatic in Go as it is in Javascript; for instance, they're the mechanism by which you implement filtering in the "http" package.


I'm sure that Go has higher-order functions, I just mean that Rust encourages you to use higher-order functions all the time. For example: in Rust, `for` loops desugar to higher-order functions (it's very neat, actually). Furthermore, whereas in Go you spawn a goroutine with the `go` keyword, spawning a task in Rust is done by handing a function (usually a Ruby-esque closure) to the `task::spawn` library function. (Note also that "higher-order functions" are not the same as "first-class functions".)

Go does not have pattern matching, to my knowledge, though without algebraic datatypes I don't think it's really a big deal.


Go has first class functions yes, but without the support for generics/parametric polymorphism, you can't write "higher order functions" for polymorphic functional constructs like map/filter/reduce etc.




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

Search: