Hi Tim, I'm glad you're continuing the conversation, which has helped me at least to clarify my thinking about not just LP but about the nature of programming and the sort of tools we (or I at least) need to support good programming. I end up in a very different place than you, but I don't think it's a zero-sum game. Please take the comments below in the irenic spirit in which they are offered - not "you are wrong on so many levels that I'm compelled to enlighten you", but "here are some other ways to look at things that seem interesting."
On Wed, May 21, 2014 at 6:03 AM, <d...@axiom-developer.org> wrote: > The primary focus of a "documentation system" is communication from > the author to the audience. > Communication is an important part of the puzzle, I agree; but what exactly is it? There are lots of models<http://en.wikipedia.org/wiki/Models_of_communication>, which carry very different implications. > > One of the struggles apparent in discussing issues of communication, > especially with programmers, is Heideggers "present-at-hand" vs > "breaking down". > > Programmers write programs to instruct a machine to perform some > task. In the ideal, this involves "communication" from the mind of > the programmer to the "execution of the program". This suggests a transference or transmission model of communication based on what Roy Harris <http://www.royharrisonline.com/INP26.html> calls the "telementation" and fixed-code fallacies - the idea that communication involves transference of some kind of content ("thoughts", "concepts", etc.) from one mind to another, or to a machine, by encoding, sending, receiving, and decoding "messages". That may be a good model for computational communication, but it has severe (and I think insurmountable) problems as a model for human communication. More fundamentally, whether human-computer interaction should be considered communication at all is problematic to say the least. For a terrific study on communication check out Michael Tomasello's Origins of Human Communication<http://books.google.com/books/about/Origins_of_Human_Communication.html?id=T3bqzIe3mAEC>. The suggestion there is that successful communication amounts to successful coordination of joint action. The notion that programs "instruct" a machine to perform some task is very common - it's arguably central to Knuth's concept of LP - but I'm not convinced it is correct. In a sense, a program just *is* a machine, albeit an abstract one. When you compile it, you just translate it into another language, yielding an equivalent machine, one that a physical machine "understands". When you "run" the machine program, it doesn't "instruct" the hardware to do this or that, any more than the laws of physics "instruct" apples to fall in a certain way, or a hurled stone "instructs" the window it meets to shatter. ...snip... The effect of this constant "breaking down" is that we have learned, > rather painfully, to be aware of the machinery of the process at every > step of the way. This focus on the machinery becomes the expected way > of communicating with the machine. Scratch any programmer, interview at > any company, listen to any talk, and you find "machinery". > How could it be otherwise? Programming is machine construction. > > But communication from the author to the audience is the underlying > theme of literate programming. Knuth's point is about communication, > not about the machinery of communication. The question is, to what > audience, not how. > I'm not sure what "machinery of communication" means. It's not something I ever think about when I'm programming; in fact I never think about communication. I think about language, logic, and expressiveness. Whether others understand what I write is not something I can control; all I can do is try to write clearly under the constraints of the language I'm using. The problem with focusing on communication is that successful communication is the responsibility of all parties involved. Authors can be held responsible for what they write, but not for what readers read; this is true for all forms of writing. There's not much an author can do to prevent readers from misreading, other than try to write clearly. Unfortunately, the Principle of Charity<http://en.wikipedia.org/wiki/Principle_of_charity>is routinely ignored (especially on the internet!) Knuth: "Instead of imagining that our main task is to instruct a *computer*what to do, let us concentrate rather on explaining to *human beings* what we want a computer to do." Notice how Knuth changes horses in midstream, from "instructing a computer" (i.e. writing code) to "explaining to humans", which is not writing code. The conclusion that many (well, some) have drawn is that we should treat the "literary explanation" as central, and the code as secondary or even incidental. I guess that's ok if your task is to explain a program, but as a model of what programming is or ought to be, it's not even wrong. The *only* reason to write a (real, not toy or pedagogical) program is so that a (physical) machine can run it. If it can't be run, or if it produces the wrong result, then it doesn't matter how good the documentation is. Here's the Knuth quote from his LP article nobody ever cites: ""In fact, my enthusiasm is so great that I must warn the reader to discount much of what I shall say as the ravings of a fanatic who thinks he has just seen a great light." We should take him seriously. [Also, as a historical matter, Knuth himself clearly had strong ideas about the "how" involving things like "natural" narrative order, monolithic text+code, etc.; see the quotes at https://github.com/mobileink/codegenres/wiki/Quotations.] The notion that programmers should focus on documentation addressed to humans is where I part company with Knuth (and just about everybody else, I reckon). Time spent writing "magnificent" documentation is time that could be spent making the code better and more understandable. I actually think that Knuth completely misunderstood the nature of programming. I do *not* think that programming **essentially** involves "communication" with other humans (although it arguably does involve coordination with other humans). Or with machines, for that matter. The essence of programming is the construction of machines, which is something that creatures lacking natural language can do in principle and do in fact do - there are many examples of non-human animals constructing and/or using machines (e.g. primates using sticks to pull termites out of a mound). When you compile and run a program there is no communication of ideas going on - machines obviously do not have ideas. What's really happening is that you arrange the physical world in such a way that it behaves the way you want it to behave. (Let's not forget that program text is physical - a configuration of "bits" in a piece of hardware - which we construct using our fingers at a keyboard; also, that there is no distinction to be made between (formal) language and machine.) The fact that we draw on natural language to define the symbols of our programming languages (the sprockets of our machines) is entirely parasitic on the primitive notion of machine (formal language). We could replace all the keywords of our favorite language by random strings, and programming would still be possible in principle; that's trivially obvious, but it is not trivial. It means that human communication is not a primitive element of programs. Yet for obvious practical reasons we do prefer to use natural-language facsimiles in our programming languages - facsimiles, since predefined formal strings like "map" or "conj" only look like natural language words. And when we define local names we invariably use natural-language-like terms. The possibility of doing this is obviously very useful, but it remains secondary to the primitive structure of mindless symbol manipulation machinery. Choosing a good natural-language representation for a variable or function name involves finding a word or phrase that *expresses* the computational semantics, and *that* is where human communication enters the picture: the expressiveness of the programming code itself, as a hybrid of quasi-natural-language piggybacking on abstract formal language. This suggests an alternative to LP "methodology": programming not as literary composition but as language design. Program texts to be viewed not as essays expressed in a programming language, but as extensions of the language. For example, every function definition of arity > 0 effectively defines a mini-DSL as an extension of the base language. The parameters to the function are "terms" that are locally (temporarily) added to the lexicon. Ditto for "def"ed names. Lambda expressions ("anonymous" functions) are themselves names - you can view them as one-off names, or you can think of the language lexicon as already implicitly containing all possible lambda expressions as names. If your language has hygienic macros like Clojure you can extend the syntax as well. A "good" language extension (program) is one that uses the expressive resources of a natural language to extend the vocabulary and/or syntax of the base language in "good" ways - good involving principles of clarity, parsimony, etc. On this view documentation is entirely external to programming. In any case, the result is a radically different view of what programming is all about: programmers not as mere users of languages designed by others, but as designers of (derived) languages, whose task is to extend programming languages in ways that fit (express) the problem domain. Every program is then viewed as a kind of DSL design. Libraries are DSLs that can be used in other designs. Locals are not "variables", which puts the focus on semantics, but "lexical extensions", which puts the focus on language and thus expressiveness. Etc. Since programming language designers are generally held to a higher standard with respect to clarity and expressiveness - you'd better put some serious thought into syntax and predefined names if you're going to design a new language - programmers who think of themselves as language designers might do a better job of writing understandable programs. And from this perspective documentation is a completely separate issue that should not be confused with writing code. (I am NOT saying that documentation is unimportant, only that it is not to be conflated with programming.) So I would modify Knuth's plea to something like ""Instead of imagining that our main task is to instruct a *computer* what to do, or to explain to *human beings* what we want a computer to do, let us concentrate rather on designing *expressive* languages that solve our problems." Needs work I guess, but you get the idea. Improve programming. Also improve documentation. Don't confuse the two. > Discussions seem to get lost in a debate about the machinery rather > than the goal. We focus our debate on docstrings versus markup versus > wiki. We consider literate programming to be "too much machinery". > Not too much, but the wrong kind of machinery. > > In these forums there is rarely find any example of "present-at-hand" > issues of communication. That is, given a large program (e.g. Axiom, > Clojure), what is it that we need to communicate, to what audience, > and at what level of detail? > Or, for what purpose? The author cannot determine who reads his or her work, but can decide on a purpose. You might write a book with a college freshman audience in mind, but to me that translates into "for the purpose of instructing people with a certain level of knowledge and experience", which frees it from any particular social group. Even though I've challenged some of your assumptions I think you are right to stress this aspect of program texts and documentation - the purpose (or intended audience, or whatever we want to call it). Lots of comments on behalf of LP ignore this; a common ploy is to offer an expressly pedagogical LP text as an example that generalizes to programming of all kinds. But different purposes (audiences) demand different approaches. (I've sketched out some ideas along these lines at https://github.com/mobileink/codegenres/wiki/Code-Lit.) The presentational output of LP is great for some purposes, so LP may be a good method; but note that that does not imply that the source from which such a presentational form is generated must be an LP text. > > Axiom focuses on "The 30 year horizon" under the assumption that the > computational mathematics will be forever valid and that the audience > will be unable to contact the likely-dead authors. > > Pharr and Humphreys' "Physically Base Rendering" [0] is written as a > literate program, a book that won an Academy Award, using Tex and > C++. The very first thing they mention in the preface is the > "Audience". They communicate to humans and, also, to machines. > The goal of the book is explicitly pedagogical, so LP is useful. But it doesn't generalize to all purposes. PBR is clearly becoming the poster child for LP. It won an award! LP good! (I'm not saying that's what you mean here. I'm just sayin'.) But what won the award was the book - the explanation, presentation, and content of the book/program, not the LP source text of the book/program. The award was for "for their formalization and reference implementation of the concepts behind physically based rendering<http://www.oscars.org/press/pressreleases/2014/20140108.html>" - not for using LP. In principle the same book could have been produced by other methods. > > What is the audience for Clojure? > I don't think it has an "audience" - it's a tool, not a text. But it does have markets - programmers and other users of such tools. > > Common Lisp has achieved a long-term horizon by raising the language > to a standard. No standard is perfect but it does make it possible to > construct programs which have a stable base for communication. That > base makes it possible to write a book like "Lisp in Small Pieces" [1] > which communicates ideas in natural language using an embedded program > as a reduction to practice. > A great book, but it's not really about CL in particular. It's mostly Scheme, and it's not LP. So I'm not sure why you're citing it - is your point that it exemplifies narrative prose with embedded code? Maybe I'm not following your point about communication here. > So the fundamental point is what to communicate to what audience, > not how to implement it. Different audiences will need different > implementations (e.g. docstrings for REPL users) but we must avoid > losing ourselves in the noise. > You can say that again. Another major source of noise is failure to distinguish between the presentational output of classic LP and the use of LP tools and techniques. There's more than one way to get that sort of output. > > Axiom, by choice, has a defined audience. Does Clojure? > I'm not sure what you're getting at with this question. What kind of answer would count as a good one, for you? Cheers, Gregg -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.