Slashdot Mirror


Donald Knuth Rips On Unit Tests and More

eldavojohn writes "You may be familiar with Donald Knuth from his famous Art of Computer Programming books but he's also the father of TeX and, arguably, one of the founders of open source. There's an interesting interview where he says a lot of stuff I wouldn't have predicted. One of the first surprises to me was that he didn't seem to be a huge proponent of unit tests. I use JUnit to test parts of my projects maybe 200 times a day but Knuth calls that kind of practice a 'waste of time' and claims 'nothing needs to be "mocked up."' He also states that methods to write software to take advantage of parallel programming hardware (like multi-core systems that we've discussed) are too difficult for him to tackle due to ever-changing hardware. He even goes so far as to vent about his unhappiness toward chipmakers for forcing us into the multicore realm. He pitches his idea of 'literate programming' which I must admit I've never heard of but find it intriguing. At the end, he even remarks on his adage that young people shouldn't do things just because they're trendy. Whether you love him or hate him, he sure has some interesting/flame-bait things to say."

99 of 567 comments (clear)

  1. Literate programming... by Gordonjcp · · Score: 3, Insightful

    ... looks like it falls into the same trap as COBOL. The idea that by making programming languages incredibly verbose, they will somehow become easier to use is a fallacy.

    Using "MULTIPLYBY" instead of "*" isn't going to make your code easier to read.

    1. Re:Literate programming... by CastrTroy · · Score: 3, Insightful

      I'm not sure if MultiplyBy is any better. It takes longer to type, and most people have understood that * (or X) meant multiply by since second grade. The thing I like about more verbose languages like VB.Net are that they force you to write out things that most good programmers would write out anyway as comments. At the end of a while loop, you write "End While". Most people using C++/Java/C# end up writing "} //end while" anyway, especially if the loop goes over 6 or 7 lines, and even more likely if there's a nesting construct like an if statement in there anyway. Seeing the "End While" let's you know what you are finishing off, without scrolling higher and trying to line up and see which bracket matches. Which even with visual brace matching, can sometimes be difficult.

      --

      Anthropic principle: We see the universe the way it is because if it were different we would not be here to see it.
    2. Re:Literate programming... by 1729 · · Score: 4, Interesting

      ... looks like it falls into the same trap as COBOL. The idea that by making programming languages incredibly verbose, they will somehow become easier to use is a fallacy.

      Using "MULTIPLYBY" instead of "*" isn't going to make your code easier to read. From what I've seen (particularly of CWEB), literate programming doesn't change the programming language itself, it just adds a TeX style markup to the comments so that detailed (and nicely typeset) documentation can be generated from the source code. Take a look at some of Knuth's CWEB code, such as his implementation of Adventure:

      http://sunburn.stanford.edu/~knuth/programs/advent.w.gz

      It appears to be ordinary C once the CWEB documentation is stripped out.
    3. Re:Literate programming... by Basilius · · Score: 5, Informative

      That's not literate programming at all. A tad more research on your part is required. I actually remember when "web" in a computing context a literate programming tool rather than that thing you're surfing right now.

      Literate Programming interleaves the documentation (written in TeX, naturally) and code into a single document. You then run that (Web) document through one of two processors (Tangle or Weave) to produce code or documentation respectively. The code is then compiled, and the documentation built with your TeX distribution. The documentation includes the nicely formatted source code within.

      You can use literate programming in any language you want. I even wrote rules for Microsoft C 7.0's Programmer's Workbench to use it within the MSC environment.

      I've frequently thought about going back. Javadoc and/or Sandcastle are poor alternatives.

    4. Re:Literate programming... by Eunuchswear · · Score: 4, Insightful

      Most people using C++/Java/C# end up writing "} //end while" anyway,
      Pray god I never have to work on code written by these fictitious "most people".

      I'd kill any colleague of mine who wrote such a vacuous comment. With a golf club, in front of its cow-orkers to drive the lesson home,
      --
      Watch this Heartland Institute video
    5. Re:Literate programming... by davolfman · · Score: 2, Insightful

      I don't. It's pointless if you format your code decently. The bracket and the knockdown in tabbing should be enough. The only place I can see it being useful is when you have a truckload of nested brackets and even then you want something a lot more useful than "end while" it should at least name the stinking loop.

    6. Re:Literate programming... by 1729 · · Score: 4, Insightful

      Most people using C++/Java/C# end up writing "} //end while" anyway,
      Pray god I never have to work on code written by these fictitious "most people".

      I'd kill any colleague of mine who wrote such a vacuous comment. With a golf club, in front of its cow-orkers to drive the lesson home, I sometimes add comments like that if the brace is closing a deeply nested block, but then the comment indicates which particular loop or block is ending.
    7. Re:Literate programming... by Swizec · · Score: 5, Insightful

      I concur. Comments should tell WHY the while block is there and what it DOES. Not where it starts and where it ends, the code tells us that descriptively enough.

      I've met code blocks several hundred lines long and it was never ambigious where they started and ended.

    8. Re:Literate programming... by iMacGuy · · Score: 2, Informative

      In literate programming, the documentation is the default state and you have to escape it to write code. It's an important difference if you're going to write a lot of it.

      --
      Why won't slashdot let me change my terrible username :(
    9. Re:Literate programming... by numbsafari · · Score: 3, Interesting

      A better way to handle that is to turn the loop body into a function or group of functions. makes the code easier to read and a good compiler will inline the function so their's no performance loss.

    10. Re:Literate programming... by Sancho · · Score: 2, Informative

      From my brief look at doxygen, it looks like the biggest difference is semantic. Literate Programming with web is effectively documentation with code bits and metacode to indicate where the code bits should go. This means that the code bits can be (and should be) in the order that makes the most sense for the documentation. This is not necessarily the order that makes the most sense for the code.

      Doxygen looks like it just extracts properly formatted comments in code in order to generate documentation. Web extracts properly formatted bits of code in order to generate a semantically correct C file.

    11. Re:Literate programming... by Coryoth · · Score: 2, Informative

      Excuse my ignorance, but please explain how this this different (or superior) to doxygen or any of the many systems that do just this. I'm not meaning to be rude, I'm just asking. I think the prime difference is that literate programming allows you to re-order the code; that is, you include snippet of code within the documentation, and attach tage to the snippets that allow them to be reassembled in a different order. That doesn't sound like much, but it means that you can just write the documentation have code appear as i is relevenat to the documentation rather than having the program structure dictate things. Take a look at some examples (in various languages) to see what I mean. The key here is that documentation is (or should be) first and foremost in the writers mind, and it is the documentation that dictates presentation structure. This means that you are concentrating on writing the documentation, and will thus write it well, as opposed to concentrating on code, and adding documentation as an afterthought if you get around to it. Well, that's the principle at least.
    12. Re:Literate programming... by sholden · · Score: 2, Informative

      It predates it.

      And the philosophy is different, literate program is essentially embedding the code in the documentation. Doxygen is more about embedding documentation in the code.

      So doxygen gives you fancy comments and a way of generating documentation from them and from the code structure itself. CWEB lets you write the documentation and put the code in it deriving the code structure from the documentation, sample cweb program: http://www-cs-faculty.stanford.edu/~knuth/programs/prime-sieve.w

      Literate programming is more suited for "dense" programs, which surprise, surprise is the type of stuff Knuth does.

    13. Re:Literate programming... by rascher · · Score: 5, Funny

      I myself solve the problem using this construct:

      #define BeginWhile {
      #define EndWhile }

      #define BeginFor {
      #define EndFor } ...

    14. Re:Literate programming... by Nicolas+Roard · · Score: 4, Informative

      Literate Programming is not about making programming languages incredibly verbose; it's about *describing* your program in a normal, human way, by explaining it step by step and quoting bits and pieces of the program. Sounds ideal from a documentation point of view, right ? only that if that was all there was with Literate Programming, it would be a stupid idea, as documentation has a nasty habit to not follow up with code modification.

      The really cool idea with LP is that the code snippets you use in the documentation are then weaved together to generate the "real" code of your program. So a LP document is BOTH the documentation and the code. A code snippet can contains references ("include") to other code snippets, and you can adds stuff to an existing code snippet.

      Let me show you an example in simple (invented) syntax:

      {my program}

      {title}My super program{/title}

      Blablabla we'd need to have the code organized in the following loop:

      {main}:
          {for all inputs}:
              {filter inputs}
              {apply processing on the filtered inputs}
          {/}
      {/}

      The {for all inputs} consist in the following actions:

      {for all inputs}:
          some code
      {/}

      The filtering first remove all blue inputs:

      {filter inputs}:
        remove all blue inputs
      {/} ... and then remove all the green inputs:

      {filter inputs}+:
        remove all green inputs
      {/}

      etc.

      {/}

      The above is purely to illustrate the idea, the actual CWEB syntax is a bit different. But you can see how, starting with a single source document, you could generate both the code and the documentation of the code, and how you can introduce and explain your code gradually, explaining things in whichever way that makes the most sense (bottom-up, top-down, a mix of those..).

      In a way, Doxygen or JavaDoc have similar goals: put documentation and code together and generate documentation. But they take the problem in reverse from what literate programming propose; with Doxygen/JavaDoc, you create your program, put some little snippets of documentation, and you automatically generate a documentation of your code. With LP, you write your documentation describing your program and you generate the program.

      Those two approaches produce radically different results -- the "documentation" created by Doxygen/JavaDoc is more a "reference" kind of documentation, and does little to explain the reason of the program, the choice leading to the different functions or classes, or even something as important as explaining the relationships between classes. With some effort it's possible to have such doc system be the basis of nice documentation (Apple Cocoa documentation is great in that aspect for example), but 1/ this requires more work (Cocoa has descriptive documents in addition to the javadoc-like reference) 2/ it really only works well for stuff like libraries and frameworks.

      LP is great because the documentation is really meant for humans, not for computers. It's also great because by nature it will produces better documentation and better code. It's not so great as it poorly integrates with the way we do code nowadays, and it poorly integrates with OOP.

      But somehow I've always been thinking that there is a fundamentally good idea to explore there, just waiting for better tools/ide to exploit it :-P

      (also, the eponymous book from Knuth is a great read)

    15. Re:Literate programming... by MrSteveSD · · Score: 4, Insightful

      Not all programmers are uber-elite, and many are only slightly better than not being there at all.

      I don't think there's anything elite about writing short concise functions and breaking things up. The problem is when people first go into programming, they make these kinds of mistakes unless there are proper code reviews/training (things which often don't happen). When you are at university, the programs you write tend to be quite short and because of that, you don't realise how bad a programmer you actually are at that stage. It's only when you leap into the workplace and start writing a lot that your inadequacies become evident.

      To me, programming is a discipline requiring a fair bit of intelligence, but all to often companies hire programmers like they are just hiring shelf-stackers or something. I think there is a lot more professionalism in Open Source projects than in many software houses.
    16. Re:Literate programming... by arivanov · · Score: 2, Funny

      No, it is a person who says moooooo when you ask him about trivial things like O(X) is his algorithm or what is the finite state machine he used to implement a protocol. Using a mutex-locked delete+insert instead of atomic replace in SQL is another popular mooooooo. It is usually done because the cretin cannot fatom the idea that a database op done correctly is atomic anyway so it needs no mutex and the database will NOT DEADLOCK the way an incompetently done mutex can.

      An so on...

      Very common species... The COW-WORKER...

      --
      Baker's Law: Misery no longer loves company. Nowadays it insists on it
      http://www.sigsegv.cx/
    17. Re:Literate programming... by Anonymuous+Coward · · Score: 5, Funny
      why, have you ever read the source to the original, one-true unix bourne shell ?

      http://unix-archive.kalwun.de/PDP-11/Trees/V7/usr/src/cmd/sh/mac.h

    18. Re:Literate programming... by Anomolous+Cowturd · · Score: 2, Informative

      Something like this might help: folding in vim. Emacs probably already has an 11-note chord that does this.

      --
      Software patents delenda est.
    19. Re:Literate programming... by Temporal · · Score: 2, Funny

      What's a cow-orker? A misspelled description of somebody who irritates cows?
      Scott Adams once observed that a person you work with is technically called a "co-worker". The common misspelling "coworker" is actually a contraction of "cow orker", "ork" being an old Scottish slang term the meaning of which is not hard to guess.
    20. Re:Literate programming... by johannesg · · Score: 2, Insightful

      I worked with Captain Endif for a while. It gets very, very, VERY tiring at some point. Especially in cases like this:

      #define TRUE_VAL true
      #define FALSE_VAL false // if theVar is true

      if (theVar == TRUE_VAL) { // set theVar to false
          theVar = FALSE_VAL;
      } // end if

      (I made this up, but sadly it is not that far removed from actual examples...)

      I also worked with a guy (another one) who left a blank line between every two lines of code. ALWAYS.

      Anyway, if you are in the neighbourhood, feel free to come over to our office. If you forgot your golf club I'm sure we can rig something using parts from the paper cutter or something...

    21. Re:Literate programming... by mkcmkc · · Score: 4, Interesting

      Most people using C++/Java/C# end up writing "} //end while" anyway,
      Pray god I never have to work on code written by these fictitious "most people". Well, actually, once you've programmed in Python for a while, all of those spurious '}'s to close blocks really start to look as annoying and useless as "} //end while".
      --
      "Not an actor, but he plays one on TV."
    22. Re:Literate programming... by jacquesm · · Score: 2, Interesting

      if you feel like experimenting with literate programming try finding the 'leo' editor (written in python)

    23. Re:Literate programming... by 1729 · · Score: 2, Insightful

      I sometimes add comments like that if the brace is closing a deeply nested block Deeply nested blocks is a sure sign of crap code. Don't document crap code, rewrite it. A sure sign? Some code is necessarily complex. Conditional blocks inside nested loops are sometimes necessary for a logical, efficient, and human-readable implementation of an algorithm.

      Furthermore, I don't have the luxury of rewriting millions of lines of existing code. I document the parts I touch and I try not to make anything worse, but rewriting "crap code" is not always an option.
    24. Re:Literate programming... by SanityInAnarchy · · Score: 2, Insightful
      Yeah, that's the one thing I hate about Ruby now -- seeing the end of a file that looks like this:

      # for some reason, Slashdot won't indent the first line...
                end
              end
            end
          end
        end
      end
      Especially when the whole culture around things like Ruby on Rails is "Convention over Configuration" (thus, your code should always be indented properly anyway) and "Don't Repeat Yourself" (tons of 'end' statements isn't particularly DRY).

      I will say one thing, though: After haml, I never want to write any raw HTML, or any XML, by hand again. Ever.
      --
      Don't thank God, thank a doctor!
    25. Re:Literate programming... by nuzak · · Score: 4, Funny

      I have actually seen code like this:


              } // end while-loop
      } // end if-loop


      You read that right. if-loop.

      --
      Done with slashdot, done with nerds, getting a life.
    26. Re:Literate programming... by Charbox · · Score: 2, Funny

      Nobody who modded this funny ever worked with a foreign language programming team.

  2. Shocked by gowen · · Score: 5, Interesting

    He pitches his idea of "literate programming" which I must admit I've never heard of
    I'm shocked to discover that Knuth is taking an opportunity to push literate programming, given that he's been pushing literate programming at every opportunity for at least 25 years.

    Now, I've no problem with literate programming, but given that even semi-literate practices like "write good comments" hasn't caught on in many places, I think Don is flogging a dead horse by suggesting that code should be entirely documentation driven.
    --
    Athletic Scholarships to universities make as much sense as academic scholarships to sports teams.
    1. Re:Shocked by Coryoth · · Score: 5, Insightful

      Now, I've no problem with literate programming, but given that even semi-literate practices like "write good comments" hasn't caught on in many places, I think Don is flogging a dead horse by suggesting that code should be entirely documentation driven. To be fair to Knuth, I don't think the failure to write good comments detracts from literate programming. What Knuth wants is an inversion of thr traditonal code/documentation relationship: you write the documentation and embed the code within that, as opposed to concentrating on code, and incidentally embedding documentation (as comments) within the code. Ultimately the failure of good comments and good documentation is because people are focussing on the code; as long as documentation and comments are an afterthought they will be forgotten or poorly written. If you switch things around and focus on the documentation and insert the code, comment-like, within that, then you're focussing on the documentation and it will be good.

      The reason I think literate programming doesn't catch on has mostly to do with the fact that a great many programmers don't bother to think through what they want to do before they code it: they are doing precisely what Knuth mentions he does use unit testing for -- experimental feeling out of ideas. Because they don't start with a clear idea in their heads, of course they don't want to start by writing documentation: you can't document what you haven't thought through. This is the same reason why things like design by contract don't catch on: to write contracts it helps to have a clear idea of what your functions and classes are doing (so you can write your pre-conditions, post-conditions and invariants) before you start hammering out code. The "think first" school of programming is very out of favour (probably mostly because it actually involves thinking).
    2. Re:Shocked by gowen · · Score: 2, Funny

      I'm shocked to discover that Knuth is taking an opportunity to push literate programming, given that he's been pushing literate programming at every opportunity for at least 25 years.

      You're full of shit. A proponent of semi-literate programming, I see.
      --
      Athletic Scholarships to universities make as much sense as academic scholarships to sports teams.
    3. Re:Shocked by Coryoth · · Score: 2, Informative

      Yes! I like writing code to see how things pan out, it's one of my ways of thinking about what the problems and goals are. But I don't intend that to be the final code - make a cheap throwaway prototype, then make the final product, possibly salvaging bits of the prototype. Don't get me wrong, and not arguing against that. Neither is Knuth. He mentions such scenarios as one of the cases when he does find a use for unit testing. That's part of the "thinking" stage. From what I gather from the interview Knuth tends to do that with pencil and paper, but you can do it just as well by mucking out some example code and test cases. The point, as you note, is that it isn't your final code: it is that "final code" step (once you've figured out what you want to do) that literate programming really comes in (and in this sense is orthogonal to TDD and similar approaches).
  3. What? by TheRaven64 · · Score: 5, Interesting
    You've heard of TeX, written in Web, the language designed for Literate Programming, but you've not heard of Literate Programming?

    I have a lot of respect for Knuth as an algorithms guy, but anything he says about programming needs to be taken with a grain of salt. When he created the TeX language, he lost all credibility - designing a language in 1978 which makes structured programming almost impossible is just insane. TeX gets a lot of praise as being 'bug free,' but that's really only half true. The core of TeX is a virtual machine and a set of typesetting algorithms, both of which are very simple pieces of code (they'd have to be to run on a PDP-10). Most of the bits people actually use are then metaprogrammed on top of the virtual machine, and frequently contain bugs which are a colossal pain to track down because of the inherent flaws in the language (no scoping, for example).

    If you want to learn about algorithms, listen to Donald Knuth and you will learn a great deal. If you want to learn about programming, listen to Edsger Dijkstra or Alan Kay.

    --
    I am TheRaven on Soylent News
    1. Re:What? by gowen · · Score: 5, Insightful

      Amen about TeX (and even LaTeX). I consider myself pretty knowledgeable about many computing languages, but every time I've hit a non-trivial problem with making TeX do what I want, I've had to consult with a TeXpert (i.e. the utterly invaluable comp.text.tex). And, sadly, in almost every case the solution has been either insanely baroque, or there's been no real solution at all. LaTeX makes brilliant looking documents, but Jesus wept, it's hard to make your documents look like YOU want, as opposed to how it thinks they should look.

      --
      Athletic Scholarships to universities make as much sense as academic scholarships to sports teams.
    2. Re:What? by cbart387 · · Score: 5, Interesting

      If you want to learn about algorithms, listen to Donald Knuth and you will learn a great deal. If you want to learn about programming, listen to Edsger Dijkstra or Alan Kay. For those that didn't read the article, Knuth expressed criticism on several of the questions asked, but he didn't want to just duck the question. For instance, the 'trendy question' he said this.

      With the caveat that thereâ(TM)s no reason anybody should care about the opinions of a computer scientist/mathematician like me regarding software development
      --
      Lack of planning on your part does not constitute an emergency on mine.
    3. Re:What? by sc00p18 · · Score: 2, Interesting

      Fortune cookie at the bottom of the page for me:

      They are relatively good but absolutely terrible. -- Alan Kay, commenting on Apollos

    4. Re:What? by jeremyp · · Score: 2, Funny

      I fon't know. I've found that Dijkstra hasn't said anything new or profound in more than five years.

      --
      All I want is a secure system where it's easy to do anything I want. Is that too much to ask ~~ Randall Munroe
  4. Programming for the human VM by TuringTest · · Score: 4, Insightful

    Literate programming is an old friend for developers of functional programming languages. I see it like "code for the human mind": it provides a source code that is well adjusted to the needs of the developer, not just the machine.

    It interleaves code and documentation in the same files, and provides a specialized compilator to tell the two kinds of codes apart. Just like Doxygen and Javadoc can extract the comments from a source code project, the "tangle" process can extract all the code from a Literate program and pass it to a clasic compiler.

    Now that C and C++ seem to have a declining popularity, maybe we can look for better ways of getting away from the bare metal (which, don't forget it, is why those languages become popular at the beginning). Don't get me wrong, they served us well for 36 years, but I think it's time again to begin caring more for the developers' requirements and less for the hardware requirements.

    --
    Singularity: a belief in the "God" idea with the "demiurge" relation inverted.
  5. Re:Did anyone claim the bug prize on TeX? by paulbd · · Score: 4, Informative

    the prize was not US$1000. it started out very small. Knuth did indeed pay out, and indeed doubled it, several times. From wikipedia: "The award per bug started at $2.56 (one "hexadecimal dollar"[24]) and doubled every year until it was frozen at its current value of $327.68. This has not made Knuth poor, however, as there have been very few bugs claimed. In addition, people have been known to frame a check proving they found a bug in TeX instead of cashing it."

  6. You misunderstand by Rix · · Score: 4, Interesting

    Using "MULTIPLYBY" instead of "*" is asinine, because both are equally descriptive. Putting a comment above the line telling people why you're doing it isn't.

    1. Re:You misunderstand by Anonymous Coward · · Score: 5, Informative

      The GP must have been confused by the example on Wikipedia, which a) wasn't literate programming and b) used a shitty made-up language where "multiplyby" was one of the operators. Literate programming is programming (in your favourite language) with a code-in-documentation approach instead of the usual documentation-in-code approach. So, for example, the flow of your literate program is defined by how best to explain what's happening to a human reader, rather than being constrained by the order the compiler requires. You run your literate program through a tool and it spits out compilable code or pretty documentation.

    2. Re:You misunderstand by jwiegley · · Score: 3, Informative

      It is also the use of accurate and descriptive symbol names.

      Database database("data.txt");
      if (database.empty())

      is a lot more readable (i.e. literate) than

      DB d("data.txt");
      if (d.e())

      --
      I will never live for sake of another man, nor ask another man to live for mine.
    3. Re:You misunderstand by ruben.gutierrez · · Score: 2, Funny

      I like the idea of using "ZEROORMOREOFTHEPRECEDINGCHARACTER" rather than "*", myself.

    4. Re:You misunderstand by PingPongBoy · · Score: 3, Funny

      Putting a comment above the line telling people why you're doing it isn't.

      I don't have to tell people why I do it. I do it for money. Well, sometimes for love and world peace, but that's rare.

      --
      Know your pads. One time pad: good for cryptography. Two timing pad: where to take your mistress.
  7. Re:Did anyone claim the bug prize on TeX? by nuzak · · Score: 2, Interesting

    > But the story during my grad school days was that, Knuth offered 1000$ prize to anyone fining a bug TeX and he doubled it a couple of times.

    The $1000 bounty was from Dan Bernstein with respect to qmail. He's always found a reason to weasel out of ever paying.

    Knuth started the bounty at $2.56 (one "hexidollar") and doubled it every year til it reached $327.68. Several people have claimed it, most people never cashed the checks. One of the first bug finders had his check framed.

    --
    Done with slashdot, done with nerds, getting a life.
  8. Re:Did anyone claim the bug prize on TeX? by TheRaven64 · · Score: 3, Interesting

    The original prize was $2.56 (i.e. 2^8Â), and he doubled it every time someone found a bug until it reached $327.68. Over 400 bugs have been fixed in TeX, and that's just counting the core VM and typesetting algorithms - all of the rest is in metaprogrammed packages, many of which contain numerous bugs. I'm fairly sure that most programmers could write bug-free code if the only place where bugs counted was in a simple VM with a few dozen instructions that interpreted all of the rest of the code...

    --
    I am TheRaven on Soylent News
  9. Unit Tests are not wasteful by LargeWu · · Score: 5, Insightful

    The reason for his dismissive attitude of unit tests - that he knows exactly how all of his code works, and what impact a change will have - is exactly the reason you need them. In the real world, most programmers do in fact have to share their code with others. You're not always going to know the ramifications of refactoring a particular block of code, even if you wrote it yourself. And if you can keep all of that in your head at once, either your program is trivial, or you are some sort of supergenius. Now while I think the TDD guys are a little bit overzealous sometimes with their "100% coverage or die" attitude, unit testing is still a good habit to get into, regardless of what Knuth thinks.

    1. Re:Unit Tests are not wasteful by CodeBuster · · Score: 4, Insightful

      Unit tests, especially if written and organized in an intelligent fashion, can be of tremendous value in eliminating small coding errors that were not inteded but are bound to creep in if the project is large enough. If you are clever about your tests then you can usually inherit the same test multiple times and get multiple uses out a test or part of a test. If unit tests are not used then it is more likely that several small errors in seemingly unrelated classes or methods can combine in an unforseen way to produce nasty and unexpected emergent behavior that is difficult to debug when the whole system is put together. Unit tests will not make up for crappy design, but they will help detect minor flaws in a good design that might otherwise have gone undected until final system integration where they could be much more difficult to debug.

      I actually have a great deal of respect for Knuth, but I think that he is wrong about unit tests. Perhaps it is the difference between the academic computer scientist and the career programmer who admires the ivory tower, but is willing to make concessions in the name of expedience and getting work done on time.

    2. Re:Unit Tests are not wasteful by ivan256 · · Score: 3, Insightful

      I think that the arguments about unit tests often go too far in one direction or the other. People either treat unit tests as a religion, or they disavow them entirely.

      People in the first group end up with a project full of tests where many are valid, many end up testing basic language functions, and many end up not helping due to oversimplication of behavior in the mocked interfaces.

      People in the second group end up missing simple problems that could have been caught had they exercised their code.

      Both groups waste a lot of time.

      Perhaps this is what you were trying to say when you said "TDD guys are overzealous". I think there are other problems with TDD. Namely that you can only use it when you don't need to learn how to solve a problem as you go... Most interesting programs fall into that category.

      Really, people need to use good testing judgement.

    3. Re:Unit Tests are not wasteful by seaturnip · · Score: 5, Interesting

      It actually doesn't sound to me like Knuth has heard of the term 'unit test' before this interview at all. It sounds like he thinks it means prototyping a function before writing the real version. Given that he likes to push his model of documentation-driven programming, I think he might be more sympathetic to unit tests if he understood that they can serve as a kind of formalized documentation.

  10. Re:Did anyone claim the bug prize on TeX? by 1729 · · Score: 4, Interesting

    It is probably folklore. But the story during my grad school days was that, Knuth offered 1000$ prize to anyone fining a bug TeX and he doubled it a couple of times. And it was never claimed. If that was true, it is very unlikely he was just flame baiting. He offers rewards for reporting errors is his books and for finding bugs in his code:

    http://en.wikipedia.org/wiki/Knuth_reward_check

    Many people save these (usually small) checks as souvenirs. My father -- a frugal mathematician -- received a few $2.56 checks from Knuth, and he promptly cashed each one.
  11. and, arguably, one of the founders of open source? by xx_chris · · Score: 2, Informative

    No, that isn't arguable.

    Tex got started in 1977 after Unix (1974), well after SPICE (1973), and about even with BSD.

  12. His comment on unit tests by free+space · · Score: 2, Interesting

    ...the idea of immediate compilation and "unit tests" appeals to me only rarely, when Iâ(TM)m feeling my way in a totally unknown environment and need feedback about what works and what doesnâ(TM)t. Otherwise, lots of time is wasted on activities that I simply never need to perform or even think about. Nothing needs to be "mocked up."


    I'm not sure, but I think he's talking personally about his own work on his code. Remember that he comes from an era where people had the goal of mathematically proving that the code is indeed correct. He isn't necessarily doing this now but my persaonal guess is that he prefers statically checking the code to checking a running program. In certain kinds of mathematic/scientific applications this could make sense.
    1. Re:His comment on unit tests by a66at · · Score: 2, Interesting
      No, he prefers debugging (which is dynamic checking) over systematic unit-testing. See:

      That simulator includes debugging features like the ones I found so useful in Ed Satterthwaiteâ(TM)s system for ALGOL W, mentioned earlier. I always feel quite confident after checking a program with those tools.
  13. Documentation is the source by CustomDesigned · · Score: 5, Informative

    So basically it's the same as the XML comments you can put in your .Net or Java code to create JavaDocs, or whatever they are called in .Net, based on the comments in the code? Not quite. In Javadoc (or the C/C++ equivalent) the C/Java code is the source, and documentation is generated from that. In literate programming, the documentation is the source, and it has code snippets, like you would see in a Knuth textbook.


    The snippets have markup to indicate when some snippet needs to come textually before another to keep a compiler happy, but mostly this is figured out automatically. But in general, the resulting C code is in a different order than it appears in the source documentation. For instance, the core algorithm might come first, with all the declarations and other housekeeping at the end. (With documentation about why you're using this supporting library and not that, of course.)

  14. He's right by Brandybuck · · Score: 4, Insightful

    He's right about unit tests... sort of. Just as most coders shouldn't be designing interfaces, most coders don't know how to test. It can often be more work writing the unit tests than writing the code.

    If you have a function that multiplies two integers, most coders will write a test that multiplies two numbers. That's not good enough. You need to consider boundary conditions. For example, can you multiply MAX_INT by MAX_INT? MAX_INT by -MAX_INT? Etc. With real world functions you are going to have boundaries up the whazoo. In addition, if you have a function that takes data coming from the user, check for invalid cases even if another function is validating. Check for null or indeterminate values. Write tests that you expect to fail.

    --
    Don't blame me, I didn't vote for either of them!
    1. Re:He's right by Brandybuck · · Score: 3, Insightful

      Conclusion: Knuth is somewhat right, in that most unit tests written by coders are useless. But unit tests themselves are not.

      --
      Don't blame me, I didn't vote for either of them!
    2. Re:He's right by clap_hands · · Score: 4, Interesting

      The thing about unit testing is that it's subject to the law of diminishing returns. A simple test of the basic functionality gets you a lot for minimal effort. Writing dozens of carefully chosen tests to examine boundary conditions etc. gives you a little bit more, but for a great deal more effort. Whether or not it's worth it depends very much on the situation and the nature of the code you're writing.

    3. Re:He's right by tknd · · Score: 2, Interesting

      If the coder is already aware of the possible failures, then he should be fixing the code instead of writing a test.

      The purpose of a unit test testing for failure cases is not to detect places where the code has issues, but to ensure that the code performs as expected given the initial requirements/specifications. When people talk about "failure cases" they mean that they expect the code to return some sort of exception, not that they expect the code to fail in how it operates.

      For example consider that a block of code is required to perform a "division" operation. A unit test case to test for a failure case would be one that provides a denominator of zero. In this case we can expect that the code will throw a divide-by-zero exception or return a special error code rather than halt the entire program.

      And after a "unit" of code is written correctly, it shouldn't be changed a lot. Any big changes means a change in semantics, which means the original unit tests are useless anyway.

      Not necessarily. An easy example is a developer writes division function and test cases are written to ensure it operates as expected. A month later we determine that we need to improve performance of the software that utilizes the division function, and the current division function performs poorly. So given the unit test cases, we can re-implement an optimized version of the function, and testing for accuracy of the function is almost free.

      Another example is a developer starts working on a big software project. 6 months later he conveniently leaves the company without notice and his portion of the project is only 50% complete. Would you rather have 50% of code that you are not sure works or 25% of code that you are not sure works, but 100% of the unit test cases required for the existing code to tell you whether or not it works?

      An even more useful example is dealing with bugs. You receive a bug report on some software that performs some function. You eventually find the cause of the bug in a particular function, but realize that it requires a specific state of the system. You fix the bug in the software but it results in "ugly code" that at first glance is unexplainable. How should you ensure that this code is not modified accidentally? A unit test case of course! This is a good example for very special bugs that are the result of hardware issues or other software systems that are out of your control.

      There are valid argument against unit test cases (and automated testing in general). One argument is that in order to do automated testing, you are required to write more code for the test cases. This is a problem because now you have new code that does not have test cases for itself and can have bugs. So if the test case is written incorrectly, then it may point out that the original code is working incorrectly when in fact the test case is the culprit.

      Another argument (which is what I think you were trying to say) is that when the specifications for the code change, so must the test cases. This can potentially double the maintenance work required when updating the software.

      So I don't think that every piece of code needs a unit test case. But for code that will be reused considerably and is closer to the foundation of your project, you probably should make unit test cases.

    4. Re:He's right by cgranade · · Score: 2, Insightful

      Unit testing is often about detecting regressions, and so writing a unit test to catch some failure that you found and fixed can often be very helpful. To borrow the MAX_INT * MAX_INT example above, if after getting that case to work right and writing a unit test to confirm it, you decide to improve the performance of your integer multiplication routines (silly, I know... imagine a better example if you have to, like that they're matricies and you're implementing Strassen's Algorithm), then the unit test can tell you if you introduced bugs back into your code.

      --

      #define DRM chmod 000

    5. Re:He's right by rawler · · Score: 2, Interesting

      Testing is not a waste of time. Writing unit-tests, is. A better use of that time could be learning about http://en.wikipedia.org/wiki/Design_by_contract, and possibly a language that implements it. (Dare I suggest http://en.wikipedia.org/wiki/D_(programming_language) ?)

      The problems with unit test as someone already pointed out, is that writing small tests helps you verify the really simple things is relatively quick and easy but, those mistakes are easy to detect and find anyways, even a decent compiler/lint-tool will find many of them for you.

      Most of the really tricky problems comes in the interfacing between units and no unit tests will help you here.

      Design-by-contract, on the other hand, can.

      First of all it requires you to give really clear formal declaration on each component and how it may be used. (A contract) This contract can be used to automate testing of all the exotic, but allowed, corner-cases your implementation may have missed.

      The contract implemented by classes and function will furthermore function as a REALLY clear documentation, spelling out exactly what the allowed input and expected output is.

      Finally, in a design-by-contract-enabled language, you can choose to turn on debugging at run-time, and enable all kinds of tests, including input/output validation, class invariants and other really handy tests that allows you to test AND debug your entire system at once, but still at a highly granular level.

      Design-by-contract will in no way prevent you, or discourage you, from writing test-code (in fact, it encourages it), but it can help you spend your time writing those tests more sensibly, and drive your code in much more life-like scenarios.

      All in much less time spent, and much more return than the traditional ways of unit-testing.

    6. Re:He's right by shutdown+-p+now · · Score: 2, Informative

      It's integrated into my IDE (VS2008 Team Edition), so I have no excuse not to - it's just a couple of clicks.

  15. On multicore by cryptoluddite · · Score: 2, Insightful

    Making a program parallel will always be too hard for most programmers. But that's exactly why you don't have normal programmers do it... have the libraries do it automatically. Functions like qsort(2) are already black boxes, so they can be made to always run in parallel when the input is large enough. Other functions like say Ruby's .collect can run in parallel. For things like .each there can be a parallel and a sequential version that the programmer can pick which is appropriate.

    But to do this we need operating systems that can efficiently and reliably schedule code across cores. Add an ability to 'bind' threads together, so that they schedule always at the same time but on separate real processors. This gives the program the ability know when running an operation split between these threads will always complete faster than sequentially, without vagaries of scheduling possibly starving one thread and making it run much slower.

    Once you have this then you can automatically get some speedups from multiple cores on programs that are designed to only run sequentially, and more speedup on programs with just minor tweaks. You aren't going to get perfect scaling this way, but you will get substantial improvements at virtually no cost to the programmer.

    1. Re:On multicore by Nomen+Publicus · · Score: 4, Insightful
      I've been involved with "parallel programming" for 20 years. There is no mystery involved. The C family of languages are particularly ill suited for parallel programming which may be why we are seeing reports recently claiming that it is "too difficult". Pointers in particular make life difficult for both the programmer and the compiler.

      There are a few techniques to be mastered and using a language designed with parallelism in mind helps hugely with the picky details.

  16. In other news, Chuck Norris rips on safety gear... by CaptKilljoy · · Score: 5, Insightful

    The headline is misleading. Donald Knuth represents the epitome of the solitary super-programmer stereotype, so it's only natural that he sees no need for unit tests to catch mistakes or extreme programming to improve team development practices. I don't think he's necessarily saying that those things are without value for ordinary programmers.

  17. A sample literate program by Lengyel · · Score: 2, Interesting
    I cannot resist including my own literate program. The original was written in reply to a programming test, posed by a prospective employer. During the interview I was told that the company contained their costs by keeping salaries low. In keeping with the spirit of literate programming, this story is recounted within the body of the program.

    Literate programming might be more popular if it had support for interactive debugging, with the standard features common in contemporary interactive development environments.

  18. Dismissive of DAK by symbolset · · Score: 3, Insightful

    That's a brave stance. He's old, but he hasn't reached his dotage yet. The good doctor has contributed more to the science of information than most, and almost certainly more than you.

    debugging ALGOL on punch cards as he has done would be brutally painful, of course, but here we are in 2008 with no punch cards or ALGOL.

    One of the reasons why we're reinventing so much over and over with nuisances like VB and C# is that developers are architecting grand toolchains based on ideas that were in the 1960's proven incorrect. They get a lot profits from their workarounds, and then we burn it all down and start over because they all contain the same fatal flaws.

    my dualcore laptop really has no problem with that.

    That would be because you haven't installed Vista on it yet.

    Having watched this tragedy unfold for a quarter century I've often shook my head and wondered what y'all were thinking. And then I remember that I once thought my parents were fools too. If you can read TAOCP and understand a good fraction of it you will come away with a firmer foundation for the way all things work. It's a tough slog, though, and not everybody is capable.

    --
    Help stamp out iliturcy.
  19. I've only proven that it works... by DirtySouthAfrican · · Score: 3, Funny

    "I've only proven that it works, I haven't tested it" - Knuth

  20. The Summary Exaggerates the Interview by Cal+Paterson · · Score: 5, Informative
    Knuth said many of these supposedly outrageous things in passing, and does it while noting that he is an academic. Most of these claims in the summary vastly exaggerates the strength of the claims in the interview. Knuth specifically states;

    there's no reason anybody should care about the opinions of a computer scientist/mathematician like me regarding software development.
    Knuth doesn't claim that unit testing is a waste of time for everyone, just that it is a waste of time for him, in his circumstances. This makes sense, considering he follows his own (diametrically opposed) doctrine of "literate programming", which, if the summary author has never heard of, should cause him to be cautious about interpreting Knuth.
  21. those damn kids by superwiz · · Score: 2, Funny

    and their unit test. in my days, if you needed a language, you wrote your own assembly. and when you couldn't document it, you wrote your own mark up language.... and your own fonts. phew... multiple cores. who needs them?!

    --
    Any guest worker system is indistinguishable from indentured servitude.
  22. "Open source" and Stanford policy by Animats · · Score: 2, Interesting

    There's a relevant quirk of Stanford University employee policy. For Stanford academic employees, software usually is considered "work for hire" and an "institutional work", with Stanford holding the copyright. But books and papers are considered to be the property of the author. (Policy on this changed in the late 1990s; there's a long history here, primarily involving the founding of Sun and Cisco.) However, Stanford permits the creator to place a work in the public domain, unless external funding prohibits this.

    Knuth's code is open source. But his books are not.

  23. Knuth is hardcore by Sits · · Score: 2, Insightful

    FVWM on Ubuntu Linux. Emacs with special modes using a homemade bitmap font. Mac OSX for Illustrator and Photoshop...

    Now that's breadth AND depth.

  24. Re:he's from another era by Not+The+Real+Me · · Score: 2, Informative

    "...but here we are in 2008 with no punch cards..."

    Yes and no. Yes, the physical punch cards are gone, but they live on in financial institutions in the form of Automated Clearing House (ACH) debits and credits which use the 96 column IBM punch card format. So, the next time you use your credit card, ATM card, e-check or pay a bill online through some company's web site, on the backend they are probably using ACH upload files (aka NACHA format) which was based on IBM's 96 column punch card to transfer financial data. Magnetic tape may be used on a contingency basis but it has to have an additional header record, be EBCDIC encoded and use 9 track tape. The IRS and many state tax agencies use ACH transfers, as an option, to refund personal income taxes instead of sending taxpayers a physical check.

  25. Is Multithreading a Flop? Answer: Yes by MOBE2001 · · Score: 2, Interesting

    From the interview I see that Knuth thinks multithreading may turn out to be a flop. I agree and I would go even further. I don't think there is any question that the multithreading strategy used by Intel and AMD for multicore programming is a big flop already. Multithreading is the second worst thing to have happened to computing. The worst is single-threading which is what normal algorithmic programming is based on. Parallelism is the correct approach to computing. Computing should have been parallel from the start even on single-core processors. If parallelism had been emulated in a processor from the beginning, adding more cores would have been a simple evolutionary transition, a mere engineering problem. My point is that there is a better way to do parallel programming that does not involve threads at all. Cellular automata and neural network programmers have been emulating parallism for decades without threads.

    Essentially, you need to have two buffers and a loop. While the first buffer is being processed, the second buffer is filled with objects to be processed in the next cycle. When the first buffer is done, swap the buffers and start over. Two buffers are used in order to prevent signal racing conditions. It's not rocket science. We just need to take it to the instruction level by changing it from a software mechanism into a hardware mechanism. In other words, the mechanism should reside in the processor, whether single or multicore. This is the correct approach to parallelism. Multithreading is going to be a complete disaster, a multi-billion dollar disaster. Google "Nightmare on Core Street" to find out why multithreading is not part of the future of parallel computing.

  26. Spaghetti-O Code by illegalcortex · · Score: 4, Insightful

    I somewhat disagree with what you and... *sigh* Monkeybaister posted. Yes, there are many times when long stretches of code should be broken out into functions. But I tend to do that mostly when the same bit of code is used in several different cases. The reason being is that when you start modularizing off all your while loops that are more than a dozen lines long, you create a whole new type of spaghetti code. I'm going to coin a term and call it "spaghetti-O code." You try to track down a bug and what would have been a straightforward couple pages of code now has all kinds of functions at different places in the code. As such, it can often make debugging or forming a mental map of the code much harder.

    1. Re:Spaghetti-O Code by fishbowl · · Score: 3, Insightful

      >The reason being is that when you start modularizing off all your while loops that are
      >more than a dozen lines long, you create a whole new type of spaghetti code.

      There is also a risk that you or a maintenance programmer might re-use such a "function"
      that was created simply to make a while loop more aesthetically pleasing, and introduce a bug because that function was not designed or tested for use in isolation.

      And in the spirit of the topic, such functions become awkward to unit test, since you're extracting a unit of work out of a loop or control structure, that logically lives there.

      --
      -fb Everything not expressly forbidden is now mandatory.
    2. Re:Spaghetti-O Code by Kent+Recal · · Score: 4, Interesting

      I know this problem very well from the dark days when I was still writing java.
      There doesn't seem to be a satisfactory solution, it's always a tradeoff.

      While reading this thread I realized a funny thing: This particular annoyance
      totally vanished from my day-to-day headaches when I switched to python about
      a year ago.

      It's a bit wierd because Python doesn't even use braces so one would expect
      it to be even harder to identify where a block begins and where it ends.
      But the opposite has been the case for me: The clean syntax and language
      design has led me to write, on average, shorter blocks with very little
      nesting.

    3. Re:Spaghetti-O Code by mykdavies · · Score: 4, Informative

      It's called ravioli code

      --
      The world has changed and we all have become metal men.
    4. Re:Spaghetti-O Code by Mr.+Slippery · · Score: 3, Insightful

      This applies mostly to programmers who write functions. Developers who create objects with methods usually don't require blocks of code "pages" long.

      Oh, please. Don't put on object-oriented airs. A "method" ain't a nothing more than a function associated with a class..

      A function (method, procedure, subroutine) should be just as long as it has to be to encapsulate the work it's doing. Sometimes that's one line. Sometimes it's pages.

      Breaking those pages of code into a bunch of other subroutines solely on some misguided notion that a function shouldn't be longer than N lines, makes for code that is harder to understand an maintain.

      --
      Tom Swiss | the infamous tms | my blog
      You cannot wash away blood with blood
    5. Re:Spaghetti-O Code by try_anything · · Score: 2, Interesting

      This is why good programmers must be good writers as well. The ability to explain the structure of code, primarily with clear, precise names for classes, functions, and variables and secondarily with comments, is as important as the ability to decompose a program logically. I have seen programs that were twice as complex as they should have been, yet made perfect sense and were easy to hack on, because the code and comments made it easy to understand the original programmer's understanding.

      In the interview, Knuth gave one reason why literate programming isn't popular: few people are good programmers, few people are good writers, and literate programming only works for people who fall into both categories. I think he's right. Encouraging people to write more unstructured prose than they feel a need to results in worthless verbiage, and most programmers naturally limit their comments to sentence fragments and the occasional short paragraph. If you have to force people to write, you need to provide structure and clear expectations. That's why Javadoc and similar schemes are so much more valuable in practice than literate programming.

    6. Re:Spaghetti-O Code by try_anything · · Score: 2, Interesting

      Breaking those pages of code into a bunch of other subroutines solely on some misguided notion that a function shouldn't be longer than N lines Usually people can come up with better reasons than that.

      I've worked with code written in the "pages-long function" style. One thing I've found consistently in such code is duplicated functionality. I've even personally seen how this happens: A programmer implements a very large, complex piece of functionality as a function. Later, the need arise to implement a variation on this functionality. It turns out that the variation is quite structurally different, so to implement it by parameterizing the original function would result in spaghetti code. So, a second enormous function is written. The programmer scans the two functions and finds no large sections of code that are duplicated between the two functions, so he calls the job done.

      Naturally, code developed in this manner degenerates into an unmanageable mess as more and more variations are added. Anyone trying to program this way in the business world, for example, will quickly drown. However, people tend to get by with this style in the scientific computing world, where there are relatively few variations that cannot be handled by parameterization.

      The first thing that must be done to get out of this mode of programming is to assume that such variations will arise. Treat the first problem you solve as merely the first of many variations that you will be asked to solve in the future. (Either that, or make the opposite assumption and then completely rewrite your code when the second variation arises.) Then, analyze each variation in terms of the things it must accomplish. You can categorize things using problem domain concepts, solution domain concepts, whatever, as long as you can put names on things.

      (The tendency to think in human terms and give natural language names to things is a hindrance to mathematical insight, but it often generates effective ways to decompose code. Perhaps this is another reason why the "big function" style tends to plague scientific computing.)

      Once you have split the original task into conceptually separate chunks that can be given reasonable natural language names, split the program up into pieces that have those names.

      Voila, now you have a program made of small chunks that can be understood by other programmers. And, since each chunk has a reasonable name, programmers can limit themselves to reading the name and documentation of most pieces of the program, rather than reading every single line of code. This makes the code effectively shorter and easier to maintain, even if you never reuse the chunks to compose a new variation.
  27. How is that flamebait? by zullnero · · Score: 3, Interesting

    Seriously, if you're "religious" about unit testing and mock objects, then you really need to revise the way you live your life.

    It's just a good habit to get into, if you take it seriously and don't just create tests that test silly little things like "is my text box centered where I slapped it on the form with gui form tool" type of stuff. That's kind of the point he's trying to make, that you program intelligently in the first place to avoid having an insane amount of redundant tests to pass each time you build.

    I've been doing literate programming (well, as close as you can with C and its derivative languages) for a long time now. I've watched XP coders take that literacy and chop it all up because "it didn't look pretty enough". The idea with making something literate is to make it so clear that you can reduce the total numbers of tests needed to make that code pass to only ones that test the actual expected outputs of that function. That's something that intelligent coders who don't just follow the Agile rulebook, but apply it effectively, can do. I don't know how many times I'd see a piece of code that did one simple task, had one test to test the output of that test, then another coder drops 3 more tests because they "didn't feel comfortable with only one" without specifying WHY. That is how you get into having redundant tests that muck up your test infrastructure.

  28. It's the same philosophy that K&R impart... by galimore · · Score: 3, Informative

    I'll forgive you for being a Java developer, but the fathers of C have always cited readability first (The C Programming Language ~1978). They don't call it "literate programming", which is simply a trendy buzzword, but the idea of programming for readability has been around for an extremely long time.

  29. Maybe More Like 50-75 Times a Day by eldavojohn · · Score: 5, Funny
    Well, I guess I might as well try to defend myself.

    Well, if you are testing your code 200 times a day, you are almost certainly wasting time. Lets run some numbers:

    Assuming you work an 8 hour day, that means you are testing your code every 2 minutes and 24 seconds. Given that most of your tests will take this long to run (you've got a suite of them right?), that leaves you with zero time to actually do the work you are testing.

    Frankly, if you are using Unit Tests you should be using them after major chunks of work, not in a trial and error fashion. Now if you were using them in a trial and error fashion - "lets change this, run the tests and see if they pass, no that didn't work, lets try this", etc, I could understand how you hit the 200 times per day mark. That is a completely respectable position to take. I used to work in this way during college. My several thousand unit tests do take 2-3 minutes to build. My estimate of 200 times was probably over shot and should be more like 50-75 times a day. I would also like to point out that I can continue developing while the tests run. I use Maven2 as a build tool and enjoy it immensely, it helps me do test driven development. Since you are obviously far superior to me, I will assume you know what this means but point it out to the rest of the idiots like myself. TDD is where you write your unit tests before you code. Then you satisfy your unit tests with code. When you need to change code, you change the tests and then you change the code to fix the tests. Crazy waste of time right?

    If you are coding in a trial and error fashion and using unit tests that way, I'd advise getting some tuition or changing career. Thanks, I love you too.

    But the thing is that my employer loves my work and my code rarely breaks. Now why is that? Perhaps because I'm regression testing at all times? Perhaps it's because I take the time to think about things before I do them and, as a result, I really begin to understand what it is that I'm writing.

    An added benefit is that I've found I can look at my or others unit tests and really understand what was going through their mind when the first wrote the method that I am expanding. It's quite interesting, but I'm sure you are a supreme being like Knuth and don't bother with such trivialities.

    I'm a highly productive individual ... Congratulations, I'm glad that you view yourself in such light while being able to cut me down with a few keystrokes. I'm also glad I don't work with you. Really glad. I would sacrifice all productivity in the name of being able to come into work and not feel like shit.

    Making the unit tests part of the build process is like requiring a roadworthiness test for you car every one mile you drive it. Sure the car is safe, but its not very productive at getting you from A to B, you could walk faster. I respect your decision to use a car analogy here although I find it flawed as I most often do.

    Here's a question: how much time do you spend working out what happened when your code breaks? TDD is a trivial amount of time compared to that. I am concerned about my software in the present and future. I wish others were also.

    What counts is that when you run the unit tests, they pass, and that they accurately test the conditions that need testing. I disagree with you. I run unit tests that fail all the time--on purpose.

    I know it will most likely result in a swift abrasive response but I implore your highness to really spend some time understanding how unit tests can help the really stupid coders (like me).
    --
    My work here is dung.
  30. Out of favor by illegalcortex · · Score: 3, Interesting

    It's also out of favor because of how much of the real world of programming works. My very small company does a lot of work for a very, very large company. At my small company, we have one layer of management - the owner of the company. Everyone else is in the level of "not an owner of the company."

    At the large company, there are a multitude of layers of management. Any software they build require extensive specifications and documentation far in advance of laying down any code. The decide all the aspects of the software before it's written. At my company, the boss just gives us a general outline of what he's thinking about and ask us to feel out the idea. We use a RAD environment and will often have a first iteration within a week. This version tends to get completely, sometimes multiple times. We do not document any of this in advance because the usable version may differ so much from the original ideas.

    At the large company, their projects tend to take years and years, go far over budget and typically are much less useful than they had originally hoped. As a bonus, they are usually bug-ridden and unstable. Many times they just eventually get canceled by the new layer of management, who then get awards for this "cost saving measure." At my company, our projects are typically finished far in advance for a tiny price. They are typically of very high quality, with very minor bugs which we fix rather quickly.

    This large company frequently hires our company to build software rather than trying to do it internally. They are usually amazed at the things we can do.

    Something like "literate programming" is completely anathema to how our company works. If we started trying to write specifications in advance of figuring out what product our clients actually want (as opposed to what they think they want at the start of the process).

    Now, I will state that our company only works because we don't hire idiots or slackers. Also, I am fully aware that this is not a good way to, for example, design nuclear power plant software or a baggage control system. But for businesses, all that documentation and "thinking" can just cloak that fact that the people building the software don't know what they are doing.

    1. Re:Out of favor by Coryoth · · Score: 2, Informative

      I think, perhaps, you're missing the point. Go ahead, build a prototype and try out ideas. Do the Brooks thing, and build one to throw away. Work out exactly what it is you want to do via experimentation. None of that contradicts literate programming, or "thinking first": the prototypes, the messing around, that's part of the thinking (stage one really). Once you've gone through your iterations and want to finalise something... well at that point you do have some specs, you should know what you want to build; and at that point you can use literate programming, and you can do some design by contract, and make the finalised version robust, well documented, and easily maintainable and reuasable. Building prototypes is not failing to "think first"; not "thinking first" is shipping the nth iteration of the prototype as is and calling it done.

    2. Re:Out of favor by Coryoth · · Score: 2, Insightful

      One would hope that you get to the final system design by iterative prototyping, which you then clean up, refactor, and rewrite into a nice codebase that doesn't have the evolved and iterative cruft, and is suitably documented (it's this last step where literate programming an come, though you can introduce some incrementally as modules and subsystems get frozen and rewritten). Who knows, maybe you do just ship the first thing you can get to work. What I do know is that in the business world where time is money, the clean well documented final version is going to involve a lot less time (and hence a lot less money) to maintain and debug and patch. And what if I want a new version next year? Well I would certainly prefer to have a clean readable well documented codebase to work from than "whatever worked" code. Maybe that's just me though. Different people work differently, and I'm sure you do what works best for you.

  31. Worst Summary Ever by TerranFury · · Score: 5, Insightful

    The summary sounds like it was written by the headline-producing monkeys at Fox, CNN -- or hell, at the Jerry Springer show. Donald Knuth is not "playing hardball." Nobody needs to call the interview "raw and uncut," or "unplugged."

    The interview has almost nothing to do with unit testing and the little Knuth does have to say about the practice is hardly "ripping."

    When will people stop sullying peoples' good names by sensationalizing everything they say?

    Knuth is a well-respected figure who makes moderate, thoughtful statements. From the summary, you'd think he was a trash-talking pro-wrestler.

    1. Re:Worst Summary Ever by lekikui · · Score: 2, Interesting

      Worst Summary Ever Thanks. I really appreciate the amount of respect and appreciation I get from this site.

      Donald Knuth is not "playing hardball." Nobody needs to call the interview "raw and uncut," or "unplugged." Wow, where exactly did I (or CmdrTaco) use any of those phrases? Calling something a "complete waste of time" is, in my book at least, "ripping" on something. I didn't "sully his good name," I posted what I found interesting. You should also point out he has prostate cancer and I left that out. God, what horrible spin I used! You'd think I was talking about someone whose life wasn't at risk, the way I spun that summary! Well, speaking for myself, I did find the summary fairly heavily spun. In general, it seemed to take statements out of context somewhat, turning "I generally don't find unit tests useful" into "Knuth rips on unit tests". He mentions that there are definite applications for multicore work, but that he's not in that field. Basically, the summary struck me as being spun to make his statements seem more controversial.

      Knuth is a well-respected figure who makes moderate, thoughtful statements. I happen to disagree with his stances on multi-core chips and unit testing. I didn't find anything thoughtful about what he said and really wish he would have elaborated on why unit testing is a complete waste of time. Look, shall we quote what he said about unit testing?

      As to your real question, the idea of immediate compilation and "unit tests" appeals to me only rarely, when Iâ(TM)m feeling my way in a totally unknown environment and need feedback about what works and what doesnâ(TM)t. Otherwise, lots of time is wasted on activities that I simply never need to perform or even think about. Nothing needs to be "mocked up." That doesn't look like he ripped on it. He said, basically, that he doesn't find it useful, and that it tends to waste time because of the sort of work he's doing.

      In other words, he considered the question, and provided the answer that described what he found for his work. Not what you'll find for your work, or anything like that. Just what he finds works for him.

      From the summary, you'd think he was a trash-talking pro-wrestler. Actually, after reading the article, I did find him to be a bit preachy. Apparently you and everyone else find him unquestionably correct in all his statements from that interview. I'll admit to having generally found him right. When he's talking about a subject he's not an expert on, he mentions that. He says why his opinion isn't the best on all topics. He seems to be generally careful about what he's saying.

      Where what he says is likely to be personal bias, he mentions that. So weight it as you think is relevant, given who he is.

      Yes, there's stuff in there I reckon is probably wrong. There's also an awful lot that's probably right, and he's generally been careful and thoughtful about what he's saying.

      And also, people are claiming he said these things "in passing." Which I find to be a phrase used when you want to avoid owning up to something you said. If I call you a "whiney bitch in passing" that doesn't lessen it one bit. Knuth claims no one should listen to him. Why is he publishing books if no one should listen to him? No, he said, quite regularly, that his opinion on some things wasn't going to be very useful, as he wasn't that good at them. His books are about the topics he is good at. He doesn't write them about software development best practice, or economic, or parallel computation. He deals with the topics he knows, and that's all he expects to be listened to about.

      The guy said some inflammatory comments. If you read the following posts, you'll realize that I wasn't the only one that found them inflammatory or controversial. No. Knuth generally was cautious about his statements. Do please find me some actually inflammatory comments from there. Go on, direct quotes, not just rephrasings or spin.
      --
      "Lisp ... made me aware that software could be close to executable mathematics." - L. Peter Deutsch
  32. heresy by tsotha · · Score: 3, Insightful

    After initially being a proponent, I've come to the same conclusion about unit tests myself. I don't think they're worthless, but the time you spend developing or maintaining unit tests could be more profitably spent elsewhere. Especially maintaining.

    That's my experience, anyway. I suppose it's pretty heavily dependent on your environment, your customers, and exactly how tolerant your application is of bugs. Avionics software for a new jet fighter has a different set of demands than ye olde "display records from the database" business application. More applications fall in the second category than the first.

  33. That's not literate programming! by TerranFury · · Score: 2, Informative

    That's a mischaracterization of literate programming.

    The whole idea of literate programming is to basically write good technical documentation -- think (readable) academic CS papers -- that you can in effect execute. What many people do with Mathematica and Maple worksheets is effectively literate programming.

    It has nothing to do with what language you use, and is certainly not about making your code more COBOL-esque.

    Maybe think of it this way: Good documentation should accurately describe what your code does. In literate programming, the computer code is just the "comments" you add to your documentation so that the computer can execute it.

    See this post, for instance.

  34. Nonsense by MarkusQ · · Score: 2, Interesting

    Making a program parallel will always be too hard for most programmers.

    Nonsense. The problem isn't with the programmers, it's with the languages. Writing object oriented code in Fortran is too difficuiltr for most programmers, but that doesn't mean that the programmers aren't up to the task, but that the language they are using isn't well suited to the job.

    Learn a little erlang, or Haskel to see how easy writing massively parallel programs can be. p.--MarkusQ

  35. Re:he's from another era by rawler · · Score: 2, Insightful

    "my dualcore laptop really has no problem with that"
    Moore's law says (well, indirectly at least) that machines from 2007 should be roughly 256 times as powerful as machines from 1995.

    Somehow, the actual performance difference (starting the computer, starting a web-browser, editing text etc.) in running Win95 on hardware from it's time, compared to running Vista on todays hardware, seems to be nowhere near a 256-times improvement.

    I can only conclude that while the hardware-industry have improved itself again and again, the software industry have ate almost all of those improvements, instead of giving it to the users.

  36. Knuth dismisses multicore but MMIX is poor design by pslam · · Score: 2, Insightful

    I expected much, much more from Knuth than what I've just seen in that interview and after reading the design of MMIX.

    Knuth dismisses multi-core and multi-threading as a fad and an excuse by manufacturers to stop innovating. I'm amazed someone of his intelligence has managed not to read up on exactly WHY this is happening:

    • Faster single-thread processing means faster clocking.
    • Faster clocking means smaller feature size.
    • Eventually you run into the limit of your process, shrink further and continue.
    • Finally, you run into the thermal limit of your process, and you cannot go faster in the same area.
    • To go faster you have to go sideways - more parallelism.

    So he dismisses the technical problems that manufacturers have been falling over for the last few years as merely a lack of imagination. No - parallelism is here to stay, and people need to realise it rather than just wishing up some magical world where physics aren't a problem.

    He dismisses multi-threading as too hard. It isn't, if you're not unfair to the concept. Nobody is getting 100% out of their single-threaded algorithms. You always have stalls due to cache misses, branching, the CPU not having exactly the right instructions you need, linkage, whatever. Nobody EXPECTS you to get 100% of 1 CPU's theoretical speed. So why do people piss all over multi-core/multi-threading when it doesn't achieve perfect speed-ups?

    If you achieve only a 50% speed-up using 2 cores compared to 1, you're done a good job, in my opinion. That means you could have dual-core 3GHz CPU or a single core 4.5GHz CPU. Spot which of those actually exists. Getting a 25-50% speed-up from multi-core is easy. The 100% speed-up is HARD. If you stop concentrating on perfection, you'll notice that multi-threading is a) actually not hard to implement, and b) worthwhile.

    Then there's MMIX. Knuth thinks that simplicity has to work all the way down to the CPU design. Yes, but not simplicity by way of having instructions made up of 8 bit opcode and 3x8 bit register indexes. A CPU doesn't give a crap how elegant that looks. It's also BAD design - 256 registers makes for a SLOW register file. It'll either end up being the slow critical path in the CPU (limiting top clock speed) or taking multiple cycles to access. There's also no reason to have 256 opcodes. He should have a look at ARM - it manages roughly the same functionality with much less opcodes.

    It almost pains me to see the MMIX design and how it's a) not original, b) done better in existing systems already on the market, e.g ARM, and c) doesn't solve any of the performance limit problems he complains about. What's going on with Knuth?

  37. Re:MMIX is poor design by bunratty · · Score: 2, Informative

    Remember that MMIX is not designed to be a practical hardware computer architecture. It's designed to illustrate algorithms written in assembly language. It's optimized for humans to read and write, not for computers to execute quickly. I'm glad that he's keeping assembly as part of his books, and that's he's updated them to a 64-bit RISC architecture. Reading MMIX assembly programs is the closest to hardware that some readers will ever get, so he has one chance to show those readers how computers actually work. It had better be as simple as possible for people to understand.

    --
    What a fool believes, he sees, no wise man has the power to reason away.
  38. foreach is a parallelism killer by Estanislao+Mart�nez · · Score: 2, Insightful

    To be fair, I find that a lot of high-level (business layer) code I write today consists of "foreach (...) { ... }". It would seem that there are quite a few opportunities to parallelize there.

    ...which the compiler can't discover, because foreach describes a mechanism (looping through a sequence, in order), and not a high-level transformation.

    Compare foreach with map. Map is a higher order function that takes a function and a collection, and results in a collection of the same size and structure as the original, but with each element replaced by the result of applying the supplied function to it. Note that the value of each element in the result depends only on the corresponding element of the input. It's trivial to parallelize map.

    You can parallelize map easily because it has a favorable contract that specifies the relationship between its inputs and its outputs, and it just so happens that this contract is amenable to parallel execution. A smart compiler, upon seeing a use of map, can trivially tag it as a parallelism candidate.

    But since foreach specifies a sequential looping mechanism, there are no guaranteed relations between the input and output (in fact, not even any simple way to determine what should be treated as inputs and outputs). When you write a foreach loop to perform the equivalent of a map, you're underspecifying the transformation you're performing on your collection, and overspecifying the mechanism. That's bad programming.

    You mention Parallel LINQ, and this is very relevant. LINQ is based on operations similar to map, that transform sets into sets. LINQ queries, since they abstractly describe the relation between an input and the desired output, can be executed in a number of ways: (a) the system can translate them into SQL queries and send them to a database server to execute; (b) the system can execute them serially; (c) the system can execute them in parallel.

  39. "Bug" is a relative term... by SEMW · · Score: 3, Insightful

    If you define "bug" to mean "unexpected undocumented behaviour", as Knuth seems to, then it's not surprising that there have been very few bugs claimed, since TeX is so very well documented.

    But most people -- and certainly the majority of open source projects these days -- define "bug" as "undesirable behaviour"; and by that standards, TeX is chock full of bugs. To pick a couple of obvious examples, incorrect handling of ASCII 0x22 quotation marks, and treating "etc." as the end of a sentence. These aren't "bugs" to Knuth since the incorrect behavious is well documented, but by many people's standards they are.

    --
    What's purple and commutes? An Abelian grape.
  40. Re:computer programming by Anonymous+Brave+Guy · · Score: 4, Insightful

    No offence meant, but I think your preconceptions may be clouding your judgement here.

    You claim that today's programming field is not about clever tricks and fast algorithms. I claim that if more people understood these old-fashioned concepts, we would have much better software today. For a start, anyone developing those "libraries implemented by specialists" you mentioned had better be very good, since a lot of other people's code is going to depend on them. Having worked in groups that develop various kinds of library, I can assure you that a little more general programming knowledge about clever tricks and fast algorithms wouldn't go amiss.

    You claim that today's programming field is about big systems with many programmers. I claim that this is because management and technical leadership in most places isn't competent enough to divide up a big system in modular fashion and allow smaller, more flexible teams to solve the little problems before multiplying them all up to solve the big ones. Instead, the guys at the top tend to reduce all problems to the least common denominator, "throw enough people at it and we'll win eventually" philosophy. This explains how a small company with a few dozen employees can produce software that is better in every way than the competing offering from a larger company with hundreds of developers. You don't even need to have a dew dozen genius programmers; you just need to understand the concept that there are O(n^2) lines of communication between n individuals working in a single large team, but if your project is divided hierarchically then logarithms start coming into play, and if you can split a problem into several properly independent smaller ones this becomes a constant factor overhead. This elementary mathematics seems to be beyond a lot of senior management in the software business, and that has far more to do with the need to build monolithic systems maintained by zillions of developers than any actual project requirements do.

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
  41. Literate programming by pikine · · Score: 2, Informative

    I think most people who post here don't know what literate programming is. It's more like writing a textbook explaining how your code works, but you can strip away the text and actually have runnable code. This code can be in any language of your choice. It makes sense from Knuth's point of view, but for many of us, we don't write textbooks for a living.

    Knuth also doesn't need unit testing because he probably runs (or type checks) the program in his head. Again, for most of us, seeing the program run provides additional assurance that it works. Unit tests also provide a specification of your program. It doesn't have to be just b = f(a). For example, if your code implements a balanced binary search tree, a unit test could check the depth of all subtrees to make sure the tree is balanced. Another unit test would check if the tree is ordered. You can prove by the structure of your program that these properties hold, but a lay-man doesn't want to write proofs for the code he writes, so the second best alternative is to use unit test.

    About parallel programming, Knuth is actually right. Many high-performance parallel programs are actually very involved with the underlying architecture. But we can write a high-level essentially-sequential program that uses libraries to compute things like FFT and matrix multiplication in parallel. This tends to be the trend anyways.

    --
    I once had a signature.
  42. There is no "final" version by Gorimek · · Score: 2, Insightful

    I've never seen any interesting and useful software that is ever "finished". You always need to add and change things, and there is always far more functionality wanted than you can produce.

    If you clean up and refactor as you go, rather than at "the end", what you have described is Agile/XP development.