Live data from Hacker News

Rust and the Future of Systems Programming [video]

hacks.mozilla.org

341–350 of 511 posts

Re: Rust and the Future of Systems Programming [video]

#341

Earlier quoted context omitted.

I think people would be more inclined to try to understand your perspective if you hadn't called Rust's design "jumping on the bandwagon", which, to me, implies a thoughtless act of conformity rather than a deliberate trade-off towards explicitness. To me, verbosity is bad, but implicitness is worse. I like the trade-off that ? (the question mark operator) has stuck for Rust. I agree that OOM handling in Rust should…

Panics are recoverable: initially at task boundaries, and these days at catch points. They are literally exceptions and unwind the same way. The designers intended for programs as a whole to keep running after a task panics. Code running in such a context needs to avoid leaking and corrupting resources on unwind --- i.e., be exception safe. On the rust development list, people call this property literally "exception…

I don't agree that panics are exactly equivalent to exceptions in languages like Java or Python because the language doesn't support using them as a general purpose error handling technique by providing `try/catch/finally` or by documenting what exceptions may be thrown with `throws`. I agree that the implementation of unwinding is similar in both cases, but I'd argue that that's not sufficient in practice to be able to apply knowledge about the usage of exceptions in, say, Java to the usage of panics in Rust.

I'm aware of catch-panic and the unwinding related to panics. Nevertheless, the vast majority of panic usage I've seen is related to the semantic that a panic signals an error that is fatal to the context of the panic. (This is a more nuanced view of panics that didn't exist in my previous post.)

Yes, you can use catch-panic on a server that is meant to stay up even if one of its threads panics. Or you can replace unwinding with aborting to save on code size. But idiomatic Rust code doesn't use panics simply to signal to a caller that some sort of typical error occurred like a file not existing.

Edit: I realize that my post may come across as arguing over semantics. I really don't care whether they're called exceptions or panics or even if they're mechanically the same thing. What I'm trying to talk about is whether they cause code to become harder to understand because of implicit error cases that are invisible in the source.

2nd edit: I appreciate your several good points in your replies to my posts.

Re: Rust and the Future of Systems Programming [video]

#342

Earlier quoted context omitted.

I think people would be more inclined to try to understand your perspective if you hadn't called Rust's design "jumping on the bandwagon", which, to me, implies a thoughtless act of conformity rather than a deliberate trade-off towards explicitness. To me, verbosity is bad, but implicitness is worse. I like the trade-off that ? (the question mark operator) has stuck for Rust. I agree that OOM handling in Rust should…

Panics are recoverable: initially at task boundaries, and these days at catch points. They are literally exceptions and unwind the same way. The designers intended for programs as a whole to keep running after a task panics. Code running in such a context needs to avoid leaking and corrupting resources on unwind --- i.e., be exception safe. On the rust development list, people call this property literally "exception…

> Panics are recoverable

You can't rely on this. Panics could just as easily abort your program. (By changing a flag on the compiler.)

Re: Rust and the Future of Systems Programming [video]

#343
post #318

Earlier quoted context omitted.

I think I know what this trend is, more generally. It has to do with how explicit our code is. We've been through an era where you have some very powerful and compact indirection constructs(event callbacks, polymorphic objects, dynamic types, exceptions) in common parlance and the trend has turned against these lately. Their utility in many instances is mostly to enable technical debt, by worrying about the edge case…

This trend represents the unlearning of very hard earned lessons. Personally, I can't wait until people rediscover that programming can be more fun and productive without boilerplate. A language being explicit, by itself, is not a feature. Being explicit instead of implicit is only worthwhile if you get clarity in exchange, and boilerplate is clarity-reducing because it's so regular and so obscures program logic.

In Rust, in the common case, the boiler plate you're talking about here is literally a single sigil. (Previously, it was `try!(...)`.)

This is of course to say nothing about the advantages of having something that signals "this operation can return an error," (at the call site) but you seem to dismiss that out-of-hand.

Re: Rust and the Future of Systems Programming [video]

#344

Earlier quoted context omitted.

Panics are recoverable: initially at task boundaries, and these days at catch points. They are literally exceptions and unwind the same way. The designers intended for programs as a whole to keep running after a task panics. Code running in such a context needs to avoid leaking and corrupting resources on unwind --- i.e., be exception safe. On the rust development list, people call this property literally "exception…

> Panics are recoverable You can't rely on this. Panics could just as easily abort your program. (By changing a flag on the compiler.)

If you write a general purpose library, you have to make conservative assumptions and work either way.

By the way: I am depressed as hell that the Rust people, knowing full well what went wrong in the C++ ecosystem, repeated the mistake of having an -fno-exceptions and thereby fragmentating the language.

Re: Rust and the Future of Systems Programming [video]

#345

Earlier quoted context omitted.

This trend represents the unlearning of very hard earned lessons. Personally, I can't wait until people rediscover that programming can be more fun and productive without boilerplate. A language being explicit, by itself, is not a feature. Being explicit instead of implicit is only worthwhile if you get clarity in exchange, and boilerplate is clarity-reducing because it's so regular and so obscures program logic.

In Rust, in the common case, the boiler plate you're talking about here is literally a single sigil. (Previously, it was `try!(...)`.) This is of course to say nothing about the advantages of having something that signals "this operation can return an error," (at the call site) but you seem to dismiss that out-of-hand.

I do dismiss this advantage out of hand: almost everything can fail, because most things allocate memory. It's only because Rust treats memory specially (incorrectly --- memory is just another resource) that it doesn't appear that more functions can fail. It's much more valuable to flip the sense of the annotation and mark the few functions that cannot fail in any way.

Allowing most code to throw just reflects reality and allows you to stop obscuring your program logic with mechanical error handling plumbing.

All you do with "try!" is annoy readers by constantly reminding them that things can go wrong when the default assumption should be that things can go wrong.

Re: Rust and the Future of Systems Programming [video]

#346

Earlier quoted context omitted.

Asynchronous nonblocking interfaces are more general-purpose than synchronous blocking interfaces. I can't speak for this library or Rust specifically, but in my experience well-designed asynchronous libraries allow you to interact with them in a synchronous style as well, if you wish. Netty is an asynchronous, event-driven network framework for Java, and it's perfectly possible to expose synchronous blocking abstrac…

Yes, I know, async I/O is the new cool thing. Here's an async I/O program from 1972.[1] John Walker wrote this. EXEC 8 had the IO$ system call, which, unlike IOW$, returned immediately. A "completion routine" was called when the I/O operation finished. Note how similar those libraries are to what's used today, now that people are reading Dijkstra again. The problem, of course, is that a callback system dominates the…

Huh, so are you implying that hyper should stay synchronous so that it doesn't appear to just be copying things from 40 years ago?! This comment sounds like you think that it was good back then, but now you don't know what to think of a library that is aiming to switch to asynchronous IO and/or don't know why it's a good thing?

(It's also not like the comment you're replying to said that async IO is a recent invention, your low-effort sarcasm as a response is unfortunate.)

Re: Rust and the Future of Systems Programming [video]

#347

Earlier quoted context omitted.

> Panics are recoverable You can't rely on this. Panics could just as easily abort your program. (By changing a flag on the compiler.)

If you write a general purpose library, you have to make conservative assumptions and work either way. By the way: I am depressed as hell that the Rust people, knowing full well what went wrong in the C++ ecosystem, repeated the mistake of having an -fno-exceptions and thereby fragmentating the language.

In C++, exceptions are a first class error handling mechanism. This is not the case in Rust, so it can't be the same mistake.

Rust (and C++) are systems programming languages. Users must retain the ability to opt out of the cost of exceptions. The problem with C++ is that exceptions are a first class error handling mechanism.

> If you write a general purpose library, you have to make conservative assumptions and work either way.

If panics abort and they were our only error handling mechanism, then there is no other way to do error handling.

> All of this because some people don't like exceptions

On the one hand, you want people to understand your position. But on the other hand, you come off as implying the Rust designers (which includes the entire community) are a bunch of incompetent boobs that irrationally dismissed exceptions just because they "didn't like them." Do you see how these things conflict with each other? I'd suggest reconsidering your approach when engaging in discussion on this topic with others. As it stands now, you're extremely difficult to talk to.

Re: Rust and the Future of Systems Programming [video]

#348

Earlier quoted context omitted.

In Rust, in the common case, the boiler plate you're talking about here is literally a single sigil. (Previously, it was `try!(...)`.) This is of course to say nothing about the advantages of having something that signals "this operation can return an error," (at the call site) but you seem to dismiss that out-of-hand.

I do dismiss this advantage out of hand: almost everything can fail, because most things allocate memory. It's only because Rust treats memory specially (incorrectly --- memory is just another resource) that it doesn't appear that more functions can fail. It's much more valuable to flip the sense of the annotation and mark the few functions that cannot fail in any way. Allowing most code to throw just reflects realit…

> It's only because Rust treats memory specially (incorrectly --- memory is just another resource)

Which is a perfectly reasonable trade off to make. Of course, it's not always the right trade off, so we're looking to improve our story there.

If you can't acknowledge that there are real trade offs at play here, then I don't really see how it's possible to meaningfully understand your position (or have a non-frustrating conversation).

Re: Rust and the Future of Systems Programming [video]

#349
post #261

Earlier quoted context omitted.

Sometimes I think Rust people lose the forest for the trees. The end goal isn't for the compiler to verify the safety, the end goal is for the software itself to be safe in a way that's cheaper. It doesn't really matter if they both end up at the same place, which is safe software.

> It doesn't really matter if they both end up at the same place, which is safe software. I think the contention is that, unless you're applying NASA style rigor, you don't end up in the same place without verifying the safety automatically, because in practice it's too expensive to verify the safety manually (without getting squeezed out of the space by your competitors.) SaferCPlusPlus's goals are noble, but approa…

> None of the huge swaths of legacy and third party code I'd like to sanitize uses it - and a large scale rewrite to 'fix' that may very well introduce more bugs than it fixes.

SaferCPlusPlus is designed for compatible interaction with unsafe legacy code and library interfaces. Some may see this as flaw. But it allows you to incrementally "improve" C++ code without requiring a total rewrite. It also means that members of a team can adopt it unilaterally. It's regular C++ code that won't interfere or impose on your co-programmers, even when you're working on the same code.

> A library cannot 'fix' fundamental language constructs either, short of telling you to please remember to perfectly avoid those language constructs even if you're very very used to them.

Right, but the "safe replacement" elements in the library are designed to behave just like their unsafe counterparts, perhaps making the transition easier. In terms of enforcement, I think it may be a "use it and they will build it" scenario. Once there is significant adoption of the SaferCPlusPlus library, it should take a relatively modest effort to implement a static enforcer. I mean, you just want to flag any uses of unsafe elements, not even do any analysis on them.

> Frankly, I'm skeptical of how useful I'd find SaferCPlusPlus even for new projects - especially when modern SC++L implementations already have a lot of error checking code built into them as well, at least for debug builds.

That's the beauty of SaferCPlusPlus. Let's say you're using std::vector somewhere in your program. You can just replace "std::vector" with "mse::mstd::vector" and now your vector is (optionally) safe. With a compiler directive you can choose to "disable" the safety features in any build (i.e. mse::mstd::vector will be automatically aliased back to std::vector). Compilers generally just do bounds checking (the "sanitizers" notwithstanding). SaferCPlusPlus checks for things like "use-after-free" as well.

And you don't need to link to any library. You just need to add a couple of header files to your project.

> Meanwhile, I already credit these to saving me at least a month of debugging time: http://clang.llvm.org/docs/ThreadSafetyAnalysis.html

The sanitizers are fantastic. But they're not quite a substitute for SaferCPlusPlus [1]. SaferCPlusPlus addresses the issue of safely accessing objects from asynchronous threads.

> Static analysis and annotations, designs to make edge cases impossible to ignore, and where static analysis cannot perfectly find all problems, let it error out reliably at runtime instead of randomly corrupting memory unless I really really really mean it.

SaferCPlusPlus is not a competitor to, or an excuse to neglect static analysis. SaferCPlusPlus exists because static analysis does not fully solve the problem.

[1] http://duneroadrunner.github.io/SaferCPlusPlus/#safercpluspl...

Re: Rust and the Future of Systems Programming [video]

#350

Earlier quoted context omitted.

If you write a general purpose library, you have to make conservative assumptions and work either way. By the way: I am depressed as hell that the Rust people, knowing full well what went wrong in the C++ ecosystem, repeated the mistake of having an -fno-exceptions and thereby fragmentating the language.

In C++, exceptions are a first class error handling mechanism. This is not the case in Rust, so it can't be the same mistake. Rust (and C++) are systems programming languages. Users must retain the ability to opt out of the cost of exceptions. The problem with C++ is that exceptions are a first class error handling mechanism. > If you write a general purpose library, you have to make conservative assumptions and work…

I agree that it must be possible to use the language in a very low overhead, literal way. That's not most use, I think. Most applications can tolerate exceptions, so stdlib should have used exceptions to report errors. The people who can't tolerate exceptions are the same ones who want precise machine control and who probably don't want stdlib either.

If exceptions were the only way to report errors in stdlib, stdlib wouldn't have had to panic on errors --- or, rather, users would have come to expect these panics instead of treating them as a fatal, anomalous condition.

The trade off seems wrong here --- you should be able to support stdlib and exceptions for clarity or !stdlib and !exceptions for full control, but I don't see a big case for stdlib and ! exceptions, but the way Rust is designed, everyone pays for the stdlib and !exceptions model. (And they have to care about exceptions anyway, but can't rely on them.)

I think Rust's error handling is very poor design. I regret that this opinion coming across makes it difficult to have a conversation.

Post reply on HN