[HN Gopher] Code only says what it does ___________________________________________________________________ Code only says what it does Author : mjb Score : 95 points Date : 2020-07-06 16:41 UTC (6 hours ago) (HTM) web link (brooker.co.za) (TXT) w3m dump (brooker.co.za) | deeg wrote: | When I teach coding I tell the students to document their code | well but don't document _what_ the code is doing it. That should | be evident from the code itself (if it 's not, then consider a | refactor). Rather, explain _why_ the code is doing it. | sosborn wrote: | The marketing corollary is that metrics only tell you what | happened, they cannot tell why. Yet somehow, entire companies | have been built on the promise that they can answer the "why" by | looking at the metrics. | ChrisMarshallNY wrote: | I comment my code[0]. | | I don't particularly care what people think about it. | | I will say that I have turned over a _lot_ of code, over the | years, and virtually _never_ get asked about what it does. When | people ask me about my code, I generally tell them where to look, | and contact me if they need explanations. | | I don't get contacted, so I guess they could figure it out. | | I also tend to write a lot of supporting documentation. | | We do have to be careful, though. Documentation can easily become | "concrete galoshes"[1], so things like header/auto documents are | pretty important. | | [0] https://medium.com/chrismarshallny/leaving-a- | legacy-1c2ddb0c... | | [1] https://medium.com/chrismarshallny/concrete- | galoshes-a5798a5... | ChrisSD wrote: | A big issue with documenting what the code does is that the code | and documentation can very quickly fall out of sync. As this | posts says, it's much more useful to document the intent of the | code, or _why_ there 's this mess of seemingly hacky code (see | issues #80681, #82108, #66065). | | Also be wary of unit tests that are overly tied to the specifics | of an implementation. These can be worse than useless when it | comes to changing code. I.e. asking "why are my tests failing?" | and finding out it's only because I breathed near the code. | mrkeen wrote: | System tests too! | | The last code-base I worked on had do-everything system tests | (with unexpectedly good coverage, I'll admit). They were so | slow and passed often enough that I didn't immediately spot | flakiness. | | I got suspicious when the tests started failing regularly when | I added new unrelated code. | saagarjha wrote: | About the only time I use comments are to delineate a block of | code that for whatever reason can't be a method or because I am | working around some bug and I think I might be tempted in the | future to remove that code as "useless". (Think "the | dispatch_main here ensures that the code runs on the next runloop | iteration, which is necessary for the animation to work".) | cloogshicer wrote: | The huge value that I see in a formal specification language like | TLA+ is that we could have a precise way of communicating the | problem in a way that is agnostic to the implementation language. | | Imagine something like StackOverflow, but instead of posting a | question, you post a formal spec. Thinking even further, you | could then find a way to combine/interface these specs and build | something like a global database of computational problems. | | We're currently doing this already with StackOverflow, but we're | focusing on the implementations, not the problems themselves. | | Please correct me if there's a mistake in this line of thought, | I'd love to know. | trixie_ wrote: | If I had a nickel for every programmer who thought their code was | so good it didn't require comments... or thinks somehow that unit | tests make up for comments... only to come back years later and | have no idea why the logic is working how it is. | dnautics wrote: | It's a matter of judgement. I've read code in languages I don't | know, even, where I could immediately figure out what was going | on without reading any comments. I've also patched libraries in | ten minutes without reading comments. It's certainly possible | to write code that doesn't need comments, though perhaps, we're | not the best people to judge when that's the case or not for | our _own_ code. | trixie_ wrote: | Same here. Though if you are putting thought into the code | you are writing - the logic, the structure, etc.. Then those | thoughts should probably be written down as well as comments. | baddox wrote: | It seems to be fairly common for experienced programmers to | point to unit test code as a way to explore or understand an | open source software project. I don't doubt that this works for | them, but it definitely doesn't work for me. When I'm trying to | explore a new software project, the first thing I want to do is | find the relevant "entry point," which is arguably the exact | opposite end from the unit test code. | henryfjordan wrote: | Tests that target the surfaces of the project (public APIs, | endpoints, etc) and code examples start to blend together at | some point. "Here's a basic example that should do X" sounds | a lot like "Do something basic and assert it does X". | DreadY2K wrote: | One thing that I like about Rust is that they actually | allow you to merge those two into one. In your | documentation of anything, you can include code snippets, | and those code snippets become tests that can ensure that | the documented behavior still applies to the current code. | baddox wrote: | I think the biggest problem with using unit tests for this | purpose is that unit tests tend to (rightfully) spend a | disproportionate amount of lines of code on edge cases. | dllthomas wrote: | Where applicable, this is what doctests are for, and | they're magical. ... where applicable. | dfinninger wrote: | Yes, this is how I use them as well. I'll go to the unit | tests after I have a decent understanding of the project | and am looking for examples that aren't covered in the | README. | selykg wrote: | This was a thing at my last job. The lack of comments always | made me cringe. While not every line needs a comment, there's a | reason why comments would be useful, especially in security | software. | | I learned a lot of bad habits there and I'm glad I no longer | work there. | | Their excuses were literally "no one reads comments" "no one | keeps comments up to date" "my code is self documenting" etc. | trixie_ wrote: | The self documenting one always gets me. It's not like the | person has never read code that is difficult to understand. | | Yet they think it is just other people who write 'bad' code. | Their own code can't possibly be bad. In fact it is so good | that it 'documents itself'. It's just a statement that drips | with arrogance. | selykg wrote: | Ya, but with a security product there are important | considerations and while we commented on areas where we | fixed a bug due to something fixable, it was a pain in | general. | | Decisions maybe don't belong in code but with a security | product I feel there has to be some quality level of | comments to explain why and how. Someone coming along later | can't be expected to be in the authors head and the author | won't remember all this stuff years later when it might | matter or need to be rewritten. | | Such a shit show | tigershark wrote: | Clear code and clear tests absolutely don't need comments that | explain them if they are really clear, at least for me. | Comments are extremely useful to explain something unexpected. | Commit messages are too limited to explain properly a use case, | but linking to a Jira with the proper explanation does the | trick. From the tests you can see both the typical use cases | and the correct way of using some piece of code and have a | guarantee that the code respects the specification. With the | comments you have none of this guarantees. I had the opposite | experience from you apparently, the people that I worked with | that used excessive comments were not up to par with the rest | of the team. Also it may related to the mental model, comments | just break my flow and make more difficult for me to read the | code. | trixie_ wrote: | Right you are exactly the kind of person I'm talking about. | You think your code is clear. It is not. The logic your code | performs is the distilled by-product of higher level | reasoning. Reasoning that should be the basis of your | comments. | | People reading your code will not be in the same mind state | that you were in when you wrote it. That is what the comments | are meant to assist with. | | If you write comments for anyone, write comments for yourself | first. You will not remember years from now the reasoning | that went into the code your wrote. | [deleted] | sktrdie wrote: | What I've noticed is that code is the only medium of | communication that is non-ambiguous. Designers, product people, | stakeholders, etc, all use _ambiguous_ mediums. It's impossible | to understand just how pedantic and explicit you need to be when | writing code versus, say, giving your human colleagues | instructions. | | So it's 0% ambiguity for code. 100% ambiguity for the rest. In | other words, communicating with the computer is overly pedantic, | and code bares all the frustration. Can we make it more fair? | 70-30 perhaps? | | Rather than concentrating on mediums that help with communication | (as this post mentions: Design Docs, TLA+, comments...) I want a | new medium that allows me share the burden of overscrupulousity | with the rest of the people in my team, and not just developers. | webmaven wrote: | Pseudocode, perhaps? | rcshubhadeep wrote: | Here is little demo of codeBERT - https://youtu.be/oDqW1JHmaYY | | codeBERT is trying to predict if a certain function and its | docstring are associated or not. | | Thought about sharing it, I guess it is interesting in this | context | bob1029 wrote: | If you want your cake and also the ability to consume it, you | might want to consider what functional programming can do for you | regarding the ability of your codebase to self-document itself. | Having type systems that are very closely aligned with the | abstract business model is the best way to avoid frustration when | you are trying to figure out why something is the way it is. | | The trick is understanding that functional vs imperative is a | spectrum, and trying to force 100% on one side or the other is | how you wind up killing any project. We find that keeping our | business-level abstractions functional with the underlying | infrastructure code imperative provides the best of both worlds. | The code that is changing and analyzed most frequently is in the | functional domain, whereas code that we touch maybe 1-2 times per | month lives in an imperative domain (but sometimes functional | wherever it makes sense here too). | ajuc wrote: | I find functional code much shorter and cleaner, but also when | you want to change something along a new axis you need to do a | much bigger rewrite than with imperative/procedural/object- | oriented code. | | OO code: "here's a detailed and llong-winded description of | what happens that's hard to understand. Ignore 95% of it and | change that 1 little detail and hope for the best" | | Functional code: "here's a concise and easy to understand | description of what happens, understand it fully, throw it | away, and create a new, just as clear and concise description | of what should happen from now on" | corbins wrote: | The counterexample here is the declarative style of programming. | Most ideally this looks like an executable spec and is | documentation itself. | lmilcin wrote: | Only for simple cases. When it becames complex enough the same | problems show. | | Example: CSS. | ativzzz wrote: | Sure, but then you offload the complexity to the functions used | as the declarative building blocks, so you do the documenting | in a different place, though you will probably end up | documenting complex declarative business logic anyway. (like | why is process X that is so similar to process Y require Z | different declarative blocks) | voiper1 wrote: | Relevant: Writing system software: code comments. from | http://antirez.com/news/124 + | https://news.ycombinator.com/item?id=18157047 | client4 wrote: | This article fits nicely with the recent post discussing how | Linus spends the majority of his time writing emails. For | projects with n+1 contributors, inter-contributor communication | is just as important as what code is being written. Emails, | commit messages, code comments, docs, are all just different ways | to communicate. | | I always think of the Underhanded C Contest[^1] as my favorite | example of readable code that doesn't act as expected after a | quick read. | | [1] http://underhanded-c.org/ | dllthomas wrote: | Code is a mixture of what and how (and with IaC, sometimes who | and where). | | I agree that "why" is the role of documentation. I've been | experimenting with tying the two together with (machine checked, | automatically surfaced) cross-references, so we can better know | what bits of documentation a test supports, &c. I haven't yet | gotten rigorous about it. | rawoke083600 wrote: | Ja to me the "rule-of-thumb" is still: "Code Is The How, Comments | Are The Why" | bryanrasmussen wrote: | Should we be looking out for lying code? | https://softwareengineering.stackexchange.com/questions/2023... | phendrenad2 wrote: | It gives me no end to pain that "Comments are lies because they | aren't code" is a fad that we're currently suffering through as | an industry. For decades prevailing wisdom was that comments were | a net benefit, and now in the last few years this trend has | become prevalent. How much perfectly-good code is going to have | to be rewritten from scratch in 10 years because no one remembers | what it does? | wanderr wrote: | If no one understands what it does, it's not perfectly good | code is it? Of course there are rare cases where code cannot be | simplified, made more readable or self explanatory and in those | cases comments are vital. But the aim should be for the vast | majority of code to be easily readable by humans. | Jtsummers wrote: | Essential versus accidental complexity. | | Perfectly good code can be unclear because of the accidental | complexity included within it. Memory management, error | handling (especially in languages with less expressive type | systems), configuring hardware/database/network connections, | etc. Those things are important, but they prevent the | essential portion of the program from being expressed on its | own. | | Type systems, a brief example: C versus Ada. Implement a | network protocol where the data packet has specific n-bit | sized fields with ranges less than the maximum for that size. | You can easily do this in both languages. But in C, you'd | either need to add bounds checking to all of those fields or | risk letting errors propagate. That error handling obscures | the essential portion of the program. In Ada, you make a type | that is n-bits and only accepts values of the correct range. | The errors can still exist in received packets, but the error | checking is partially elided from the code because the type | system itself can catch it. | | There's nothing _wrong_ with the C code, and there 's nothing | _wrong_ (many will disagree with that) with choosing C to | implement the protocol. But it will increase the complexity | due to factors beyond the inherent, essential complexity of | the network protocol itself. | phendrenad2 wrote: | I mean it's "perfectly fine" because the people building it | know how it works (because they were there when it was | built), and think they don't need comments to help out future | maintainers. | softwaredoug wrote: | "works as coded" | | My last job we used to say that if asked whether our code was | correct or bug free ;). Often the devs get thrown under the bus | if something doesn't work "correctly" when in reality it might | perfectly pass all unit tests based on the best understanding of | the problem. | | Of course whether we could get any support to help define | "correct" from anyone was another matter... | xsmasher wrote: | This fits my theory of programming, and theory of bugs - We | take a problem, create a plan, and then write code that | implements that plan. | | Defects can come from: * having/being given | the wrong problem * right problem, but plan does | not actually solve it * right plan, but your code | did not correctly implement it | bobbane wrote: | Any thoughts on applying this article to... | | programming languages defined by a single portable | implementation? | aequitas wrote: | My pathway into software development was through electrical | engineering and embedded systems. So I don't know if this applies | to other ways into software development as well. But what really | stood out to me in the beginning was how useless code comment | where. I would almost always see code like this: | x = 1; // assign 1 to x y = x * 2; // multiply x by 2 | | I don't know if it was because they thought electrical engineers | needed to be explained everything about code. Or if it was | because all teaching material used this style and people just | copied it. But I never understood why you would add comments like | this, but had to do so anyways otherwise I would not pass my | exams. | | It took me a while to learn that comments are the tool in which | you can express your expectation of what the code should do. | ris wrote: | So many times this. | | "Clear code shouldn't need comments" - clear code can make it | easy to see _what_ but it can never say _why_. Let me know what | corner cases you thought about when you wrote this. | | "The comments are in the commit messages" - almost nobody _ever_ | goes looking for them there, they 're effectively invisible from | `git blame` when they _remove_ lines, people rarely make fine | grained enough commits to be able to target specific lines or | blocks sufficiently with context. | | "Nobody ever updates comments, so they're always out of date" - | don't hire such people. It is an crucial task _resolving_ the | meaning of comments to make sure everything still makes cohesive | sense. Neglecting to do this will often lead to commits that don | 't quite grok any subtleties of the original design. Don't make | the _reader_ of the code do the job of trying to piece together | the scattered history of 5 different people 's intentions. Of | course, it's also useful to try to keep comments as close to the | code in question as possible so that references which need | updating are obvious to see. | cjfd wrote: | Clear code needs some comments. Not many, though. If you write | a numerical algorithm it probably needs an explanation or a | reference to where it came from or something like that. | Generally, one needs a comment when it is difficult to figure | out why something was written that way. In many cases comments | are not needed. I perhaps write a comment once every ten files | or maybe even less but then it tends to be a rather long | comment because the thing explained is very non-obvious. The | kind of comment that I hate seeing is when somebody feels the | need to tell me what methods are constructors or similar such | nonsense. | tigershark wrote: | Clear code and clear tests shows both the what and the why. | With the additional advantage that they can't diverge and be | out of sync like the comments because otherwise the tests will | fail. Comments should be used to explain something unexpected. | Commenting each line of code is a recipe for disaster. | sanderjd wrote: | > _almost nobody ever goes looking for them there_ | | I've seen this claim a number of times and it's always so odd | to me. One of my most common activities each day - certainly | more common than the activity of writing new code - is reading | the commit history for different files. It's always surprising | to me to hear that this is an uncommon thing to do. | | Edit to add: But I also think comments and documentation of all | kinds are good. I don't advocate good commit messages instead | of comments, but rather in addition to comments. The more | documentation the better. | aflag wrote: | Which tool do you use to view commit messages and revisions | for each file? I think one of the reasons this is uncommon is | due to lack of tooling (or wide-spread knowledge of them). | I'd really like to be able to easily see all the previous | commits that affected a specific line while I'm editing code. | But I usually have to resort to interacting with git, rather | than having something popping up on my screen (I use pycharm | and vim regularly). | nfRfqX5n wrote: | I use gitlens for vscode | recursive wrote: | Visual Studio has this. It's called "Annotate". | nemetroid wrote: | I use tig, which is a terminal UI. The "blame" view has a | shortcut to jump to the commit _before_ the one that | changed a given line. This makes it easy to quickly dig | backwards through the history of a file. | kevinschumacher wrote: | Not the person you were replying to, but in PyCharm: | | - right click on the line number, click Annotate; this | gives you the commit date and author in the gutter | | - hover over the date/author name; this gives you the | commit hash and message | | - click on the hash itself in the popover; this shows the | git commit graph on the Version Control tab | | - right click on the date/author name, click Annotate | Revision; this opens up the version committed then, with | its git blame in the gutter. | Braxton_Hicks wrote: | Agreed. I think the "nobody ever goes looking for them" case | is common for code bases where people are not writing good | useful commit messages. | phendrenad2 wrote: | Commit messages are much harder to get to for a given line of | code than a comment would be. | Ma8ee wrote: | A lot of comments can (and should) be replaced with good | naming. Sometimes the only reason to introduce a variable or | function is to name something. The advantage is that it is | harder to not read a name than it is to not read a comment, and | it is more obviously a bug when we try to set a variable, or | make a function calculate, something not agreeing with its | name. | phlakaton wrote: | > people rarely make fine grained enough commits to be able to | target specific lines or blocks | | Take your own advice then: don't hire such people. Why would | you insist on maintaining documentation and not maintaining a | reasonable change log in your commits, if knowing "why" is | important to you? | | (I make the advice tongue-in-cheek btw. Better to educate and | lift developers up wherever you can than just freeze them out. | Not everyone has the experience with these things that we do.) | | There's not a one-size-fits-all solution here. Different orgs | handle their code history different ways, but having tasted the | power Git gives you over certain other VCSes to make the commit | log really useful as a record of change, and having taken | advantage of that feature several times myself, I wouldn't want | to go back. | | This follows another comment I just made on the topic: | https://news.ycombinator.com/item?id=23743973 | thdrdt wrote: | The only time I place comments is exactly this: to explain why. | | Today I just had this example. I placed a little sleep in a | loop. But there is absolutely no way to know why it is there. | So I inserted a comment to explain the loop is DOSing a server | by constantly requesting it and the sleep will reduce the load | on that server. | | Those comments are not only for others but also for yourself. | Even weeks from now it is easy to lose track on why you did | things the way you did. | | Comments on why are very helpful. | pronoiac wrote: | > _" The comments are in the commit messages" - almost nobody | ever goes looking for them there_ | | Consider it another tool in the toolbox. I've gone spelunking | through git history to decipher the reasoning of something | still in use, though comments had been deleted and no one had | documented it before me. | clairity wrote: | yes, comments should be considered code too, but for humans, so | later coders (including your later self) can effectively | simulate (not but necessarily replicate) the prior code-writing | process(es). it's as critical as the code for machines. | | which is to say, the comments should be kept concise and | current too. | codegladiator wrote: | > "Clear code shouldn't need comments" | | That's like saying articles don't need summary. | unoti wrote: | Agreed; or like saying "You don't need a map; you can clearly | see where this road leads if you follow it far enough." | keithasaurus wrote: | I agree with most of the points made here, though I think some of | the bias toward up-front exhaustive documentation is probably not | a good fit for most of the projects I've been a part of. | Prototyping often reveals necessary changes due to resources | constraints, or to unconsidered corner cases. Documentation needs | to be a living thing as much as the code, and I think that pushes | you toward documenting within the code more than externally. | | One of the more important points the author brings up is that | authorial intent and the 'why's of comments are the most | important. A corollary I'll bring up to that is that the 'what's | should be encoded in tests. Tests can be great documentation, and | they have the added benefit of informing developers when the | goals of the software is being voided (when they fail). | | What has worked for me is conceiving of documentation this way: | | - Design Documents: Historical use only, not to be updated. | | - Readme: intro to project; why it exists, overview of how it's | meant to function, how to edit, etc. Tends to be updated when big | things change. | | - Code comments: why something exists, what considerations were | made in that code's creation | | - Test descriptions and comments: binding goals of previous | development to future development | | This approach has done a pretty good job of keeping documentation | from getting too out-of-sync with code while enforcing basic | business objectives, still tilting the balance toward development | rather than documentation. | jariel wrote: | This is quite good actually. | | I would add that some elements of design are worth keeping up, | like a general architectural overview and the details of some | things, like state-machines or specific kinds of statefulness. | | It can be done in the comments, at the package level, that way | developers can keep it up to date without much fuss. | foodigger wrote: | most people cant read it anyway so what does it matter? | dkarl wrote: | _This is a major problem with code: You don 't know which quirks | are load-bearing. You may remember, or be able to guess, or be | able to puzzle it out from first principles, or not care, but all | of those things are slow and error-prone._ | | This is a problem from both the negative (not breaking things) | and positive (knowing how to add things) perspectives. The | positive perspective was written about by Peter Naur in one of my | favorite software engineering papers, "Programming as Theory | Building," in which he describes how the original authors of a | codebase have a mental model for how it can be extended in simple | ways to meet predictable future changes, which he calls their | "theory" of the program, and how subsequent programmers | inheriting the codebase can fail to understand the theory and end | up making extensive, invasive modifications to the codebase to | accomplish tasks that the original authors would have | accomplished much more simply. | | I highly recommend finding Naur's paper (easily done via Google) | and reading it to understand why divining the "theory" of a | codebase is a fundamentally difficult intellectual problem which | cannot be addressed merely by good design, and not with 100% | reliability by good documentation, either. | Jtsummers wrote: | This is important to understand when moving through the early | stages of a project. | | Many projects go through a clear prototype stage (where a lot | of disjoint things are written, like a set of utilities to | print out information on a file based on the format spec, make | files with hardcoded content, etc.), then a system starts | coalescing, and finally it's released. | | The problem I've encountered is when the prototype is _too_ | good. It 's an 80% solution, it seems to do everything that's | wanted, but the people who wrote it | (contractors/consultants/too expensive older devs) aren't the | ones who are tasked with finishing the last 20%. The original | developers may have understood how to create that last portion | with what they'd written, or they may have intended to throw it | away [0]. | | The new developers don't know what's present (and so recreate a | lot of existing capabilities), don't understand how to extend | it properly (so a lot of copy/paste when the original devs laid | out a nice extendable system with generics and or interfaces or | whatever the language provides), and the whole thing turns into | a mess. This communication between developers is critical, but | usually absent. | | [0] "This is more of a proof of concept, it does everything you | want for converting two file formats between each other, but | doesn't scale yet because it's all 1-to-1 mappings, we are | working on the intermediate representation now that we have a | firmer grasp of what's needed." | | "Oh, that's fine, you guys can go work on the next project | we've got a crack team that can wrap this up." | | "...Ok, thanks for the money." | | The crack team never makes that intermediate representation and | just creates 1-to-n mappings between each format. The explosion | in code size becomes unmaintainable, most of the mappings are | the result of copy/paste, and bugs proliferate throughout | because, while fixed in one section, they don't realize how | many other places that same bug resides in. | | EDIT: For the record, [0] started off short enough to be a | footnote then grew to be too long for it, and I forgot to edit | it properly when I came back from getting a glass of water. | hinkley wrote: | I think I have to disagree with Naur on this, in that people | using the Scientific Method don't ship their theories, but we | do. | | As a scientist who has just succeeded in testing a hypothesis, | I now need to go back and document a simplified series of steps | that should lead any independent party to the same phenomenon. | Once we are on the same page, they can confirm or refute my | theory based on their own perspectives on the problem space. | | During that process I may discover that I based half of my | experiment on another hypothesis that I never tested, or was | plain wrong. Now I've discovered my 'load bearing' assumptions. | I may discover something even more interesting there, or I may | slink away having never told anybody about my mistake. | | Essentially, scientists still 'build one to throw away'. We | haven't in ages. And my read on Brook's insistence that we | build one to throw away is that it was aspirational and not | descriptive. And notably, he apparently recants in the 20th | anniversary edition (which is itself 25 years old now): | | > "This I now perceived to be wrong, not because it is too | radical, but because it is too simplistic. The biggest mistake | in the 'Build one to throw away' concept is that it implicitly | assumes the classical sequential or waterfall model of software | construction." | | So we are very much at odds with the scientific method. And we | have the benefit of hindsight. We have seen the horrors that | can occur when you take the word Theory out of context and try | to apply it to non-scientific theories. We should learn from | the mistakes of others and summarily reject any plan where we | do it too. | | In other words: next metaphor, please, and with all due haste. | Jtsummers wrote: | I think I have to disagree with you on this one, I've used | the scientific method (though not in an explicit checkbox-y | way) plenty of times to ship and debug code. | | In particular, since (as I've said on this forum many times) | I work primarily on the maintenance end of software. I don't | know what the creators or previous developers were thinking, | especially with more recent projects (documentation quality | has really gone down hill, people call autogenerated UML | diagrams "design docs", but without commentary they only | reflect the state of the system, not its design). I have to | try different changes based on my understanding of the system | and see the consequences. That is, I form a hypothesis about | what will happen if I do X, I do it, I collect the results | and I've either confirmed my hypothesis, refuted it, or left | it in an indeterminate state. I form another and repeat. Over | time I build up a model (theory) of how the system behaves | and should be updated/extended. Since I can't keep tens of | thousands of lines of code in my head, let alone hundreds of | thousands or millions, I always only have a model (theory), | because I never have the totality of it in my mind. Though | good code, with good use of modules, makes it easier to keep | large chunks in mind, I still have to have a model of how | those modules work and work together. | | Hell, this is half (or more) of testing for older software | systems. You put in some input and see if you get the output | you expected. If you don't, you evaluate why (is my model | wrong or is the system wrong) and repeat. | webmaven wrote: | Insofar as "what happens when I do this?" goes, it neglects | the null hypothesis. If you don't pay attention to | falsifiability can you claim to be doing science? | hikarudo wrote: | On the topic of the "theory" (mental model) of a program, I | recommend John Ousterhout's book "A Philosophy of Software | Design". You get such gems as: | | "... the greatest limitation in writing software is our ability | to understand the systems we are creating." | | "Complexity manifests itself in three general ways... change | amplification, cognitive load, and unknown unknowns." | | "Complexity is caused by two things: dependencies and | obscurity." | | "Obscurity occurs when important information is not obvious." | | "The goal of modular design is to minimize the dependencies | between modules." | ponker wrote: | I've had that experience describing the plot of a novel to | friends of mine. The novel is pretty complex and covers ideas | in crime, internet anonymity, memetics/virality, and then some | technical things with vehicles and atmospheric science. Some | friends I've talked it through with, they come up with ideas to | add stuff and it's like "that makes no sense for this novel, | but it's not a dumb idea given how little of the _theory_ of | the novel I 've communicated to you." Whereas other friends | seem to immediately grasp onto the theory and make suggestions | that actually fit with the overall concept very well, and | usually recommend small changes rather than wholesale plot | rearchitectures. It's like an architect coming in and saying | "we should move this door two inches so that this door doesn't | bang this wall" vs. "We should build this whole house as one | story into the side of a cliff." | mjb wrote: | Thanks for sharing that, I'll read it! | | I do agree that comments, documentation, and other artifacts | aren't sufficient to solve this problem. The closest I've come | is with formal specification, where the intent of the program | can be communicated very clearly. Multiple approaches are | needed. One of those approaches is continuity: Keeping people | around who are familiar with the code base and can pass on this | knowledge to others. | kevsim wrote: | I think the most reliable thing to see what quirks are load | bearing is tests, particularly regression tests. You change | something, you break expected behavior, you fix it and you write | a test. Now the next person may wonder if some quirk is load | bearing, but they'll know for sure when running the regression | tests. | | Additionally, I'd say naming things, though one of the hardest | things we have to do, can go a long way towards explaining the | "why". Some programmers I've worked with have a knack for knowing | just went to break a giant line into separate lines, giving local | variables great expressive names, and all of a sudden the code | reads a million times better. | | All that being said - I agree with most of the points of the | article and do push my teams to do a lot of upfront writing down | of designs. These things tend to go stale, but in the moment | they're a great tool for fleshing out ideas and sparking | discussions. | macintux wrote: | I've had similar arguments here once or twice. There's so much | context that isn't deducible from code. | | You rarely need to document the "how" (that much should be | evident if the code is well-written) but you absolutely should | document the "why" (or, often as important, the "why not": what | code _could_ be here but isn't). | throw1234651234 wrote: | Give me an example, and I will write you code documenting the | business context. | Jtsummers wrote: | And then what? You throw away the example specification so | that the why only continues on in the code? | | And after 10 years of maintenance, the code has drifted with | each iteration so that the why is no longer clear in the | code. | mjw1007 wrote: | I agree that you shouldn't document "how", but when I'm reading | unfamiliar code, I find I what I miss is "what", not "why". | | To my mind, in well-written code each function should be | documenting its contract: what it assumes, what it guarantees | if that assumption holds. | | (And if it turns out that what you'd write is just the | function's name and its parameter and return types with a few | grammatical particles added, maybe it's OK to omit the | documentation.) | | Then if you find that in order to do that you have to write a | little essay, or you need terminology that doesn't correspond | to a named thing in the codebase, or you're repeating yourself | in multiple comments, that tells you something you need to put | in higher-level documentation. | gimboland wrote: | Yes. Floyd-Hoare logic is worth learning about in this sense | -- a formal system for imperative languages where the rules | essentially say "given preconditions X and code Y, if X is | true before you run Y, we guarantee Z to be true afterwards". | I've never ever ever proven code correct using this | formalism, but that way of thinking permeates my every action | as a programmer. | lmilcin wrote: | Whether or not to document "how" will depend on the target | audience. | | The code is written for people to read and only incidentally | for computers to execute. From that point of view the target | audience will matter a lot. I agree that in most cases, you | expect the audience to be on level with the code and if you are | writing code that is not on level with the audience (for | example it is way too advanced) then you are doing something | wrong (at the very least not considering who will be working | with it). | | But not always. | | Example: I do with a lot of bright quants. With regards to code | that does a lot of complicated calculations, they typically | understand "why" but might need help with understanding "how". | | Another example: when your audience is mostly junior team you | might want to explain "how". My current project starts using | more and more reactive constructs and oftentimes I throw in an | explanation of "how" when I, for example, get queries to | explain during code reviews. ___________________________________________________________________ (page generated 2020-07-06 23:00 UTC)