Hacker News new | past | comments | ask | show | jobs | submit login

That's all true, but there's a reason that we define "safe languages" in this way: it's that you can isolate parts of the program from other parts of the program, and know with confidence that a failure in one part of the program will not corrupt data in another part of the program.

Again, my proposal is to wrap only that part of the program which doesn't interact with shared state in a giant try/catch block (and you can know with 100% reliability what that part is in a safe language). The parts about taking a request off the queue, or storing results in a shared data structure, or whatever, should be outside of the try/catch block, because if they break, your shared state is indeed at risk.




Your proposal doesn't scale and doesn't apply in general. Neither Rust nor Python enforce high-level data structure integrity (e.g. transactionally pulling data off one queue and stuffing in another). A team of 100 programmers will get this wrong. Big try:except:log:continue is the exception (rimshot), the rule should be to abort().


> Neither Rust nor Python enforce high-level data structure integrity (e.g. transactionally pulling data off one queue and stuffing in another).

Rust absolutely does. For instance, if you unwind while holding a lock, the lock gets poisoned, preventing further access to the locked data. If you're not holding the lock, no safe Rust code can possibly corrupt it, unwinding or no unwinding. So you definitely can put a lock around your two queues, operate them from multiple threads running safe (or correct unsafe) code, and be robust to a panic in one of those threads.

I'm less familiar with Python's concurrent structures, but as I keep saying, this is why you leave the stuff that touches the data structure outside of your try/except - Python does guarantee that a thread that doesn't have explicit access to a shared object can't mess with the shared object by mistake.


Just because Rust has safe guards for lock usage during unwinds doesn't mean it prevents all high level data structure inconsistencies or even just plain old bugs.

Doesn't matter how you choose to handle invalid semantic forms, either via undefined behavior, error code, exception, or assert, as long as you silently ignore it, your code is unsafe. Rust doesn't have undefined behavior but that doesn't mean it doesn't suffer from silent errors. E.g. Returning NaN from sqrt(-1) or signed integer overflow wrapping.

That's my entire point.

As a programmer your intent is to use APIs in the manner they expect. An invalid use is an invalid program. Garbage in, garbage out. No amount of subsequent error handling is going to help you. Better to abort().


Yes, if you break the contract, better abort. But throwing errors can be part of the contract, even for some programming errors. Failure tolerance, resilience etc.


A runtime exception is fine to handle. Like ENOENT, etc. these are expected and your program can be designed to handle these errors.

A programming error is a sign that your program is not operating the way you expect. No correct program should ever call sqrt(-1) or overflow arithmetic.

Outside of effectively aborting the process, what other way is there to safely handle a programming error (aka bug) when encountered?


Not all programming errors lead to incorrect programs (correctness being defined by the language).

You shouldn't call sqrt(-1) in C, and if you do, you abort. But maybe you are not supposed to call sqrt(20) either, because 20 is a sign your programmer did not understand the application. In that case, the programming error is still a correct program.

In languages like Python, or Lisp, there are a whole set of programming errors like dividing by zero, calling length on something that is not a sequence, etc. that are designed to not crash the system (nor make it inconsistent), in part because those errors can happen while developing the code and are just of way providing an interactive feedback.

Now, if you ship a product and there is a programming error that manifests itself while in production, you better not try anything stupid, I agree.


You essentially agree with me. Aborting with a stack trace is still an abort. It doesn't need to be catchable.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

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

Search: