Live data from Hacker News

Author of “Unix in Rust” Abandons Rust in Favour of Nim

github.com

31–40 of 86 posts

Re: Author of “Unix in Rust” Abandons Rust in Favour of Nim

#31
post #17

We just switched from Rust to Nim for a very large proprietary project I've been involved with after rejecting proofs of concept in Go and Erlang earlier in the process. This despite the fact that we had formally decided on Rust, had tons of code developed in it, and only stumbled upon Nim by complete accident randomly one day. Even though many large components were already developed in Rust we have already reached p…

Wow, that should have been its own post! Great to hear how you get along with Nim.

Re: Author of “Unix in Rust” Abandons Rust in Favour of Nim

#32
post #7

Earlier quoted context omitted.

> Not sure compiling to C as an extra step is going to do to reliablity or performance in Nim but we'll see. Interesting times. Having worked with languages that target C, machine code and C, I will make a few predictions: Compiling to C shouldn't hurt reliability anymore than compiling to LLVM. Performance will likely be somewhat less, particularly as "readable C" is the target, not arbitrary C. > Basically he likes…

LLVM's optimization passes are pretty awesome, but so are GCC's. My guess is that both methods can get you good performance, and that what performance you do get depends on how good the LLVM bitcode or C you generate is. I've tried using Rust and Nim for very small programs (Project Euler problems and some text munging), and currently it seems to me that (1) Nim's executables are always a little faster than Rust's (b…

One reason you may find text munging to be faster in Nim is that we have an different algorithm than they do that's better in the worst case but slower in many small cases. Plus, Rust's are UTF-8 aware by default, and Nim's are not.

(This doesn't mean that it's still not the same from a user's perspective, just explaining a bit about why, and that this might change in the future.)

Re: Author of “Unix in Rust” Abandons Rust in Favour of Nim

#33

Earlier quoted context omitted.

The presence or lack of a GC has nothing to do with the Kernel. The Kernel is simply another program, with specific requirements and limitations. So long as your language allows you to write and call raw assembly, you can write a Kernel. It's worth remembering that Rust has a form of GC as well - it uses a reference counting collection mechanism which is executed at scope boundaries instead of as a separate thread or…

> It's worth remembering that Rust has a form of GC as well - it uses a reference counting collection mechanism which is executed at scope boundaries instead of as a separate thread or co-routine. And it's opt-in: you only pay for reference counting if you explicitly wrap your type in Rc. Moreover (and in contrast to Nim), you don't need to use reference counting for memory safety.

> you don't need to use reference counting for memory safety.

If you limit yourself to boxed and stack variables, which is a pretty big limit when writing larger programs.

And as noted by a sibling comment, you can create a memory leak due to cycles if you use it imprudently - do we consider that to be a safe use of memory?

Re: Author of “Unix in Rust” Abandons Rust in Favour of Nim

#34

Earlier quoted context omitted.

The presence or lack of a GC has nothing to do with the Kernel. The Kernel is simply another program, with specific requirements and limitations. So long as your language allows you to write and call raw assembly, you can write a Kernel. It's worth remembering that Rust has a form of GC as well - it uses a reference counting collection mechanism which is executed at scope boundaries instead of as a separate thread or…

I'll note that Rust's reference counting system is not a full garbage collector - it can't detect cycles. As a result, if you create cycles, you leak memory. You don't want a garbage collector in a kernel, because there's a lot of code that needs to run in soft realtime - aside from timekeeping, there's lots of hardware that'll enter a failure mode or drop data if you don't respond to it in time.

> As a result, if you create cycles, you leak memory.

Eep.

> there's a lot of code that needs to run in soft realtime

This is not really a problem, since the hardware will trigger an interrupt which will, at the hardware level, stop the current instruction and move the instruction pointer to a registered location in code. Most time-sensitive hardware interaction occurs in these interrupt handlers, the kernel simply has to read/populate buffers with data which the interrupt handlers consume/fill.

Since interrupts happens to existing kernels all the time (as well as user-space GC runs as well), and so long as the interrupt handler can properly run without having to mess with memory being managed by the GC (which might, to be fair, require a bit of lower level code), you could resume back into a GC cycle as easily as you can resume into a normal kernel.

Re: Author of “Unix in Rust” Abandons Rust in Favour of Nim

#35
post #15

Earlier quoted context omitted.

The presence or lack of a GC has nothing to do with the Kernel. The Kernel is simply another program, with specific requirements and limitations. So long as your language allows you to write and call raw assembly, you can write a Kernel. It's worth remembering that Rust has a form of GC as well - it uses a reference counting collection mechanism which is executed at scope boundaries instead of as a separate thread or…

Kernels tend to want to be very specific about how memory is being used. GCs cause the opposite situation. i.e. these "specific requirements and limitations" you mention have a LOT to do with memory.

Yes, locations in memory, not the kernel's working memory space. i.e. so long as you can have your program loaded after a certain point, write to, and read from, specific locations in memory, you're fine. How the kernel manages its own memory is up to it (for example, one of the tasks which is required to bootstrap into C is establishing a stack so you can call a C method).

EDIT: Real life example of a GC'ed kernel:

https://en.wikipedia.org/wiki/JavaOS

Re: Author of “Unix in Rust” Abandons Rust in Favour of Nim

#36

Earlier quoted context omitted.

> It's worth remembering that Rust has a form of GC as well - it uses a reference counting collection mechanism which is executed at scope boundaries instead of as a separate thread or co-routine. And it's opt-in: you only pay for reference counting if you explicitly wrap your type in Rc. Moreover (and in contrast to Nim), you don't need to use reference counting for memory safety.

> you don't need to use reference counting for memory safety. If you limit yourself to boxed and stack variables, which is a pretty big limit when writing larger programs. And as noted by a sibling comment, you can create a memory leak due to cycles if you use it imprudently - do we consider that to be a safe use of memory?

> If you limit yourself to boxed and stack variables, which is a pretty big limit when writing larger programs.

That's more or less how most C or C++ programs work, however. C and C++ programs (including the Linux kernel) use reference counting when the object lifetime is truly dynamic. For example, file objects going back to the very first Unix have had to be reference counted, because they can be duplicated via the dup() system call, inherited via fork(), or sent from process to process via cmsg.

The big advantage of the C/C++/Rust approach comes from the observations that (a) the vast majority of objects only have one owner; (b) reference counting does not have a global performance impact when used only for a small subset of objects.

> And as noted by a sibling comment, you can create a memory leak due to cycles if you use it imprudently - do we consider that to be a safe use of memory?

It's a tradeoff: reference counting is bad at cycles, but has advantages due to prompt deallocation, avoidance of the mark phase, and (in Rust) avoids unnecessary cross-thread synchronization. I don't think it's unsafe, because leaks can happen in any language, including garbage-collected ones: you can have arrays in global variables that grow without limit, for example.

Remember that the criterion that GC uses—no more references to an object—is ultimately a heuristic approximating what you really want, which is whether the program will access the data in question again. Of course, due to the halting problem, we can't actually solve that problem, so all garbage collection algorithms approximate it, with the requisite possibility of leaks.

Re: Author of “Unix in Rust” Abandons Rust in Favour of Nim

#37

Earlier quoted context omitted.

I'll note that Rust's reference counting system is not a full garbage collector - it can't detect cycles. As a result, if you create cycles, you leak memory. You don't want a garbage collector in a kernel, because there's a lot of code that needs to run in soft realtime - aside from timekeeping, there's lots of hardware that'll enter a failure mode or drop data if you don't respond to it in time.

> As a result, if you create cycles, you leak memory. Eep. > there's a lot of code that needs to run in soft realtime This is not really a problem, since the hardware will trigger an interrupt which will, at the hardware level, stop the current instruction and move the instruction pointer to a registered location in code. Most time-sensitive hardware interaction occurs in these interrupt handlers, the kernel simply h…

> This is not really a problem, since the hardware will trigger an interrupt which will, at the hardware level, stop the current instruction and move the instruction pointer to a registered location in code.

At which point the interrupt handler needs to route the interrupt through a complex, multi-layer driver stack, and the driver needs to respond - where it's likely to depend on complex datastructures of the type that would normally be managed by a GC if the response is anything but an absolutely trivial ack.

All garbage collectors require that at least some memory is inaccessible to regular code while the garbage collector is running. As a result, you essentially have to ensure that anything that might ever be touched as a result of an interrupt, or during another soft-realtime event, is not managed by the garbage collector - and then you may have to detangle even more data from the GC's grasp when the hardware vendor releases the next revision of their hardware which requires access to more information. You also have no proof that what you're doing outside the safety of the GC is correct without a Rust-like lifetime system, or other more complex static verification systems (such as have been built on top of Coq).

In addition to that, developing performant code with few/no obvious hangs under a GC takes a lot of effort and specifically fighting against the GC - ask any game developer who's developed a large game using C# under Unity or the like - and they get the luxury of getting to run GC at vsync. You don't have any good spot to run GC in a kernel.

Re: Author of “Unix in Rust” Abandons Rust in Favour of Nim

#38

What is Nim's community like? I ask because I first learned about Nim a few weeks ago when some people were chatting about it on Slashdot. One comment [ http://slashdot.org/comments.pl?sid=6771453&cid=48860921 ] quoted from that day's Nim irc logs and well it was a little disturbing. There was a lot of insulting and name calling going on and it didn't leave a good impression on me. I don't want to judge the entire Ni…

[deleted]

Re: Author of “Unix in Rust” Abandons Rust in Favour of Nim

#39
Having played with both Nim and Rust, I also prefer Nim.

Basically Rust is a slightly more pleasant C++, but still huge, complicated, things break all the time, and there's no IDE support to help you make sense of anything. It's probably more robust, maybe faster as things get big, but I haven't got there yet.

Nim is as easy to write as Python, the toolchain is very easy to set up, creating Nim interfaces (with documentation) to your favourite C or C++ library is dirt simple (thanks to tools that come with the compiler), and the language is shockingly fast.

Right now, it's just so much easier to get things done with Nim. Reminds me of Coffee-Script - because it compiles to another language, you get access to a million libraries and platforms for free.

Re: Author of “Unix in Rust” Abandons Rust in Favour of Nim

#40
post #9
post #4

I think the reasoning is sound, but this isn't an indication of either language being better than the other. Only that it's easier to look under the hood of Nim. I find Nim easier to read, and then as is with ruby, probably more productive for prototypes, but I'd like to see more use cases before I start to move in that direction. It does make me wonder if we'll ever see a Nim to rust transpiler.

2 different languages for 2 different use cases. Seems to me that Nim is more in league with Go and D while Rust is lower level with some syntactic sugar. Might be wrong but that's how I feel about these. Anyway it's great to have new french languages that you can still link to C libs when you need it.

Edit: meant fresh not french ,of course.
Post reply on HN