Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

MOPT-01 - assumptions and spaces

by mstone (Deacon)
on Dec 10, 2002 at 03:25 UTC ( [id://218729]=perlmeditation: print w/replies, xml ) Need Help??

Meditations on Programming Theory

This is the first in a series of articles about programming theory. I'm writing them in response to requests other monks have made for such information, and as a personal test to see how much of this stuff I can make accessible to an intelligent and motivated audience. I'll try to post a new article every monday. Between posts, I welcome questions and discussion.

And now, the (hopefully) good stuff..

meditation #1: Human assumptions and information spaces:

When self-taught programmers start to explore programming theory, they tend to find the vocabulary daunting. That makes sense, because it's a dense, layered vocabulary, full of ideas that seem obvious at first glance, but turn out to be surprisingly complicated when you really start thinking about them. And you have to pile a whole bunch of those ideas together before you get anything that even vaguely ressembles a high-level language like Perl.

To make matters worse, most books on programming theory jump to the fun parts, like the implications of the pumping lemma on finite automata. They do that because it's a long walk from there back to the kind of fundamental concepts an ordinary person can understand.

For this series, I'm going to go all the way back to the basics, starting with one of those deceptively obvious ideas that everyone can agree with at first glance:

  • Computers do not think.

Everyone knows that computers don't think, but most people would be hard pressed to tell you what computers actually do. And they'd have an even harder time trying to describe the difference between 'thinking' and whatever it is that computers do.

What computers really do is manipulate symbols according to a predefined set of rules. Humans, on the other hand, associate symbols with meanings.

Again, it's easy to nod and agree with that, but even good programmers can get caught by the difference a dozen times a day. Every time we write 'Foo_package' instead of 'FooPackage', or 'if ($string == "foo") {...}' rather than 'if ($string eq "foo") {...}', we cross the boundary between symbols and meanings. The problem is so common that we've built ourselves special tools (i.e.: syntax-coloring text editors) to make sure we're spelling our symbol names properly.

That brings us to our second deceptively simple idea:

  • For humans, symbols represent meanings.

The tricky bit here is that we humans are the ones who assign the meaning. Remember: computers don't think. They have no concept of 'meaning'. They just manipulate symbols according to a predefined set of rules. But in the human frame of reference, we expect to move from one meaning to another, logically connected meaning.

The problem is that, even in the human frame of reference, it's hard to pin down the concept of 'meaning'. Philosophers have been fighting over it for centuries. Personally, as a programmer meditating about programming theory, I've found it easiest to assume that the term 'meaning' describes all the logical connections we can make between one idea and another.

To put that another way, we can define meaning in terms of human assumptions. We assume that a symbol with a certain meaning will behave a certain way. And that brings us to our first basic concept of programming theory per se:

  • Human assumptions are the basis of all software.

Programmers define the rules by which computers manipulate symbols. We (and the users) assign meanings to the symbols, and expect the software to give us new symbols whose meanings make sense. That means the programmer's job is to track down all the connections between meanings, then model that graph of connections with a set of rules that manipulate symbols.

More poetically, you could say that programmers build bridges between the human frame of reference and the machine frame of reference.

To do that job properly, you need to know several things: you need to know what kinds of assumptions people usually make, you need to know what kind of behavior you get from a given set of rules for manipulating symbols, and most of all, you need to do a whole lot of bookkeeping to make sure you haven't left anything out.

That last one is important. Humans inherit a vast, richly-connected set of associations between meanings just by being human. Some of it seems to be built into the very structure of our brains. The rest of it comes from exposing a functioning nervous system to a large and complex world for a few dozen years. Computers, on the other hand, only make the connections we tell them to.

That echoing lack of connections between concepts is probably the hardest thing for humans to truly understand. But you have to be aware of it if you want to be a good programmer. I use two catch-phrases to remind myself of that idea:

  • Programming is the art of thinking clearly,
  • and, A computer programmer is a human who's learned to think like a computer.

Programming theory teaches humans how to think like computers. It teaches you how to simulate a computing machine in your head, rather than shuffling a bunch of rules together and hoping they do the right thing.

(As an aside, I've spent a fair amount of time watching other programmers work, and have read lots of code. When I'm in an especially nasty mood, I'll tell you that most coders don't actually program, they just act as the selection function in a very slow genetic algorithm that evolves a set of rules around a desired set of features)

Before we start looking at how rule-systems work, though, I want to lay out a set of very common human assumptions. They're so common, in fact, that we call them information spaces. There are seven basic kinds of information spaces, each of which revolves around a certain assumption:

  1. Nominal spaces
  2. Ordinal spaces
  3. Interval spaces
  4. Rational spaces
  5. Irrational spaces
  6. Complex spaces
  7.  and Absolute spaces

A nominal space defines the concept of identity. The word 'nominal' comes from the latin word for 'naming'. Nominal spaces let you perform two basic kinds of operation:

  • Existence testing, (i.e.: do I know what a 'foo' is?)
  • and Equivalence testing, (i.e.: is this thing in my hand a 'foo'?)

Things like interrupt symbols (SIGHUP, SIGQUIT, SIGKILL, etc), file control flags (O_RDONLY. O_WRONLY, O_RDRW, O_APPEND, etc), and similar 'valueless' constants form nominal spaces. In C, programmers use enumerations to define nominal spaces. In Perl, we generally use hash keys and ignore the associated values.

When you see a snippet of code like:

my %uniq = map {($_,1)} @strings; my @result = keys %uniq;

it's a sign that you're working with a nominal space.

Mathematically, nominal spaces are unordered sets, and you can perform all the usual set operations (subset, union, intersection, etc) on them.

An Ordinal space uses the concept of identity, and adds the concept of order. Ordinal spaces let you perform the three-value 'before, after, or same' operation that Perl represents with the spaceship (<=>) operator. The most common operation you perform on an ordinal space is sorting.

Strings, especially filepaths and URLs, tend to be treated as ordinal spaces.

An Interval space uses the concepts of identity and order, and adds the concept of distance. Any two adjacent elements in an interval space are the same distance apart, which means you can make meaningful comparisons between ranges in that space.

That was a bit heavy on the mathematical jargon, so let's look at a couple of examples:

We already know that nominal spaces don't have a concept of distance. It makes no sense to ask whether SIGHUP is closer to SIGQUIT or SIGKILL. The days of the week are an interval space, though, and it does make sense to ask whether Tuesday is closer to Monday or Saturday.

Time is by far the most common interval space you're likely to work with, although geometric calculations run a close second if you happen to be working with graphics ("does this shape overlap that shape?", for instance).

Perl doesn't have any built-in operators or data types that support interval spaces, and neither do most other commonly used languages. Databases, OTOH, almost always support a set of time operations, and some (like postgresql) also support geometric operations.

A Rational space uses the concepts of identity, order, and distance, and adds the concept of an origin, and by extension, the number zero.

Rational spaces support the mathematical operations of addition, subtraction, multiplication, and integer division. almost all the numerical work programmers do takes place in a rational space defined by the language.

An Irrational space supports all the concepts a rational space does, but also supports the existence of numbers that can't be expressed as the ratio of two integers, like Pi and the square root of two. Irrational spaces support operations involving fractional exponents (i.e.: taking the roots of numbers), and logarithms.

Technically, computers can't handle irrational spaces at all. The decimal expansion of an irrational number is infinitely long, and a computer only has a finite amount of memory. There are also more irrational numbers than rational ones, so trying to represent them symbolically leads to problems, too.

In most cases, we approximate irrational numbers with rationals, and agree to ignore the rounding error. The field of numerical mathematics deals with the headaches of trying to keep that rounding error low, for situations where you really have to care about accuracy.

A Complex space is an irrational space that includes a special symbol called the imaginary number, which is defined as the square root of negative one. A complex space lets you perform any mathematical operation at all, including those that seem really wierd, like finding the square root of negative seven.

Complex numbers are vectors, with a 'real' part and an 'imaginary' part. You'll probably never run into them unless you're doing advanced scientific work, and then you'll probably know enough math to write your own complex number package.

Absolute spaces are a bit strange because they define the concept of a unit by negation. An absolute space is a space where the distances have no units.

Again, let's look at an example:

For normal programming purposes, the Farenheit and Celcius temperature scales are both rational spaces. They both have items with names (the integers and integer fractions); they both have concepts of greater, less than, and equal; they both have an origin, and they both have a concept of unit distance between entities.

The problem is that the unit distance between Farenheit degrees is smaller than the unit distance between Celcius degrees. If we want to convert Farenheit to Celcius or vice-versa, we need to multiply by a conversion factor.

Now let's look at probabilities: If I roll a fair 6-sided die, I have a 50% chance of rolling a 1, 2, or 3. If I flip a fair coin, I have a 50% chance of getting heads. Those two 'fifty percent' values are equivalent, even though I'm generating them two different ways.

Probabilities, and most other statistics, are absolute in the sense that I can compare any two percentages, regardless of how they were obtained. The whole point of descriptive statistics, in fact, is to characterize data in terms of numbers that don't make you worry about conversion factors.

Physics, electronics, and most other scientific trades also have formulas that produce numbers without units.

----

The first step in thinking clearly-like-a-programmer is to know what kind of space you're working with at any given time. The second step is to use tools that are appropriate to the space in question. Programmers who haven't figured out what kind of space they're working with can waste endless time one of two ways:

  • trying to make a space that's too powerful do less than it can,
  • or trying to make a space that's too simple do more than it should.

If you want a nominal space, use hash keys. Don't use integers, and for heaven's sake don't 'add one' to go from one entity to another. Study the file control flags (which do use integers as constants), and see how the boolean AND and OR operations make a byte act like an eight-element unordered set of bits. Then go back to using hash keys for nominal spaces, and rejoice in how much easier everything is.

By the same token, don't screw around trying to do basic math with your hash keys. Use numbers. That's what they're for.

Okay.. that's enough for one week, in case anyone has made it this far and is still awake. Go meditate on the nature of human assumptions, and how you represent them in your code. I'll be back next week to talk about symbols and the rules that manipulate them.

Replies are listed 'Best First'.
Re: MOPT-01 - assumptions and spaces
by pfaut (Priest) on Dec 10, 2002 at 12:51 UTC

    Computers do not think.

    ...

    Programming is the art of thinking clearly,
    and, A computer programmer is a human who's learned to think like a computer.

    So, a computer programmer is a human who's learned not to think?

    :-)

    Nice article, by the way.

      And you think like a programmer :). This isn't meant to be insulting (as I'm sure it might be construed, although probably not by someone who thinks like a programmer) but it occurred to me that the way you honed in on that little logical gem is pretty good evidence that you have experience thinking like a computer (although the fact that you found it significant/amusing is wonderfully human).
Re: MOPT-01 - assumptions and spaces
by adrianh (Chancellor) on Dec 10, 2002 at 06:33 UTC

    ++. Nice intro.

    The first step in thinking clearly-like-a-programmer is to know what kind of space you're working with at any given time. The second step is to use tools that are appropriate to the space in question. Programmers who haven't figured out what kind of space they're working with can waste endless time one of two ways:

    Amen.

    It can help when writing interfaces to think about the information spaces involved and make sure that you support the operations necessary for that space, and only those operations.

    If your object has some internal state that forms a nominal information space (e.g. readable and/or writable), you know you need to provide an interface that allows existence/equivalence tests for that state (e.g. $foo->is_readable, $foo->is_writable).

    If you don't supply these tests explicitly (e.g. you return a bitmask) then you're offloading responsibities, and exposing implementation, to the user of your class. Often this will be a bad decision since the user can make mistakes, and you can change your implementation.

Re: MOPT-01 - assumptions and spaces
by talexb (Chancellor) on Dec 10, 2002 at 15:52 UTC
      • Programming is the art of thinking clearly, and
      • A computer programmer is a human who's learned to think like a computer.

    I would argue your points a little differently .. in order to become proficient at programming, one needs to be able to think clearly. And a computer programmer is a human who has learned to understand how computer software operates.

    As you already stated, a computer does not think -- therefore (being pedantic), a computer programmer can't think like a computer. What a programmer can do is understand how a computer will most likely do a task, and fit the solution to that process.

    And programmers don't have the monopoloy on clear thought. You need to be able to think clearly for lots of other jobs too. :) I would argue that creative thought helps during the software development process. For the same reason that ad agencies have a basketball court to blow off steam and trigger the creative process, Silicon Valley companies have foosball tables to achieve the same goal -- work through the creative process and come up with a great solution.

    I'm reminded of a PHB from a few jobs back -- he'd get really miffed if he saw me staring out the window, obviously deep in thought. He couldn't understand that thinking works best away from the keyboard. For some reason, upper management had decided someone with a Tourism degree from a community college was a great choice to run a software development project.

    Go figure.

    --t. alex
    but my friends call me T.

      As you already stated, a computer does not think -- therefore (being pedantic), a computer programmer can't think like a computer. What a programmer can do is understand how a computer will most likely do a task, and fit the solution to that process.

      A couple of people have called me on this one. I chose 'think like a computer' because it sounds better than 'has learned to simulate a computing machine mentally.'

      There's no "most likely" about it, though. A human can work out exactly what a computer will do for a given sequence of input, and should do so frequently. Maybe it would be better to say, a programmer is a human who can build (and run) a virtual computer in their mind.

      And I don't deny the need for creative human activities in programming at all.. mentally simulating a virtual computer is hard work. Imagine the physical effort of trying to move a welding torch in exactly the same path a robot would use.. no bumps, no jiggles, no wavering speeds. After half an hour of that, any human would want to go out and shoot hoops for a while.

        There's one thing missing in this. The "virtual computer" I'll make in my head for C, Pascal and even Perl will be totaly different than the one for Lisp, Scheme, ML or Haskel and that one will again be totaly different that the one for Prolog. And SQL basicaly adds another one.

        Each type of programming languages is based on a different computational model so your simulation has to be different as well. And what we need to do when programming is not to simulate what does the "actual" computer do, but what does our computation model do.

        What remains is the "thinking clearly", no matter what you use you have to consider all options, you have to know your border cases, you have to know exactly what /needs to happen|will be the result|must hold true/ in any circumstance.

        Jenda

Re: MOPT-01 - assumptions and spaces
by Anonymous Monk on Dec 10, 2002 at 06:13 UTC
    The tricky bit here is that we humans are the ones who assign the meaning.

    Careful. Some monks have liberal arts degrees and know enough about philosophy and linguistics to argue with you here.

    Humans inherit a vast, richly-connected set of associations between meanings just by being human.

    How so? Can you back this up? . . . Consider omitting statements like the ones above. It would strengthen your essay.

      How so? Can you back this up?

      Check out Rules and Representations by Noam Chomsky. One of his premises, for which he makes a fairly strong argument, is that at least some basic linguistic structures probably relate to human brain structure. He uses language acquisition in children as part of his backing.. the information set they're exposed to is unusually sparse for the amount of structure they pick up. IIRC, simulations with neural nets tend to support that premise. A raw neural net doesn't pick up language patterns nearly as quickly as a child does, but you can speed things up by 'predisposing' a net to certain types of patterns.

      It was a bit cavalier of me to include such a statement without going into detail, but at least I didn't pull it straight out of the air.

Re: MOPT-01 - assumptions and spaces
by dbp (Pilgrim) on Dec 10, 2002 at 21:14 UTC

    Great article. This post got me thinking a bit about how we operate here at Perl Monks. Some would consider this post OT, although not many, judging by its reputation. It would, on the other hand, probably be a "bad thing" if comp theory were to dominate the discussion, since this is a site about Perl. Nonetheless, it is very useful to look at the big picture when Perl Monking.

    Relatively often, a new Perl programmer asks a question about a piece of code that suffers from a serious lack of computational understanding. The typical result is that we correct the poster's error, and she learns that doing what she did was not one of the right ways to do it. But we correct the person by saying, "how about this" or "I'd do it like this" or "Why not this way" and then posting code. The poster may have learned something, but she probably hasn't gotten the big picture.

    When someone asks a question that is purely Perl, we should answer in Perl; but when someone is missing a point that holds true in all languages (perhaps space or time mismanagement) we should take a moment to fill them in on the theoretical considerations, if only minimally, and provide some references for further study. Not that I'm necessarily planning to take the trouble to do this every time a post like this comes up, but I should. If everyone does it from time to time, we'll encourage people to become better programmers and help Perl by making Perl coders more skilled. Just my little rant.

    --Dan
Re: MOPT-01 - assumptions and spaces
by DapperDan (Pilgrim) on Dec 10, 2002 at 10:45 UTC
    ++, interesting post. I like your writing, and look forward to your future meditations in this series.

    If I want to dig deeper on the topic of 'information spaces', is there any material (on- or off-line) you can recommend?

      Whew..

      I'm afraid you'd have to spend a bunch of time digging through math textbooks, starting with algebra-the-theoretical-subject (as opposed to what most of us sat through in 7th grade). Dig around for information on 'ring' and 'group' theory, then just keep reading the same things over and over until it all starts to sink in.

      Broadly speaking, a space is a set of entities that support some kind of operation. the type of operation defines the type of space. Officially, a rational space is one that supports an 'algebra': a commutative operation known as 'addition' and a 'multiplication' operation that's transitive across addition. And just for the record, there are about a zillion other kinds of spaces that I didn't mention (like Banach spaces), because the operations in question don't have any immediate connection to programming.

        algebra-the-theoretical-subject (as opposed to what most of us sat through in 7th grade)

        Important distinction. :)

        I am currently reading a book called "Mathematics: The Science of Patterns" by Keith Devlin (amazon) and starting to open my mind up to mathematics beyond the high-school learning-by-rote level.

        I imagine it would be interesting to have a closer look at what one can learn about programming by studying algebra. Thanks for the pointers anyhow.

Re: MOPT-01 - assumptions and spaces
by Ctrl-z (Friar) on Dec 10, 2002 at 19:17 UTC
    great post. Thankyou for taking the time to share this kind of stuff.

    I find it frustrating there is no '(Intoduction to) Computer Science with Perl' type books. There seems to be many people, myself included, stuck somewhere between CGI-101, the Camel/Perldocs and 'purer' academic concepts.
    Odd, considering the nature of Perl as a language?

    looking forward to the next one!

    edit: Well, whadayaknow!
    Computer Science & Perl Programming, released last month.

      Odd, considering the nature of Perl as a language?

      Not really.. Perl is a high-level language, and high-level languages don't spend much time making the underlying theory visible. Pretty much the opposite, in fact.

      High-level languages make the things programmers are most likely to do as easy to do as possible. If that means hiding a vast amount of complexity under the rug, so much the better.

      In terms of programming theory, the statement:

      $x++;

      is one of the most complicated things you can do. I'll explain why in future posts, but we have a hell of a lot of territory to cover before we get to a machine sophisticated enough to implement that command.

      Nobody wants to do that much work every time they need to increment a counter. We just want to say, "make $x bigger" and let the machine work out all the gory details. And that's what high-level languages are for.

Re: MOPT-01 - assumptions and spaces
by toma (Vicar) on Dec 14, 2002 at 05:12 UTC
    Excellent post, I would like to see more of this type of analysis here.

    I'll try to keep in a positive spirit and offer a few suggestions.

    There are seven basic kinds of information spaces

    Lest anyone get bored with having only seven information spaces, there are plenty more to explore. For example, there is Quaternions and Rotation Sequences: A Primer with Applications to Orbits, Aerospace and Virtual Reality which describes a four dimensional complex space.

    I enjoyed reading Flatterland for an entertaining tour of many geometric spaces.

    Or is there some sort of proof that all spaces can be categorized into one of seven types of information spaces?

    Technically, computers can't handle irrational spaces at all.

    Languages like Macsyma handle irrational numbers nicely. The MACSYMA program:

    integrate(sin(x)*exp(x^2),x)

    returns
    1/4 2 %I x + 1 2 %I x - 1 %E SQRT(%PI) (ERF(----------) - ERF(----------)) 2 2 --------------------------------------------------- 4

    which seems like a reasonable way to handle the irrationals.

    Update: I forgot about numeric mode in MACSYMA, it does both numeric and algebraic. As far as algebraic versus numeric, it's all just LISP as far as I know, which does both relatively efficiently.

    integrate(sin(x)*exp(x^2),x,0,1)

    1/4 2 %I + 1 2 %I - 1 1/4 + 1 %E SQRT(%PI) (ERF(--------) - ERF(--------)) %E SQRT(%PI) + ERF(-) 2 2 + 2 ----------------------------------------------- - ------------------- +--- 4 2

    End of update

    It would be useful also to name a few modules that work in these different spaces, especially the builtin modules that fill the gaps where there are no appropriate keywords. For example, date operations are available in POSIX support the interval space, and complex space is supported in Math::Complex.

    Thanks for the post! It has inspired me to go try out Math::Calc::Units.

    It should work perfectly the first time! - toma

      Or is there some sort of proof that all spaces can be categorized into one of seven types of information spaces?

      Hardly.. we haven't even touched things like modular spaces, yet.

      Don't put too much weight on anything I say as a complete and accurate statement of mathematical truth. I'm chopping things up like mad, to keep from overloading everyday humans with the kinds of details necessary to be mathematical rigorous. At the same time, I'm trying not to stray too far from what a real mathemetician would be willing to accept in casual conversation.

      Languages like Macsyma handle irrational numbers nicely.

      Hmm.. interesting.

      Personally, I'd call that an algebraic package rather than a numerical package per se, but that's really not a point I'd want to argue in any detail. You're right that the formula in question does represent a whole set of irrationals, which just goes to show that you can change the ground rules completely by changing your basic assumptions. ;-)

        Don't put too much weight on anything I say as a complete and accurate statement of mathematical truth.

        I think it would be better to at least attempt to make sure that your statements are correct, even if they finesse rigor or completeness. If there are statements that are just flat wrong, it would be better to fix them somehow. Otherwise, the meditation is in danger of being only psychobabble, and unworthy of being corrected by those here who know better.

        It should work perfectly the first time! - toma

Re: MOPT-01 - assumptions and spaces
by t'mo (Pilgrim) on Dec 10, 2002 at 23:57 UTC
    As an aside, I've spent a fair amount of time watching other programmers work, and have read lots of code. When I'm in an especially nasty mood, I'll tell you that most coders don't actually program, they just act as the selection function in a very slow genetic algorithm that evolves a set of rules around a desired set of features

    Amen!

Re: MOPT-01 - assumptions and spaces
by BronzeWing (Monk) on Dec 12, 2002 at 20:39 UTC

    Great post!

    I'm curious about that aside though.

    they just act as the selection function in a very slow genetic algorithm that evolves a set of rules around a desired set of features

    I thought that was what programming was about, taking the computer's way of processing and applying it to what you want done. I'm self-taught, so maybe I missed something really big in the course of my learning? Could you clarify that part for a poor confused monk? Thanks.

    -BronzeWing


    Perl Monks do it more than one way.

      When you use genetic algorithms, you don't 'plan' anything. You start with a large set of random code sequences, and test them to see which ones come closest to the answer you want. Then you throw away all but, say, the best 1% of the set, and build a new large set out of random permutations of those survivors. After a few hundred passes through the loop, you end up with code that performs the desired function--often surprisingly well--but whose workings are almost always incomprehensible to the human mind.

      The best analogy I've seen for genetic algorithms is: "teaching monkeys to drive a bus by putting each one behind the wheel for five minutes, then breeding a new tribe from the two who make the bus move the farthest."

      Genetic-style coders have practices like 'shotgun debugging': changing parts of the code more or less at random, then running the program again to see if the bug went away. It works.. sometimes.. unless it screws up the code so completely that you have to go back and rewrite everything from scratch. But in those cases where it does work, the resulting code usually ends up so badly organized that no one ever wants to touch it again.

      Whenever you hear someone say, "yeah, that program sucks, but we don't dare change it," you're in the presence of code that's evolved randomly, rather than being planned.

      Programmers, OTOH, start by doing a whole lot of bookkeeping to figure out exactly what is the program supposed to do.. and I don't mean just "crunch numbers." You have to have a good, solid answer for at least the following questions:

      • What are the inputs and outputs?
      • Where do the inputs come from?
      • Where do the outputs go?
      • What are the acceptable values for the inputs and outputs, and what values are forbidden?
      • How do we guarantee that every input and output meets its validity constraints?
      • What does the program do if it finds a forbidden value?
      • What algorithm will we use to turn the inputs into outputs?
      • How do we guarantee that the algorithm always generates correct values, and always terminates in a reasonable amount of time?

      and for any real project, you'll find more.

      If you really have everything squared away, you can write a mathematical proof that shows your program will always Do The Right Thing.

      Professor Donald E. Knuth is one of the great-granddaddies of "knowing what you're doing"-style programming, and is credited with having sent someone a piece of code with a note saying, "Beware of bugs in the above code; I have only proved it correct, not tried it.'" Just for reference, Knuth is also the creator of TeX, a typesetting language that dominates much of the professional print industry. The version number of TeX increases by one digit of Pi every time someone finds, and Knuth fixes, a bug. The current version number of TeX is 3.14159, which ain't bad for a program that's been in professional use since the late 70s. As far as anyone knows, the last bug in TeX was found and removed on November 27, 1985.

      That's programming. ;-)

        Okay, I get it now... I guess that puts me somewhere just past shotgun debugging but not quite at planning ahead. At least now I know I have lots of room for improvement *grin*. Thanks for the explanation!

        -BronzeWing


        Perl Monks do it more than one way.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://218729]
Approved by rob_au
Front-paged by mjeaton
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (6)
As of 2024-03-19 14:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found