Live data from Hacker News

Discipline Doesn’t Scale

sicpers.info

131–140 of 173 posts

Re: Discipline Doesn’t Scale

#131
post #121
post #7

Over a decade ago I used to argue this with the C++ committee people. Back then, they were not concerned about memory safety; they were off trying to do too much with templates. The C++ people didn't get serious about safety until Rust came along and started looking like a threat. Now they're trying to kludge Rust features into C++ by papering over the unsafe stuff with templates, with some success. But the rot under…

Rust is not a good example of a language which doesn't require discipline: on the contrary, it requires very much discipline and thinking deeply about lifetimes and resources. The difference to C++ (since that's what you've mentioned) is that the compiler double-checks everything at the end. The advance in programming language usability will not come from arcane tools like Rust, but from tools like Java, Python or Go…

I admit I have a bias here, as I use Rust full-time, but Java, Python and Go are not what I would call languages that require less discipline. For instance, Go's error handling is entirely reliant on discipline! All of the meta-programming and runtime reflection nonsense requires discipline to not abuse and misuse. The worst codebases I have seen in Rust are significantly better than the worst codebases I have seen in languages like Java or Python, and maybe its because Rust programmers are more disciplined on average, or maybe its because the compiler requiring clean code forces less disciplined developers to produce better code.

Perhaps there are two camps here: (1) Reduce discipline by making developers no longer have to consider certain situations (garbage collection fits here) and (2) Reduce discipline by shifting that to the compiler (types fit in here)

Re: Discipline Doesn’t Scale

#132

Earlier quoted context omitted.

Our contemporary corporate and social culture doesn't encourage or reward discipline. We produce mostly throwaway stuff that has to be released as soon as possible on the market, or else the company goes out of business. The incentives for craftsmanship and diligence are just not there.

> Our contemporary corporate and social culture doesn't encourage or reward discipline I think there is some selection bias here. The majority of particiapants in HN discussion generally people who work for startups and people who work with web technologies. The Silicon Valley culture might be focused around time to market, but there is a large (mostly unheard) group of people who exist in a very different culture. F…

Reminds me a bit of this article: http://veekaybee.github.io/2019/05/10/java8/

Re: Discipline Doesn’t Scale

#133
post #71

Earlier quoted context omitted.

I suppose it depends on what you would consider being “serious” about memory safety. I view move semantics as not a memory safety thing at all (in fact, use-after-move can be exactly as ugly as use-after-delete), and smart pointers as a “let’s just make things marginally better than raw raw new/delete” thing. Smart pointers in C++ can still be null, after all. Calling C++ not serious about seems a reasonable take to…

Smart pointers + static analysis + sanitizers is the best options I am aware of for improving the correctness of C++ programs, and I don't think Rust really had much to do with them. The picture painted that Rust made the C++ standards committee scramble to start addressing safety seems wrong; it feels more like there's been a mostly steady increase in safety over time without need for any outside influence.

> Smart pointers + static analysis + sanitizers

I feel like you just defeated your point; those are bolted on instead of a natural part of the language.

Re: Discipline Doesn’t Scale

#134
post #121
post #7

Over a decade ago I used to argue this with the C++ committee people. Back then, they were not concerned about memory safety; they were off trying to do too much with templates. The C++ people didn't get serious about safety until Rust came along and started looking like a threat. Now they're trying to kludge Rust features into C++ by papering over the unsafe stuff with templates, with some success. But the rot under…

Rust is not a good example of a language which doesn't require discipline: on the contrary, it requires very much discipline and thinking deeply about lifetimes and resources. The difference to C++ (since that's what you've mentioned) is that the compiler double-checks everything at the end. The advance in programming language usability will not come from arcane tools like Rust, but from tools like Java, Python or Go…

> Rust is not a good example of a language which doesn't require discipline: on the contrary, it requires very much discipline and thinking deeply about lifetimes and resources.

My experience is completely different. I programmed a bit in rust recently. Nothing system level. Quite opposite.

I had multiple occasions when after succeeding to implement some part in Rust I thought to myself "wow, if I tried to do that in C++ I would have fallen in so many pit traps by now, that rust helped me avoid by restricting me in some ways".

And I'm very new to rust and I was just coding blindly just by powering through different approaches till one of those compiled.

"I can't use borrow to keep that? What's a borrow anyways? Let's just cram it in Rc whatever it is. I can't return this? Fiiine! I'll create it outside and pass it in."

And in the end it worked perfectly. No weird bugs to find. I felt like a caveman trying to bang rock into shape. And at no point rock cracked, split and or buried me under the rubble.

Re: Discipline Doesn’t Scale

#135

Personally, I think Discipline is one of the things that separate “coders” from “engineers.” This sounds like it’s really a treatise on “learning to build a house by making your own nails.” Of course that won’t scale. Especially if most houses, these days, are prefab, and don’t use too many nails. But learning how to stay out of flood plains, and selecting good prefab sources, is vital to being a builder. The first o…

Our contemporary corporate and social culture doesn't encourage or reward discipline. We produce mostly throwaway stuff that has to be released as soon as possible on the market, or else the company goes out of business. The incentives for craftsmanship and diligence are just not there.

Maybe you think craftsmanship is better in the past because of survivorship bias.

For instance, the 60s and 70s had a lot of great music come out of it, but have you ever gone down a chart of the hits from decades ago and listened to the lesser known artists? Lots of it is bad and utterly forgettable.

Same goes with a lot of other fields. We only remember the best and forget about the rest.

Re: Discipline Doesn’t Scale

#136
Discipline is all what matters, automatizations are imperfect and temporary tools.

Simply put: all abstractions are leaky, all abstractions have trade-off, and you cannot necessarily rely on some abstractions in every context.

The GC example that the author uses is a good one: having GC in a language does not magically remove all memory allocation issues. Believing this means you just don't have much experience programming (or you've been very lucky). I've been working mostly with GC languages and we have memory leak every now and then, good luck to fix that without discipline. Embedded software frequently relies on (very) limited compilers and libraries, most of the time there are no GC and until recently there were even no malloc/free for $B things shipped to space: only static arrays and discipline my friend!

TCP is another good example: sometimes you need to craft you own congestion management, packet discard rule or what not.

ORMs have made my life easier but I've still had to spend days on complex hundreds lines SQL reports. The list goes on.

It's not "I had to go through this, you should too" out of frustration. It's because at some point the same kind of issue will appear again, even though the current available abstractions may seem to shield us from it.

It might not scale as easy as you wish, yet you need some disciplined seniors to review and teach your juniors. This very article ironically proves it :)

Re: Discipline Doesn’t Scale

#138
post #10

Earlier quoted context omitted.

I think this is a little oversimplified, because I’m pretty sure C++0x had move semantics and usable smart pointers prior to Rust really entering the public conscience/probably before it existed . AFAICT Rust takes a lot of inspiration from how you would “fix” C++, in ways that you could never actually do in C++ because it would break backwards compatibility.

I suppose it depends on what you would consider being “serious” about memory safety. I view move semantics as not a memory safety thing at all (in fact, use-after-move can be exactly as ugly as use-after-delete), and smart pointers as a “let’s just make things marginally better than raw raw new/delete” thing. Smart pointers in C++ can still be null, after all. Calling C++ not serious about seems a reasonable take to…

When I think about C++ "smart" pointers, I often think about easy to provoke / difficult to spot fatal edge cases. E.g.

- C++ code where some method calls std::shared_from_this(), and that method ends up being called indirectly during the object's construction, leading to a 0-pointer dereference [1]

- accidentally creating two shared-pointers to the same object leading to an eventual double-free (that may just silently corrupt the heap while the program continues running)

- undetectable cyclic shared_ptr references somewhere deeply hidden in the code causing a memory leak

Modern C++ feels like a case of "but we can do that in C++, too" syndrome. Stuff that "just works" in Java or Lisp, can now be done in C++, too, however in C++ it will only work for 95% of all use cases, and break in a spectacular manner for the remaining 5%.

E.g. think about the template meta-programming madness (and efficiency WRT compile-time) and compare that with what Lisp offers (see also [2]).

[1] https://stackoverflow.com/questions/31924396/why-shared-from... standpoint

[2] http://people.cs.uchicago.edu/~jacobm/pubs/templates.html

Re: Discipline Doesn’t Scale

#139
I would say that the validity of this argument depends entirely on the availability of hardware. To take an extreme example, reference counting would have been completely infeasible in the days of assembly programming. An assembly programmer who had this insight would have had to wait decades for the hardware to catch up. I'm sure more and more tools, language constructs and compiler features will emerge in the coming years to reduce the cognitive load on developers so that they can focus more and more on the business logic. But that doesn't invalidate the some of the discipline you need to make software fast and stable today.

Re: Discipline Doesn’t Scale

#140
post #34

Earlier quoted context omitted.

I’m not sure “what locks it” is a useful question. Locking is a performance and scalability destroying operation in a time when we care about both. Systems that care about both largely avoid locking (including most “lock-free” locks) altogether outside of rare cases, and in such rare cases the logic is simple. Nothing is lost by avoiding locks with good architecture. In big multi-core systems, I model the handful of…

"What locks it" can include "owned by different threads". That's a lock at a higher level, really. "Lock free" data structures are tied very closely to the data being locked, and depend heavily on certain CPU operations being atomic. This is more of an issue with ARM than with x86, because ARM needs more fence instructions. Really, "lock free" programming is just locking critical sections with lower level hardware pr…

> Really, "lock free" programming is just locking critical sections with lower level hardware primitives.

I have to disagree, as the more interesting lock free algorithms use atomic operations that can fail. Yes, a compare-and-swap is like having a critical section on modifying that particular address. But a compare-and-swap can fail if what is currently there is unexpected. The result of that failure generally means redoing a bunch of work, rather than just trying again. Interesting lock free algorithms tend to have the structure:

1. Read some data.

2. Perform computations on that data.

3. Trying to commit the result of that computation. If someone else committed data to the same location after you read it in step 1, go back to step 1.

That's less like a "critical section," and more like a transaction. For lock free algorithms that just rely on atomic operations that cannot fail (such as an atomic increment), then yes, those are just like having a lower-level critical section. (And, on some architectures, that's exactly what they are.)

Post reply on HN