Hacker News new | ask | show | jobs
by icambron 4636 days ago
> Personally, I’m hoping for Rust.

That was my thought while reading article; Rust seems like the answer here. I'm coming from the opposite direction than the OP: I'm unwilling to give up the expressiveness of Ruby and friends in order to write micro-optimized C++ code, and I'm hoping Rust will give me the best of both worlds.

4 comments

Yeah, everyone’s got their eye on Rust as far as low-level expressive programming goes. Nimrod[1] also looks quite good:

> Nimrod is a statically typed, imperative programming language that tries to give the programmer ultimate power without compromises on runtime efficiency.

In my spare time, I’m working on a statically typed concatenative language called Kitten[2] with similar goals.

[1]: http://nimrod-code.org/

[2]: http://github.com/evincarofautumn/kitten

Speaking as a C++ programmer, Rust appeals to me a great deal over Nimrod because you can turn off (or just not use) Rust's GC and still have memory-safe code.

I believe you can turn off Nimrods GC as well, but you lose any guarantee of memory safety when you do. Not to mention -- aren't all pointers in Nimrod reference counted? That's going to take a fairly significant performance toll due to cache effects alone.

Nimrod borrowed Modula-3's idea of having both traced and untraced pointers (using ref and ptr as keywords, respectively). As long as you only use ptr references, no overhead for reference counting (or other forms of garbage collection) is generated.

Of course, in order to use untraced references, you also have to use manual memory management (though you can use the macro/metaprogramming system to reduce the pain somewhat).

For traced references, Nimrod uses deferred reference counting; i.e. reference counts are only updated when they are stored on the heap or in a global variable (similar to write barriers for generational/incremental garbage collectors). If a reference count reaches zero, the reference is stored in a zero count table. At intervals, a separate pass checks if any references in the zero count table are still referenced from the stack (and does cycle detection where needed).

Deferred reference counting avoids the biggest problem with naive reference counting, which is that just assigning a pointer to a local variable (to inspect the contents of an object, say), can trigger up to two reference count updates. Conversely, with deferred reference counting, a read-only traversal of a data structure will not perform any reference count changes at all. Similarly, purely temporary allocations will not require any reference count changes, either.

> That's going to take a fairly significant performance toll due to cache effects alone.

It's not so bad because in Nimrod they are non-atomically reference counted and deferred reference counting is used to avoid touching the RC for stack references, at the cost of some minor latency for stack scanning. (Disclaimer: I work on Rust and my Nimrod info is possibly wrong and/or out of date.)

Even for non performance critical code, Rust is looking like it'll be a winner.
Does Kitten also try to not make (too many) compromises on runtime efficiency?
It’s very much a work in progress, but yes, as far as the language design goes. Right now there’s a horrifically inefficient AST-walking interpreter, essentially the simplest thing that can possibly work. That gives us integration tests, a standard library, and a REPL. We are working on the design and implementation of a native runtime as free time allows.

The language looks and feels fairly high level, like a hybrid imperative-functional language. But in reality, it’s closer to (stack machine) assembly. There is a relatively straightforward mapping to x86 or ARM, so it’s easy to look at some code and mentally compile it at -O0 the way you might in C. Each Kitten instruction usually corresponds to one or two x86 instructions.

Evaluation is strict, because excessive laziness can negatively impact predictability and performance, and you can get many of the benefits of laziness in different ways. All types have immutable value semantics; sharing is essentially an optimisation, and can be implemented with a tracing GC or a reference-counting one because the language is cycle-free. And function definitions are often extremely short, so they benefit from aggressive inlining.

The general feeling is that we want absolutely as lightweight a runtime as possible—no type tagging, value boxing, runtime dispatch, reflection, garbage collection, &c. unless the programmer asks for them. At the same time, we want to avoid infecting code with low-level details such as pointers, lifetimes, and ownership. Correctness first, followed shortly by performance.

Kitten is attacking the same problems as Rust and Nimrod, but from a very different direction. And of course we are only a small handful of people working in our spare time, and I write most of the code. It would be wonderful to have some more people on board.

It feels like a very modern language overall, I particularly like the memory management ideas. It's refreshing to see something which tries to find a middle ground between error prone manual handling and unpredictable GC. Now someone just needs to write a good Rust IDE.
There was actually some work done over the summer with... DWARF? So that Eclipse can use its debugger on Rust code. I'm on mobile or I'd find you a link.
> Rust has a great approach to safe regions. That's a hard problem, and Rust has had to expend a considerable amount of firepower on it (four kinds of pointers etc). D does not offer safe regions; I believe the language design precludes that without at least an amount of discipline. So Rust is better than D at safe regions. However, like in chess, good language design is to not sacrifice the whole for the beauty of the part. I think D is better than Rust at a lot of other things, because it has firepower it can afford to expend at problems that are also hard, and just as important.

http://www.reddit.com/r/IAmA/comments/1nl9at/i_am_a_member_o...

Rust seems like the answer here.

How so? To me the callout to Rust diminished the entire article because it made it almost anti-Go for no particular reason (ala "Go is poopy anyways, but maybe [some other unproven option] will be the savior]". This same sort of nonsense occurred with the statement "on my not-very-fast-at-all Core i3-2100T" regarding the C++ performance, which is just narrative nonsense given that the same circa-2012, AVX-equipped processor was what yielded his Go numbers).

The author demonstrated C code that was 2x faster than Go code run through the standard Gc chain, when the C code is run through a very mature, hyper-optimized C compiler, which is actually really impressively good for Go. They then try to pound home the point by inlining AVX which is absolutely ridiculous for such a language comparison. It borders on pure troll, and I'm really surprised that so many people are falling for this.

Both Rust and C/C++ sit squarely in the "no GC" or "optional GC" camp, which has very important implications for certain applications which strongly favor that compared to a generalized system-wide GC.
> How so? To me the callout to Rust diminished the entire article because it made it almost anti-Go for no particular reason

It might seem that way if Go and Rust were competitors, but given that they seem to have pretty different philosophies and goals, that doesn't seem to be the case.