> People go "threads are evil" with vague rationales about getting locks right and such, and insist we all use separate heavyweight processes.
Insisting processes be used != insisting OS processes be used. Although most language don't give any choice in the matter.
> Selection of sane data structures and communication channels can get you virtually all of the safety and ease of separate processes
It gives you none of the safety, as you have to be very careful in ensuring no mutable datastructure is ever shared unknowingly. When using processes, you can't share memory implicitly, which is safe.
> There as here, simply selecting the right primitives and development strategy in advance make the problem simply disappear.
That's bullshit. It may make the problem less prominent, but it can not make the problem disappear.
It may make the problem less prominent, but it can not make the problem disappear.
It would look quite weird and most other programmers would think you were crazy for having done it, I think it's possible to write a C++ program that provably doesn't leak. You could define a custom operator new for every type which ensures that it gets allocated with some smart pointer or GC heap.
You could probably still use most of the C++ standard library that returns something needing manual de-allocation (except perhaps new and the old C malloc itself, which can be banned in various ways).
Why would it look quite weird, and why would anyone think you were crazy? It's standard practice and quite easy in C++. Smart pointers and RAII are your friends.
I agree with you. That's how I code and I don't have any problem with such leaks. But the usual response by people who don't believe that is "well the language doesn't force you to use them".
I was thinking of the weird tricks that would have to be in place to plausibly prove that there was no unmanaged dynamic allocation going on.
So you go from distinguishing between processes on the language and OS levels, to categorically declaring you can't share memory implicitly with processes.
A facsimile of a process that isn't implemented as an actual process is going to be in a shared address space. Your pet bondage-and-discipline language might work to prevent one pseudo-process from interfering with another, but I don't see it being equal to full-blown processes, nor do I see it being substantively more trustworthy than making a few simple, easy decisions about how to structure your programs.
> categorically declaring you can't share memory implicitly with processes.
That's kind-of the whole point, and difference between threads and processes. If you have implicitly shared mutable memory with processes, your processes are broken and you have threads.
> I don't see it being equal to full-blown processes
Really?
> nor do I see it being substantively more trustworthy
That's interesting. So you don't see how the language enforcing a share-less discipline would be more trustworthy than people trying to do so informally?
> than making a few simple, easy decisions about how to structure your programs.
Such as not using any third-party code which has not been fully audited to the statement? What a simple and easy decision that is.
Insisting processes be used != insisting OS processes be used. Although most language don't give any choice in the matter.
> Selection of sane data structures and communication channels can get you virtually all of the safety and ease of separate processes
It gives you none of the safety, as you have to be very careful in ensuring no mutable datastructure is ever shared unknowingly. When using processes, you can't share memory implicitly, which is safe.
> There as here, simply selecting the right primitives and development strategy in advance make the problem simply disappear.
That's bullshit. It may make the problem less prominent, but it can not make the problem disappear.