8 ms·
So your defense of literate program gives, as a defense, what I would think of as an attack on literate programming: Take this strawman for instance, how cou
by mkozlows 10y ago
So your defense of literate program gives, as a defense, what I would think of as an attack on literate programming:
Take this strawman for instance, how could you find the bug in
the following code without the accompanying comment?
// Print every other line of the array to the console
for (var i = 0; i < myStringArray.length; i++) {
console.log(myStringArray[i]);
}
This shows how important intent is to a program. Yes, the
example is trivial, but without that comment, how would we know
that it's wrong?
Because the problem with that is that now you have two competing sources of authority -- the comment, and the code. One of them is right and one of them is wrong. But which is the right one?
In the real world, the answer is almost always "the code that's actually been executing, rather than the comment that hasn't," which is why it's a good idea to minimize commentry of that type, to prevent confusion on the part of the reader.
So if you're doubling-down on literate programming, how do you address that problem? That article says, "Inconsistencies between the code and the prose are themselves errors in the program and they should be treated as seriously as a buffer overflow," but does Eve actually do that? It's hard for me to see how it could, in the examples given.
(If the idea is simply that this is extra work for the programmer to do -- that they need to describe every implementation twice, once in code and once in English -- I submit that it's not very human-focused at all, if those humans are programmers.)
- CGamesPlay 10y agoWait, what? The code is a translation of a requirement to an implementation. The comment describes the requirement. The only problem with competing sources of authority is when the comment disagrees with the real requirements of the programmer/business/whatever. As another example, what if it were a method name instead of a comment? function printEveryOtherLine(myStringArray) { for (var i = 0; i < myStringArray.length; i++) { console.log(myStringArray[i]); } } Is your argument that the method name is incorrect because the code dictates a different behavior?
- computerphage 10y agoThis is the almost the same example. Function names also don't execute. The parent's point was that if the code has been tested or was considered working, and then you noticed this in the code, you should think twice before "fixing" the behavior to match the comment or function name.
- choward 10y agoThen why even name anything? Are you saying I should just name my functions and variables a, b, c, d, etc.?
- eternalban 10y agoOf course names are important to us, human programmers, but the compiler doesn't given an 'f'.
- posterboy 10y agoWe use mnemonics, because we can't remember numbers as well, but to the compiler, addresses are pretty much like names.
- eternalban 10y agoIt's a bit more than that. Function names are precisely encapsulation of the intent of the function. And unlike comments, function names are not subject to rot. Also addresses are not like names. As with names in general, a name can refer to more than one object. (Consider modules, for example.)
- computerphage 10y ago> function names are not subject to rot I don't agree with this. I think often a function will drift from its name if functionality is added to an aspect of its implementation or because of refactoring.
- ifdefdebug 10y agoWell no, I think the argument is that this kind of comment gets outdated easily, so if the program works as expected, the comment is probably outdated (new requirement, the program was changed to print every line, forgetting about the comment). If the program does not work as expected, then it's a bug and the comment is still valid. This does not happen in your function name example: if the program requirement changed to print every line, no sane programmer would change the code in this function, they'd write a new function printEveryLine() instead and use that. So you can be pretty sure this is a bug.
- dsp1234 10y agono sane programmer would If this were only true.
- alexbecker 10y ago> If the program requirement changed to print every line, no sane programmer would change the code in this function, they'd write a new function printEveryLine() instead and use that. So you can be pretty sure this is a bug. Unfortunately many programmers seem not to be sane.
- cmontella 10y ago> if the program requirement changed to print every line, no sane programmer would change the code in this function they'd write a new function printEveryLine() instead and use that. I'm not sure I understand the distinction you are making here, so I'd like to try and understand. From my perspective, function names are just another form of comment. After all, in many languages, as soon as you press "compile", your function names are mangled into something a machine can understand. So you feel that programmers are more inclined to treat the function name as an authority, as opposed to a comment. Is that an accurate? I'm curious what lead you to this conclusion.
- ifdefdebug 10y agoA function can be called from different places, maybe it will be used in code not yet written. So a programmer has a need to print every line. The code to be changed calls printEveryOtherLine. They won't change that function to print every line, because they know that would break things elsewhere.
- lnanek2 10y agoIt is possible to make the text a test spec that is then verified. See: http://jenisys.github.io/behave.example/tutorials/tutorial01.html http://jenisys.github.io/behave.example/tutorials/tutorial01... His complaint is that it isn't being done here, so all the prose is jut going to get out of date and incorrect, and meanwhile you have to write everything twice for no benefit.
- the_af 10y agoThe problem I see with verifying comments in English (that is, using English as a specification language) is that it's impossible in the general case. So you must, in practice, use a subset of English grammar/nouns which turns into a formal specification language. In turn, this becomes a programming language of sorts, and then we stray away from the goal of "programming languages for humans". I'd love to be proven wrong, but I think the problem is that this goal itself is mistaken. If we can formally specify something using a language X, this necessarily becomes a language not "for humans" -- i.e. a formal language that doesn't follow the rules of natural language and that we must be trained in. Natural language is notoriously bad at unambiguous specification.
- posterboy 10y agoAnd then you'd need to describe the specification language and how would that be verified? I suppose that English is imperfect and could use improvements. Ideally those two would converge. That would solve problems about the interpretation of laws, as well. How would that convergence work? To answer that you'd have to know how language is acquired in the first place. I suppose some form of self-reference in the language that mirrors some of Chomskie's stipulated universal grammar, if it exists.
- derefr 10y agoI think there's one kind of "specification language" that works completely unlike programming itself—and that's the interactive form of specification known as requirements-gathering that occurs in the conversation between a contract programmer and their client. I could see potential in a function-level spec in the form of an append-only transcript, where only one line can be added at a time. So you (with your requirements-specifier hat on) write a line of spec; and then you (as the programmer) write a function that only does what the spec says, in the stupidest way possible; and then you put on the other hat and add another line to the spec to constrain yourself from doing things so stupidly; and on and on. The same sort of granularity as happens when doing TDD by creating unit tests that fail; but these "tests" don't need to execute, human eyes just need to check the function against them. --- On another tangent: I've never seen anyone just "bite the bullet" on this, acknowledge that what they want is redundant effort, and explicitly design a programming language that forces you to program everything twice in two separate ways. It seems to me that it'd actually be a useful thing to have around, especially if it enforced two very different programming paradigms for the two formalisms—one functional and one procedural, say; or one dataflow-oriented ala APL or J, and the other actor-modelled ala Erlang. Seems like something NASA would want to use for high-assurance systems, come to think of it. They get part-way there by making several teams write several isolated implementations of their high-assurance code—but it will likely end up having the same flaws in the same places, given that there's nothing forcing them to use separate abstractions.
- hacker_9 10y agoI agree, if I'm writing a paragraph of english followed by a paragraph of code... what's the point? Comments at the moment are generally one liners and can quickly get outdated if not maintained.
- cmontella 10y agoRight, this is exactly the argument we are making. Given just the block of code above, we don't know enough to make the determination. Who is right? We can't possibly no without more. That's why commenting code is not enough, and that's why literate program is important. Imagine if you came across this in actual code. You might first check if the code was changed recently and by whom, and whether the comment or the code came first. But that still wouldn't tell the whole story. To get it all, you would find out who checked in the code, and what their original intent was. What we're advocating is to treat source code more like a design document. It's a collection of thousands of design decisions all informing the specification of the final product, the program. > If the idea is simply that this is extra work for the programmer to do -- that they need to describe every implementation twice, once in code and once in English Right, so the point is that prose is not redundant. As Knuth put it literate programming is "a mixture of formal and informal methods that reinforce each other." When we communicate to one another face-to-face, we use gestures, expressions, intonation, etc. to articulate an idea. On the internet, when we communicate with just text, much of my meaning is lost forever and never apparent to anyone who reads this. Programming is much the same way. The code only tells you so much about the program. Without any context, readers are often disoriented and confused by new codebases. If no one is willing to read your code, no one will ever contribute to it. GitHub and SourceForge are veritable graveyards of amazing yet abandoned projects that will never see another contribution, because their codebases are so inscrutable. I know I'm guilty of this as well; when I revisit old codebases, I hardly know even what I was thinking. Anyway, I think there's a lot to explore here. I think what you raise is an issue, and it will always be important to address, but I really believe that literate programming is important and can lead to better code. So we're going to see where we can take it with Eve, and I hope you'll give it a shot!
- 0xffff2 10y agoYou didn't address at all what forces the programmer to keep the prose and code in sync. If you still have code that's read and translated by the compiler, and prose that's ignored by the compiler completely, how have you actually changed anything?
- 10y ago
- sbuttgereit 10y agoI don't know that I really agree with this criticism. I don't think having the additional context gives you two authorities which you are helpless to reason about. The code will tell you what is happening regardless of what is intended, the comments will tell you what was intended regardless of what is happening. More often than not, having both of these pieces can tell you where inconsistencies in the larger picture have arisen and you can use your own judgement to figure out what it all means and what you might do next. Maybe I'm biased because I'm pretty proficient in the business domains I specialize in, so I can understand, conceptually, what the application is suppose to support and consider the validity of the programmer's intent as well as the code's function. But I'm not sure why it would be considered beneficial to withhold knowledge of intent in favor of purely what's happening; except maybe to junior/support staff that aren't likely to understand the motivation behind a developer's intent. Perhaps, because of the concern that code gets maintained and related commentary doesn't?
- eternalban 10y agoThe criticism is valid. I have yet to encounter a comment in production code that projects future intent for a piece of code, but having comments lag behind revised code is all too common. Comment rot is one of the motivating reasons behind 'sparse comments' school of thought.
- hacker_9 10y ago> The code will tell you what is happening regardless of what is intended, the comments will tell you what was intended regardless of what is happening. Unless you write the comment, then the code, then change the code and don't update the comment. Now if the code is wrong, both the comment and code are wrong. In current languages letting code handle the 'what', and comments handle the 'why' works well enough. Not saying it is a perfect system, but the idea of the comment being expanded to include the 'what' as well doesn't seem like progress in the right direction to me.
- sbuttgereit 10y agoI agree with you point in some cases and not others. I would characterize my position that you should comment just enough that someone other than you (or your distant, future self) and understand what the goal is; why being more important than what, what being more important than how. If you're working with a relatively simple application where the information the application deals with is conceptually simple: you're absolutely right, explaining what and then having code that has a finite set of possible intents would just be wordy. On the other hand, I gave an example of ERP system inventory costing algorithms in another answer in this general thread where the complexity is different: cost can mean different things under different circumstances and different processes. We try to generalize these algorithms into lower lever functions, but you have to understand the what to know how it's appropriate to use the function... or if it is actually achieving it's goal: it may be coded in a way to be valid in all but the use cases targeted. There simply is no one size fits all answer to how to appropriately comment code (or if to do it at all). As for bad comments and comment rot... any code, commented or not, can be written poorly or not maintained properly. Yes it's an extra moving part, and if you're not going to be as diligent about documentation as the code then, yes, often times your better without it. I think, however, it's better to force the issue. I don't think you need freestanding documents but by god if you have comments and I see code in a code review where the comments have been neglected: reject that submission.
- deleted 10y ago[deleted]
- pjc50 10y agoThis is why comments that specify what the code does are a "code smell". Comments should explain things that are not obvious from the code. Comments should be things like // Note: PCI-DSS requirements apply below // Must check status register and FIFO to determine completion due to flaky hardware // Algorithm below is modified Knuth-Morris-Pratt // This is O(scary), but seems quick enough in practice. (Now, if someone lets me put images in comments, that would be amazing. Good for state transition diagrams and random scribbles)
- e12e 10y agoA state transfer diagram would probably be more useful as a view on the code (similar to how the Smalltalk browser is a simple graphical representation/layout of code. Or indeed any IDE with advanced code folding (show me the class name and public methods only). But there's ways to mix the two: Python doctests is one. The lp approach is to "escape" the code, not the comments. I really do think some richer data structure than flat text files is needed - simple multi-/hyper-text seems like a minimum. Not only links (most ides have this: hoover to display help, click to goto definition etc). Why so few seem to successfully add vector graphics and diagrams I don't know. I guess jupyter / ipython might be a rare breath of air. But who really wants to maintain 10k locs of code and 15k locs of tests in ipython notebooks? We need something more (lively kernel might be more interesting here - webdav for persistence Web browser for run/edit/view - I'm not sure if the required power Canberra realised any simpler).
- p10_user 10y agoI personally only see the utility of the notebook as a demonstration tool of a finished product. Kinda goes to your comment on the notebooks and code maintenance. It's a good teaching or presentation tool but not (IMO) a development tool.
- e12e 10y agoThe main question is if there's any fundamental reason for why we can't have both: a rich, versioned, distributed data store for our logic and data - and a number of views that allow us to inspect and modify it. The best example I'm aware of is probably Smalltalk coupled with monticello version control and a solid object database like gemstone/s (I'm not aware of a real open/free workalike for the last part). That's not not say relational or logic databases aren't useful - but it's more difficult to manage the data, query code and program code in one integrated system if the database takes the form of an external server. That said, Ms visual studio and the SQL db gui does a pretty good job of presenting a somewhat coherent environment. I used to be strongly in the Linux/Unix camp - thinking that the datastore we call the filsystem is a good abstraction. But I've come to believe that even the strong legacy of user familiarity isn't a good enough reason to stick with it. Even if we were a little bit more serious and at least went all plan9 - rather than the half-hearted state of Linux/Unix (everything is a file, or a database file, or a binary file or an archive of a filsystem or...). That said a "filsystem" might very well still be a decent building block for a higher level system (with decent search, for example). But yeah, I don't think jupyter is the be all, end all of development. But it is an interesting way to move legacy programming environments forward in a low friction manner.
- qznc 10y agoRule of thumb: If comment and code disagree, usually both are wrong.
- WalterBright 10y ago> Print every other line of the array to the console The odd or even lines? I don't think English is going to replace programming languages anytime soon.
- mshenfield 10y agoEve places the source of truth clearly in the document surrounding the code. The code disagrees with the description, the code should be changed unless there is some evidence in git that the code functions as intended.