It’s All Wish Fulfillment, Really

Well, no, it isn’t.

Some while ago, a commenter left an angry screed on one of my posts. It seems he’d been drawn to my website by some of the computer-programming-related content, and then found a post about some aspect of Christian faith and was horrified. Apparently I’d seemed such a reasonable person up until then. I don’t recall whether he used the phrase “wish-fulfillment” or not, though I rather fancy he did; and if he did I really wish I’d been able to answer the charge as it deserves. This is twice in one week that John C. Wright has shown his ability to say what I wish I’d have thought to say in similar circumstances, and far from being envious I’m grateful.

His Dark Material

Philip Pullman’s, that is. I’ve said for years now that my real disappointment with Pullman’s His Dark Materials trilogy is not that they are anti-Christian (though they most certainly are, whatever waffling Pullman’s currently doing in the media) but that he allows his message to overwhelm his storytelling. John C. Wright has the same notion and has given it a thorough analysis, explain why and where Pullman’s storytelling falls short. (Wright’s a published author himself, BTW, though I’ve not read any of his books. His analysis is cogent, and hits quite a few points I hadn’t considered, and is worth your time if you’ve any interest in the topic at all. And then, there’s this lovely bit of snark from the end:

Nothing I have ever read, not by Heinlein and not by Ayn Rand has been more blatant in dropping the story-telling, and devoting its pages to preaching a message. The writer was drunk on sermonizing. If this plotline was a motorist, it would have been arrested for driving while intoxicated, if it had not perished in the horrible drunk accident where it went headlong over the cliff of the author’s preachy message, tumbled down the rocky hillside, crashed, and burned.

As Wright notes, it would be one thing if Pullman were a bad writer…but he isn’t, and should know better.

Yes, Virginia, There Is A Difference

Simcha of I Have To Sit Down comments on gender differences. It’s all good, but here’s my favorite bit:

When my son was about 3, he wandered in while the girls were watching Barbie of Swan Lake (a movie whose narrative was a little too sappy, if such a thing is possible, for Tchaikovsky’s music). He stood there silently, mouth clamped shut, eyes broodingly fixed on the screen. After about twenty minutes, he croaked out, “This . . . is not good. I . . . don’t . . . like this.” Then he went in the other room to hit stuff.

Notebook Markup: Headers and Whitespace

In Notebook 2, you can add section headers into your pages. This, for example, gets turned into a first-level header:

    = All About Penguins =

Or, rather, it sometimes gets turned into a first-level header. There pretty much has to be a blank line before it; if you enter something like the following, your header will become part of the previous paragraph:

    ...end of previous sentence.
    = All About Penguins =

Also, in Notebook 2 you have to remember the space characters; this won’t work:

    =All About Penguins=

I’ve fixed all of these things in the new parser, which is a good thing. However, there are still some issues.

In normal HTML, text marked as a header will typically get separated from the preceding and following paragraphs by a certain amount of whitespace. In Notebook 2, by contrast, you get blank lines where you put blank lines in the text of your page. That means you always get at least one blank line before a header (since, as I noted above, it isn’t a header without one) and you get a blank line after a header only if you want one. That is, this gives you a blank line:

    = All About Penguins =

    Penguins are fierce creatures who roam the Antarctic veldt.

And this doesn’t:

    = All About Penguins =
    Penguins are fierce creatures who roam the Antarctic veldt.

I can retain this behavior, or I can change it so that blank lines before and after the header line in the input are ignored, and the header always gets whitespace before and after.

Any one have any thoughts one way or the other?

Notebook Markup: Parsed Form

I hope everyone had a happy Thanksgiving! We certainly did, which is not surprising given how much we have to be thankful for.

The remainder of this post is likely to be of interest mostly to programmers and folks who want to know how things work inside. Later on, as promised, I’ll have some posts dealing with changes to the markup itself. If you came here looking for those, please try again in a day or two; this post isn’t it.

I took the whole of Thanksgiving week off, and spent a good deal of it rewriting Notebook’s markup parser. In order to thinking about extending the markup syntax I needed to re-familiarize myself with the order in which everything is parsed; and then there are some long standing bugs that can’t be fixed without a major rewrite; and on top of that, the output of the existing parser is not nearly as useful as it could be.

I’ll explain that by way of an example. Consider the following markup:

    = Important Stuff =

    This is a page with a link to some [important stuff]
    that you really ought to read!

Now, there are two reasons to parse this page: to render it beautifully for display to the user, and to transform the page in some way. As an example of the latter, if the page named “important stuff” is renamed “not-so-important stuff” we want to update all of the links to it, including the one in the snippet of markup shown here.

For the purposes of rendering, all we really need is the semantic content in the page. But for transformations, such as renaming links, we really want to be able to recreate the page just as it was, with the exception of the changes we meant to make. To do this, we need access to the syntactic content as well. The existing parsed form does a bad job of this: it mingles the semantic and syntactic content in such a way that any transformational code needs to understand the semantics in order to do its job.

Let me explain. Here’s the parsed form of the snippet shown above; it consists of a list of tags and values. The tag indicates the kind of thing found in the input, and the value is intended to provide enough information to render it, and to recreate the input text:

    H    {1 {Important Stuff}}
    NL   {\\n\\n}
    P    {: 0}
    TXT  {This is a page with a link to some }
    LINK {important stuff}
    TXT  {\\nthat you really ought to read!\\n}
    /P   {}

The “H” tag is produced by the header; its value tells us that it’s a level 1 header, and that the header string is “Important Stuff”. Similarly, the “LINK” tag tells us that there’s a page link, and the link text is “important stuff”. The “NL” tag indicates that there was a blank line following the header, and that the blank line was indicated by two newline characters.

Note the difference between the “NL” tag on the one hand and the “H” and “LINK” tags on the other. The value of the “NL” tag is precisely the text that was read from the input. The value of the “H” and “LINK” tags includes only a portion of the input text. And herein lies the problem. Our algorithm to rename changed links must parse this text so that it can find the link that needs to be changed, and then put the input text back together again. In order to do this, the algorithm must understand the semantics and syntax of every tag, i.e., it must know that “H” is a header and what the “H” tag’s value looks like, and what the markup for headers is, even though headers are irrelevant to the goal that it’s trying to accomplish.

Here’s the new parsed form:

    H      {0 20}   {level 1 text {Important Stuff}}
    P      {}       {code : indent 0}
    TXT    {21 55}  {}
    LBLINK {56 56}  {}
    LINK   {57 71}  {}
    RBLINK {72 72}  {}
    TXT    {73 104} {}
    /P     {}       {}

Note that each tag now has two values instead of one. The first value is a pair of numbers representing the indices of the matched text within the input string. In some cases, the tag represents a logical point within the input, such as the beginning or end of a paragraph, and doesn’t actually match any characters; in this case, the pair is empty, “{}”. The second value contains any additional semantic information needed to render or transform the specific content. The “H” tag, for example, indicates what the header level is and what the header text is.

Because each tag indicates the span of input text it matches, and since every character of the input text must be matched in order, we can rebuild the input string simply by iterating over the tags and looking at the first value for each, without any concern for the type of each tag. Thus, to rename links the algorithm now looks like this:

    For each tag,
        If the tag is not "LINK",
            Use the indices to copy the input text to the output.
        Otherwise, if the link text references the renamed page,
            Copy the new page name to the output.
        Otherwise,
            Copy the old link text to the output unchanged.

Note that there’s no need for this code to understand anything about headers, or indeed about any tag but “LINK”. The new parser output is much more useful, and I think will serve me well in general, though possibly with a little tweaking.

Soarer’s Choice, by L.E. Modesitt, Jr.

This, the sixth in Modesitt’s Corean Chronicles series and the climax of the series’ second three-book sequence, was seriously disappointing, and the more so as I liked the fourth and fifth books better than the first three.

I find that I can’t explain my disappointment without spoilers; if you want to know why I disliked it, click on through.
Continue reading

Why Jesus Makes A Difference

Once again, as so often in the few weeks since I discovered Jennifer’s blog, I find that she’s said just what I would have wanted to have said, if I’d been asked the same question, and if I’d been given the grace to understand the answer so well. In this post, she responds to the following comment:

How sad to see that you abandoned reason for faith. would it not be even better if you started living your life as if it mattered in it’s own right and not just so that you could get into a special heavenly club. I think doing good for no other reason then such a selfish desire is despicable.

Jennifer gives a typically detailed and thoughtful response, but the heart of it, for me, is this:

But these concepts — “heaven,” “hell,” “eternity” — are still vague enough in my mind that they don’t motivate me on a gut level. So while I know on an intellectual level that I want to go to heaven and stay out of hell, I have never avoided doing something bad because of the thought, “If I do that I might go to hell!”

There is a very big motivator, however, that is related to the concept of heaven: I don’t want to reject God.

(Emphasis mine.) That’s exactly right. I know that God loves me. How well I know that feeling I get just after I’ve gone out of my way to do something I shouldn’t have done that I know will disappoint Him—that feeling that makes me want to reject God because I don’t want to face Him in my sinfulness. I don’t like that feeling. The hard part is remembering how awful it is before I do whatever it is that I want to do.

Credit where credit is due

A while ago I posted a lengthy series of posts on why Jane and I had chosen to become Roman Catholic. On reflection, I realized that I’d left out an important part of the story.

What I related was my intellectual and spiritual journey, the studying I had done, the thinking and praying I had done, as though I were the active agent in all this. It certainly seemed that way at the time. But in fact, it was the Holy Spirit at work all the time. I followed a path, but I was led along that path, and it seems only fair to say so.

And then, there were many people praying for us as well. I’d like to particularly mention Julie D. of Happy Catholic, who prayed for us when I asked—diligently, over a long period of time, too.

And in the context of people I only know “on-line,” as it were, I find I have to mention the Blessed Virgin Mary and St. Thomas Aquinas, both of whom were sources of aid and comfort to me over the last year.

Regarding St. Thomas Aquinas, I’ve observed that although there are “official” patron saints for all manner of occupations, there is no specified patron for software engineers. The closest is St. Isidore of Seville, the patron saint of the Internet, so named because he wrote one of the first encyclopedias. For my part, I think St. Thomas would be an excellent patron for software folks. As a philosopher and theologian he spent his days building fine distinctions and subtle abstractions into beautiful and coherent cathedrals of thought. Which is, quite literally, what I attempt to do at work every day.

Dear Lord, thank you for your leading. Blessed Mother, St. Thomas, thank you for your prayers.

Logic Made Easy, by Deborah J. Bennett

One of the things I ran into when I started looking into Aristotle was Aristotelian logic, and particularly the Aristotelian syllogism. You’ve seen at least one of these, I’m sure, probably this old chestnut:

Major Premise: All men are mortal.
Minor Premise: Socrates is a man.
Conclusion: Socrates is mortal.

I’d run into this one any number of times…but most of the descriptions I’d read got about as far as, “This is what an Aristotelian syllogism looks like. There’s a major premise and a minor premise, and a conclusion, and if the major and minor premises are true the conclusion is guaranteed to be true.”

OK. I can look at the example above and see quite clearly that the conclusion follows from the major and minor premise; but what is it about this form that guarantees the truth of the conclusion? I had no idea. There was clearly a lot more to be known. I went looking, and found this book, which looked like it covered the topic in sufficient detail, along with a whole lot of other stuff about logic. It went with me on several of the numerous business trips I made this past year, and I had a lot of fun with it.

Bennett’s aim is twofold. First, to tell the story of how the study of logic developed over the last three millenia, and second to discuss the relationship between formal logic and the kind of reasoning most people use when confronted with logical problems. It succeeds very well at both, and I recommend it to anyone who is interested in such things.

But about those syllogisms. Here’s what I discovered. The statements in an Aristotelian syllogism have forms like “All X are Y“, “Some X are Y“, “No X are Y“, and “x is a Y“, where “X” and “Y” are categories and “x” is some particular entity, e.g., “is a man”, “is mortal”, and “Socrates”. What Aristotle did was categorize all possible combinations of these kinds of statements involving three terms “X“, “Y”, and “Z“, and then painstakingly showed, by other means, that a subset of them (well under half, if I recall correctly) will always yield a true conclusion if the premises are true. By remembering and sticking to those valid combinations (to which the Scholastics gave such charming names as “BARBARA”), one could be sure that one’s reasoning was correct.

Now on the one hand, this is cool: Aristotle was dealing with existential qualifiers two-thousand years before they were first defined in mathematical logic. On the other hand, the examples I saw seemed fairly obviously true without any particular analysis of their syllogistic structure. Hmmmm.

And then, in the next chapter or so, I found out why I’d never before had occasion to learn about Aristotelian syllogisms: modern logic, the kind I learned about in geometry class, I kind I’ve been using daily as a working programmer for two decades (and as a hobbyist before that), isn’t based on Aristotelian logic, but rather on the logic of the Stoics. The Stoics had only two syllogisms, the modus ponens and the modus tollens, the form of which is so absurdly simple I’d never thought of them as syllogisms. Given two statements, “p” and “q“, modus ponens says:

Major Premise: If p is true, then q is true.
Minor Premise: But p is true.
Conclusion: Therefore, q is true.

The modus tollens is simply the contrapositive of this, “if not-q then p.”

On these two syllogisms hang, if not the law and the prophets, then all of the programming I’ve done and all of the math I studied as a math major.

At this point I began to realize that I while I might enjoy finishing the book, I wasn’t likely to learn anything both new and useful, and I was right on both counts. For example, did you know that Venn diagrams were invented to help analyze Aristotelian syllogisms? Neither did I. Now I realize that the real descendant of Aristotelian logic is not logic per se, but set theory. Such an amazing epiphany, you can’t imagine.

But it’s still a good book, and if you have any taste for logic or logic puzzles it’s worth your time.

Notebook 3 Markup Design

I’m beginning to contemplate extending and changing Notebook’s preferred markup for Notebook 3. The plan is as follows:

  • Notebook 2 markup (nbm2) will continue to be supported indefinitely. In Notebook 3, you can choose the kind of markup you want to use, page by page.
  • Notebook 3 markup (nbm3) will be based on nbm2, but won’t be identical. It will be extended (i.e., with support for tables) and may have other changes designed to make it easier to use, easier to parse, more powerful, or all three.
  • If nbm3 turns out not to simply be a superset of nbm2, I expect to provide a translator between nbm2 and nbm3 so that you can easily update your old pages if you would like to.

In short, while I’m not setting out to define something entirely different, I’m open to making significant changes as well.

So…if there’s something about the existing notebook markup that you dislike, or something that you’d like to have, please get in touch! (Note that there are already quite a few requests in the bug tracker.)

I’ll give an example: In nbm3, enclosing a word or phrase in stars *really* ought to make it boldface, as that’s a convention most of use in e-mail and other plain text anyway. So nbm3 might handle boldface like this:

  • Star-notation, i.e., *this is bold*, might replace apostrophe notation, i.e., '''this is bold'''; or we might support both.
  • The older <b>this is bold</b> notation will be retained, as it can work in cases where one of the other forms would be ambiguous.

If you’ve got opinions, let them be heard!