9 ms·
Programmers should never trust anyone, not even themselves
- mewpmewp2 2y agoBut then you say "trust, but verify" in the post.
- fragmede 2y agotrust but verify translates to trust no one but don't be a dick about it
- nine_k 2y agoTo me, it's rather a postcondition instead of precondition. Trust that a person will do the right thing, but verify that the right thing has actually been done.
- stavros 2y agoWhich is a contradiction, because trusting someone means not needing to verify what they say or do.
- laserlight 2y agoTo the contrary, trust arises from being able to verify. Otherwise, you never know whether a failure is because of ill intentions or errors. That's why I very much dislike “trust, but verify”. I prefer “trust, and verify”.
- stavros 2y agoWhat's the meaning of "I trust you that the amount of cash you've given me is correct" when you then proceed to count it? If you're verifying, why do you need to say "I trust you"? A trustworthy and an untrustworthy person will get equally verified.
- dncornholio 2y agoHas nothing to do with trust. I trust that you will give me the money. I also trust that you counted the right amount. But I still want to make sure you did not make a mistake.
- robertlagrant 2y agoI suppose the question is: why bother with trust? Why not just "verify"?
- t_mahmood 2y agoI trust you, about your intention and effort. But I verify because there are too many moving pieces in the world that can go wrong, that you may have no control over
- dncornholio 2y agoWell the thing is, that’s how trust already works isn’t it? Trust doesn’t require any effort. Trust means I won’t put in effort. So I just verify, because I trust.
- robertlagrant 2y agoOkay, so why say it? Why not mention breathing and eating as well, given we're already doing them? In other words: why is it included?
- worble 2y ago> postcondition instead of precondition. How can you verify as a precondition instead of a postcondition? You can't verify anything until the act has been completed.
- deleted 2y ago[deleted]
- bruce511 2y ago>> Random access of a character in a text buffer could take constant time (for ASCII) or linear time (for UTF-8) depending on the character encoding This is true, but incomplete. All unicode encodings take linear time, not just utf-8. That's because a character can contain multiple code points. Utf-32 allows for random access of code points in constant time, but not characters. Utf-16 has variable length code points so it is the same as utf-8 in that regard.
- myworkinisgood 2y agoYeah, but the author was talking about ASCII. ASCII takes constant time.
- bruce511 2y agoThe author differentiated I the statement between ASCII and utf-8. The reference to the specific encoding (utf-8) was misleading because the reference should have been to Unicode (the mapping) as the issue applies to all Unicode encodings, and is not limited to utf-8. ASCII does indeed take constant time - which I agreed with.
- mjevans 2y agoIMO within a small range iterating isn't too painful. It's probably safe, maybe even close enough to optimal for typical use, to have an array or list of bytestrings for each line. Or maybe more complex Line (of text) objects that record the byte-length, 'codepoint'-length, and '(display)character'-length. There might even be special cases built in for typical and massive documents (number of lines) and overly long lines.
- bluGill 2y agoIn most real world cases N is small and so a linear search for data beats a binary search - the binary search is going to stall the pipeline with cache misses all the time, while the linear search will prefetch everything into the cache before you need it thus resulting in not pipeline stalls. Of course different computers (CPU, memory configuration... they all matter) have different characteristics so where N is large enough is different for each. However in general linear search is fast enough these days. Where it isn't you can look at a profile to verify you hotspot.
- pcwelder 2y agoHigh quality article with some new advices. > Read more documentation than just the bare minimum you need I wish I practiced this before, I'd be as good and quick as some of my brilliant colleagues.
- protomolecule 2y agoI usually do, but not a long time ago after I've read docs on boost::spirit, gpt4 suggested a trick with which I could've come up myself but I failed to connect two different pieces of documentation. This left me wondering if reading the docs thoroughly is still a good investment. On the other hand, having some level of knowledge of a library saves me some time since I can often write things faster by myself than explaining gpt4 in more and more details what I need.
- skydhash 2y agoI love it when projects gave single HTML documentation or a PDF. In the worst case, I'd take a nice site like Laravel's documentation. Any piece of software I use, I try to do a speed reading of the whole documentation or a significant part if it's big. A mental model of all the offered features is a nice help when solving problems.
- mulmboy 2y ago> Failing tests indicate the presence of bugs, but passing tests do not promise their absence. If only :) Far too often I find myself working with tests that patch one too many implementation details, putting me in a refactoring pickle
- yxhuvud 2y agoOr even worse, tests that test implementation details that doesn't matter for the actual outcome.
- hyfgfh 2y agoIf I had a dollar for each frontend test that actually don't actually test anything I would be able to retire by now!
- bdjsiqoocwk 2y agoCargo cult testing. Some people don't understand the point of testing so they just go thru the motions and end up with something that makes no sense.
- blitzar 2y ago"It passed all the tests so it must be working, it must be something you are doing wrong"
- throwawaysleep 2y agoOnly needs to be management that misunderstands. I’ve written plenty of do nothing tests in my time to be sure that management regularly got a report of tests being added.
- orwin 2y agoTests that don't test anything come in at least two categories for me: - test that were useless, are still useless and will always be useless - tests that are currently useless but were used in the "wtf should i write" phase of coding (templating/TDD/ whatever you want to call it). I'm partial towards the seconds, and i like when they're not removed, because often you understand how the API/algorithm was coded thanks to them (and its often unit tests). But ideally, both should be out of a codebase.
- globular-toast 2y ago> In reality, the bank does not just store the money we deposit. It loans away/invests most of the money that people deposit. Our money does not sit idle in a large pile in a vault. Nope. In reality the money doesn't exist. Amazing how many people think that somewhere a cartload of money is physically moving every month when they get paid. When was the last time you deposited anything in a bank? The abstraction is even higher than that. It's just numbers in a computer system. The abstractions work because banks are "too big to fail".
- ttoinou 2y agoAgreed. But a bank failing doesn’t mean the financial system would be down though. We need to get rid of bad apples. Free banking
- IshKebab 2y agoI don't think the author was under the impression that banks physically store money. They meant the digital currency does not sit idle on the bank's asset list. They're just using normal human language.
- globular-toast 2y agoThe deposits aren't assets to the bank, they are liabilities. The loans are their assets (your liability is their asset). They don't need to "do anything" with your deposit because it doesn't exist. If I increment the number 2 to the number 4, have I brought something into existence, in particular 2 "things"? What is that? Why can't I just bring 3 things into existence without incrementing the initial number? If this sounds silly it's because it is. I thoroughly recommend anyone who is confused to a) do their own accounts and b) invent a silly currency inside your accounts and start a bank for your imaginary friends. Just add trust and government support to your bank and you'll be like any other bank.
- IshKebab 2y ago> They don't need to "do anything" with your deposit because it doesn't exist. Uhm yeah they do. If they take my money and then just do nothing with it then they won't make any money from it. Banks invest your money. (I don't think that's the main way they make money - it's probably mostly from credit card interest, but they definitely do it.) The money you pay into banks absolutely exists in every sense. Banks can create money when they issue loans, which I suppose you could argue doesn't exist. But they aren't allowed to create unlimited money. I'd say it exists as much as any other money exists.
- leecommamichael 2y agoWhat does it do to the psyche, to not be able to trust anyone?
- amelius 2y agoProgrammer syndrome.
- DoctorDabadedoo 2y agoCynism and burnout, but if you are in a dysfunctional it's hard to move away from that either way.
- Barrin92 2y agoNothing if you don't take it personally. There's 'not trusting' in the sense of recognizing that most processes or people are unreliable, including yourself and there's 'not trusting' in the sense of thinking everyone's out to get ya or not living up to your expectations. The second one largely has to do with ego and is the one that creates insecure people who usually hold others to different standards than themselves, the first is just a realistic view of the world and thus very useful
- mistermann 2y agoYet another very important portion of reality that science hasn't gotten around to yet. Perhaps we'll find the answer a bit further out in the universe, or deeper inside matter.
- Joel_Mckay 2y agoAfter many years, I settled on a constraint based design philosophy: 1. type checking, data marshaling, sanity checks, and object signatures 2. user rate-limits and quota enforcement for access, actions, and API interfaces 3. expected runtime limit-check with watchdog timers (every thread has a time limit check, and failure mode handler) 4. controlled runtime periodic restarts (prevents slow leaks from shared libs, or python pinning all your cores because reasons etc.) 5. regression testing boundary conditions becomes the system auditor post-deployment 6. disable multi-core support in favor of n core-bound instances of programs consuming the same queue/channel (there is a long explanation why this makes sense for our use-cases) 7. Documentation is often out of date, but if the v.r.x.y API is still permuting on x or y than avoid the project like old fish left in the hot sun. Bloat is one thing, but chaotic interfaces are a huge warning sign to avoid the chaos. 8. The "small modular programs that do one thing well" advice from the *nix crowd also makes absolute sense for large infrastructure. Sure a monolith will be easier in the beginning, but no one person can keep track of millions of lines of commits. 9. Never trust the user (including yourself), and automate as much as possible. 10. "Dead man's switch" that temporarily locks interfaces if certain rules are violated (i.e. host health, code health, or unexpected reboot in a colo.) As a side note, assuming one could cover the ecosystem of library changes in a large monolith is silly. Good code in my opinion, is something so reliable you don't have to touch it again for 5 years. Such designs should not require human maintenance to remain operational. There is a strange beauty in simple efficient designs. Rather than staring at something that obviously forgot its original purpose: https://en.wikipedia.org/wiki/File:Giant_Knife_1.jpg https://en.wikipedia.org/wiki/File:Giant_Knife_1.jpg https://en.wikipedia.org/wiki/Second-system_effect https://en.wikipedia.org/wiki/Second-system_effect Good luck, and have a wonderful day =3
- psychoslave 2y ago> verifying code correctness is impossible Somehow, taking into account the state of our industry, yes. But this is not an absolute truth. I mean, we do have the theoretical frameworks and even tools to come with solutions that allow to proof that code is correct. It’s just that mapping this "know how" with the "how to deal with the expected flow rate feature" is very uncommon.
- tpm 2y agoIt is an absolute truth in the sense that it is true for all code that was not specifically written to be formally proven correct. So, given an arbitrary piece of code, it's impossible to verify it (because of the halting problem).
- skydhash 2y agoIt's not impossible to verify it, it's impossible to automatically verify it with another program. Other issues are the underlying abstract machine (which can have its own bugs) and the surrounding environment (you either need to assert or/and sanitize your inputs).
- versteegen 2y agoThose assertions are a long way off absolutely true! The undecidability of Turing machines in general doesn't say you can't reason about any programs, as you seem to claim, it says there exists programs which have unverifiable behaviour. (Although the proof provides unnatural examples, in practice simple recursive mathematical functions such as the Collatz conjecture will probably always be beyond automated analysis.) Of course software that was not written with verification in mind can be verified correct, provided it doesn't contains things such as an interpreter or complex conditional recursion. There are static analysis tools for analysing programs in languages such as C++ which make use of ATPs (automated theorem provers). For example, most of zlib has been proven correct using Coq. Yes, verification of the entirety of complex programs is in general impossible, but parts of them can still be verified. It's the most common use of ATPs, and an active area of research!
- n4r9 2y ago
- tm11zz 2y agoThis is a really useful mindset as a programmer, but backfires in real-life as it makes you an anxious person.
- eru 2y agoI guess you need to compartmentalise into different kinds of 'trust'. The not 'trusting' you do with a computer is different from the trusting you do with fellow humans in daily life. They just happen to use the same word in English.
- blitzar 2y agoI trust the computer far more than the fellow humans. The computer will generally give a predictable output for a given input. "fellow humans in daily life" .... not so much.
- m0llusk 2y agoAlso from 8 days ago https://news.ycombinator.com/item?id=40764826 https://news.ycombinator.com/item?id=40764826 and 9 days ago https://news.ycombinator.com/item?id=40760885 https://news.ycombinator.com/item?id=40760885. The "A Python script should be able to run on any machine with a Python interpreter." remark is amusing. Recently ended up installing a whole new distribution version just to get Python 3.11 and the new library versions that the script I was running depended upon. Giving a program finish and polish does have this kind of unlimited depth, but it is critical to remember that comes after the initial coding which is always rough with many gaps since that is always where things start. And then we make many choices. Hearing people commit to strong typing because docs are always out of date is another chuckle. Maybe if the docs were kept right from the start, maybe with some use of automatically generated reference pages, then there wouldn't be such frequent problems getting types right in the first place? To each their own, but strong typing hype is just another currently popular method among many. Strong typing has its value, but like every other methodology cannot be absolutely trusted to save programmers from error.
- keepworking 2y agoI think is kinds of "Need for cognitive closure". It is diffrent with "Never trust anyone" and "Everyone can be wrong". the NTA is make us can not to move forward. But allow the Everyone can be wrong makes we can move forward.
- deleted 2y ago[deleted]
- jll29 2y agoThis is a good post, and I agree with the "paranoid porgrammer" attitude being useful. The post could also talk about yet another desirable paranoia, namely "Am I building the right thing?" - so talking to customers/clients/stakeholders/users is arguably one of the most important steps when seeking re-affirmation and controlling one's work. Nothing worse than people who think they understand a technical problem, but it's not the one that the customer wants solved...
- kryptiskt 2y agoI think "trust, but verify" (as mentioned in the article) is a much more useful motto than "never trust anyone". The latter isn't an useful attitude, if you took it seriously you would have carefully check or rewrite everything from the ground up. And then you'd either have to trust the hardware anyway or enlist in a course on VLSI design. "Trust, but verify" is much more practicable, at least if you don't feel the need to verify absolutely everything[0], but is content with doing spot checks of all the features. So, good article with a misleading title. Don't be paranoid. [0] I don't consider 100% test coverage as anywhere near close enough for that.
- fatnoah 2y ago> "Trust, but verify" Even though my entire career has been software, I was an Electrical Engineering major, so I have taken VLSI design (and even designed an 8-bit ALU). My first job was writing embedded software, and would frequently "trust, but verify" the hardware through the use of a logic analyzer. When I pulled out printouts from the analyzer to show the hardware team that the hardware had a bug, the surprised and incredulous look on their faces was priceless. The blow was somewhat softened by the fact that I'd also found a software bug. The constant blame shifting between SW and HW teams is one reason I left that job after less than a year.
- Spivak 2y agoThis is why blameless postmortems are such good thing. Going one step further having a culture where finding a bug or defect in your own code/design is rewarded makes it so people aren't afraid but excited to talk about them.
- ImHereToVote 2y ago"Blame is for small children and God"
- fatnoah 2y ago> This is why blameless postmortems are such good thing. 100%. I'm very much a fan of asking _what_ happened and then figuring out how to prevent it from happening ahead. Look back to inform the future, not to find blame. Ultimately, if 1 person can blow things up, it's a bigger issue at play.
- dwighttk 2y agoThe radical trust of turning on a computer
- atribecalledqst 2y ago> Failing tests indicate the presence of bugs, but passing tests do not promise their absence. As somebody who primarily lives on the testing side of the house, I've definitely run into cases where the developer promises that their unit tests will make a new feature less buggy, then about 5 minutes later I either find a mistake in the test or I find a bug in something that the developer didn't think to test at all. I've also seen instances where tests are written too early, using a data structure that gets changed in development, and then causes churn in the unit tests since now they have to be fixed too. I've generally come to think that unit tests should be used to baseline something after it ships, but aren't that useful before that point (and could even be a waste of time if they take a long time to write). I don't think I'll ever be able to convince anybody at my company about this though lol
- englishspot 2y ago> I don't think I'll ever be able to convince anybody at my company about this though lol especially if the company uses 100% code coverage as a metric for success
- dartos 2y agoI’ve been preaching this for a while. When a codebase gets too big, and devs gets too clever with their tests, the whole test suite becomes complicated. If your test suite is approaching the complexity of the actual codebase (what with layers of mocks and fixtures that are subtly interdependent,) how could you be expected to trust a test you wrote more than the code you wrote.
- bloopernova 2y agoI (sysadmin/devops) am writing some nodejs and the complexity of the tests is confusing to me. I'm a nodejs beginner to be sure, and I'm not experienced enough to verify what copilot gives me. All those mocks, and other Jest code, all seem overly complicated but I don't know of anything "better".
- throwaway2037 2y ago
- lenerdenator 2y agoYou sort of have to trust yourself, but verify it against what others expect. That's the point of code reviews. Trust me; I'm an expert on never trusting myself.
- deleted 2y ago[deleted]
- megamix 2y agoThere's a leaky reasoning about the abstraction hierarchy I think. Beyond, or until a certain layer - I know that I can trust the process. I'm fine baking, I trust the physical process.
- cryptica 2y ago> Programmers Should Never Trust Anyone, Not Even Themselves Yep. Can confirm, the best programmers are often paranoid. I guess over time your brain becomes more logical and you start to notice inconsistencies everywhere around you... Then before you know it, it feels like you're living on planet of the apes.
- nottorp 2y agoMy favourite advice to give out is: "If you feel very smart after writing a particularly intricate piece of code, it's time to rewrite it to be more clear." Speaking of not trusting yourself.
- will1am 2y agoClear and maintainable code is valuable
- throwitaway222 2y ago-Programmers- > People
- ramesh31 2y agoYou do need a certain level of self confidence to actually get anything done though, and not get lost in analysis paralysis. The mantra goes "strong opinions, loosely held". Be prepared to vigorously defend your position, while simultaeneously being willing to immediately toss it aside in the face of overwhelming evidence.
- BD103 2y agoI love the link to the article on time dilation in this article, fascinating! (https://pilotswhoaskwhy.com/2021/03/14/gnss-vs-time-dilation-what-the/ https://pilotswhoaskwhy.com/2021/03/14/gnss-vs-time-dilation...)
- agentultra 2y agoTo me, this is the argument for formal verification. I don't want to hear a hand-waving explanation that this algorithm will always complete. If the algorithm is sufficiently complex I want proof. Otherwise, why would I believe you? Abstractions, in the mathematical sense, always hold (unless there is a flaw in the definition itself). Axioms in any sense are always going to throw a wrench in things. Thank Godel. But that shouldn't mean we cannot make progress. Do the work, show your proof! Think hard! Although sometimes all you need are a few unit tests. They key is to develop the wisdom to know when unit tests aren't sufficient for the task at hand.
- bee_rider 2y agoI dunno. Even in some fairly math-y situations, line solving sparse linear systems, we get stuff like BiCGStab which often will work well and converge in cases where we can’t prove that it must. CS seems mostly good for proving that everything is hopeless in the rigorous general case and, hey, here are some heuristics to give you hope again.
- atrus 2y ago> Abstractions, in the mathematical sense, always hold (unless there is a flaw in the definition itself). Axioms in any sense are always going to throw a wrench in things. Thank Godel. But that shouldn't mean we cannot make progress. But this seems like an argument against formal verification. Formal verification is 100x harder than writing tests...and still doesn't guarantee correctness? Those axiom wrenches are still there, those flaws in the definition are still there, not to mention the flaws in the proof writing. All that extra effort for what gain?
- agentultra 2y agoIt guarantees correctness vis. the axioms chosen. That's a much more powerful statement and guarantee than a unit test which only exercises a single example. A formal proof that an algorithm makes progress, doesn't require a lock, or whatever property the proof is arguing is 100% guaranteed for every case. For example, a simple function over the set of integers. A unit test can only test individual elements of the set. A proof demands more: the property must hold over all elements of the set. The Incompleteness Theorem puts a limit on the provability. That hasn't stopped mathematicians from pursuing the formalization of mathematics. It shouldn't stop computer scientists and programmers either. In fact it tends to make us more honest about the limits and capabilities of our systems.
- vzaliva 2y agoAs someone who routinely formally verifies code, I can confirm that you should not trust yourself. I keep finding bugs and hidden assumptions in the most trivial code or even in code covered with unit tests. In my opinion, formal verification is the only way to truly trust some code.
- simonw 2y agoThis is why I try to have my code commits bundle tests along with any corresponding implementation changes. The job of the test is to PROVE that the updated implementation code did what it was supposed to do - both now and into the future. If the test doesn't do that - if it still passes even if you revert the implementation - then the test isn't doing its job.
- mistermann 2y ago> So if abstractions can be problematic, then should we try to understand a topic without abstractions (to know cars as they really are)? No. When you dig beneath abstractions, you just find more abstractions. Demonstrating that language and colloquial "logic" are also abstractions. > It’s turtles all the way down. Memes and catch phrases are abstractions. > These layers of abstractions go down until we hit our most basic axioms about logic and reality. Reality too is an abstraction. Luckily all humans run Faith, and it runs invisibly, otherwise I suspect we'd have not made it this far. Though, it now seems like that which saved us may now take us down (climate change, nuclear weapons, other/unknown). > Trust, but verify. Haha...of course, just use logic and critical thinking!
- atoav 2y agoAs an electronics guy this is really ingrained. Not only could you easily waste days on a problem if you assume things rather than check them, in some cases you might also get a painful experience or depending on what you're working on that mistake might even be your last, burn down a house, kill others or what not. Checking your priors is one thing, ensuring your stuff fails gracefully if they are abnormal another. Meanwhile most software won't even handle a network disconnect gracefully. As more and more stuff™ is moving from hardware into software, for totally understandable reasons, the absolute number of software that could absolutely ruin human lifes is growing. This calls for higher standards when it comes to the whole field of software engineering.
- skydhash 2y agoHardware fails because of physical rules, software is more abstract and more flexible. I agree that higher standards should be required, but business people won't do it as it will make it as slow as hardware engineering. I'd love to see formal verification for at least the business core of any application. That should incentivize product managers to write better specifications.
- atoav 2y agoThe electrical grid is typically 230/120 Volts AC at 50/60 Hz. A bad design will rely on that and fail once something about that is out of whack in either direction. A good design will gracefully shutdown, or operate normally within reasonable thresholds. You can apply the same principle to programming (in fact, many programmers do). If your program falls completely fall and explode into pieces once any peripheral, call, timing, or whatever isn't as expected, then it isn't a resilient program. If it fails in unexpected ways while still writing data you might even have a dangerous program. So many programmers are happy with writing a program that works. That would be as if a car manufacturer would be happy to call it a day if the car manages to accelerate.
- NoPicklez 2y ago"Trust but verify" Also performing a critical self review and ensuring you remain skeptical
- cgannett 2y agopage is crashing for me so I figure I can share this: https://github.com/carbon-steel/carbon-steel.github.io/blob/master/_posts/2024-06-19-abstractions.md https://github.com/carbon-steel/carbon-steel.github.io/blob/... perfectly readable as its Markdown on regular Github