Adding new abstraction layers rarely helps when doing systems programming. You (as in "the developer") want to be as near to the machine as possible. C does this pretty well.
Perhaps I'm just getting old :-(
11–20 of 85 posts
Adding new abstraction layers rarely helps when doing systems programming. You (as in "the developer") want to be as near to the machine as possible. C does this pretty well.
Perhaps I'm just getting old :-(
In reliability theory "X failed" is a poor error message. What we want to know is which failure mode has been triggered. The function of kill is to kill a given pid, so there are two failure modes : "the pid didn't exist" or "the pid didn't die"
I can't help but think they're trying to fix something that isn't broken at all. Adding new abstraction layers rarely helps when doing systems programming. You (as in "the developer") want to be as near to the machine as possible. C does this pretty well. Perhaps I'm just getting old :-(
The original API is not "broken" per se, it's just limited by the language features ("magical" return values vs. tagged unions or whatever they're called in Rust, I don't remember.)
We have switched to Nix as internal dependency manager for our C++ project. It is really exciting! No more "after commit XXX you need to (re)build/update YYY with ZZZ". Developers just type `nix-shell` and get sane guaranted to work environment on their local machines corresponding to git HEAD. If we need to add or patch dependency we just edit and commit nix file. And if developer need to rollback to old commit/bran…
Minor nit pick but don't you typically do something like this in C pid_t childPid; switch (childPid = fork()) { case -1: ... / error handling /; case 0: ... / Child Specific / default: sleep (5); } edit - seems to mangle formatting but something like that seems fairly clean.
Nobody is claiming that C makes it impossible to cleanly do the right thing—obviously the whole world runs on C.
The point is that nothing about the C language, libraries, or toolchain discourage the example given in the blogpost compared to your more correct code. Unless you remember exactly the right details from the manpages, there's nothing about the example in the blogpost that's less natural to write than your more correct code. (And people do forget those details: http://rachelbythebay.com/w/2014/08/19/fork/ )
By contrast, as illustrated in the blogpost, the most natural way to do the same thing in Rust turns out to be the more correct thing. If you wanted the bad behavior to happen, you'd have to go out of your way to pass -1 to kill(). Hence in this example, Rust's design is an improvement.
It's great that C gives you enough rope to hang yourself with, but it's even better if tying yourself to things safely is easy, and to hang yourself you have to really go out of your way.
I can't help but think they're trying to fix something that isn't broken at all. Adding new abstraction layers rarely helps when doing systems programming. You (as in "the developer") want to be as near to the machine as possible. C does this pretty well. Perhaps I'm just getting old :-(
In this case it seems like a very thin wrapper that leverages the type system to allow catching a whole class of errors at compile time, like using exhaustiveness checks to make sure a function call handles all possible return values. I think the small overhead is well worth it. The original API is not "broken" per se, it's just limited by the language features ("magical" return values vs. tagged unions or whatever t…
if let Some(child) = fork() {
do_only_child_stuff();
} else {
do_only_parent_stuff();
}
or if let Some(ForkResult::Child) = fork() {
do_only_child_stuff();
} else {
do_only_parent_stuff();
}
Now, if you're about to tell me that the examples above are totally stupid and no
developer would do such a thing, then you know how I feel about the sloppy
C versions. Doing a system call and not checking for error is totally
stupid as well.By the way, you can also write your own wrapper functions in C, that transform the return value into something like
struct fork_status {
enum { ERROR, PARENT, CHILD } state;
int ret;
};
Then Clang and GCC will warn you about missing switch cases.That said, the libc bindings in Rust are pretty low-level and a project that offers higher-level wrappers can be very helpful, so I hope my comment doesn't create the impression that I'm ripping on the project itself.
I was very confused. I thought this had something to do with Rust and nix[1]. [1]: https://nixos.org/nix/
It's actually about a library, nix, whose mission is "to provide ‘Rust friendly bindings to *nix APIs’".