Close

In Praise of INTERCAL

A project log for JADE: Not Just Another DOOM Engine

Jade is not just another DOOM engine, because right now, JADE doesn't even play DOOM. But maybe someday, it will on an FPGA or "NOR machine"

glgormanglgorman 12/18/2025 at 05:000 Comments

INTERCAL is a programming language that I know almost nothing about, other than that I have read some things online about it being a joke or parody language from the 60's or perhaps 70's, or whenever, that I now think should perhaps be taken a bit more seriously,  Right now the only thing that I can remember about INTERCAL is that (I think) that INTERCAL is a BASIC or FORTRAN like language that has some weird requirements, like the requirement that every INTERCAL program must contain exactly four or five PLEASE statements.  So maybe an INTERCAL variant of BASIC, if such a thing could exist, might look like this:

10 PRINT "Hello World"
20 FOR X=1 TO 10
30 PLEASE PRINT X
35 PLEASE LET Y = X*X
40 NEXT X
50 PLEASE GOTO 100
60 PLEASE PRINT "Error - Goto Failure"
70 PRINT "Thanks for Playing"
80 WHEN "The Sun comes up", DISPENSE "Cat Food"
100 PLEASE END
 

It is easy to see that in this proposed version of INTERCAL BASIC, the requirement that there be exactly four, or five PLEASE statements is satisfied, so hopefully the interpreter or compiler won't issue an error that the program is too rude or too sycophantic.  So, one way to implement a version of INTECAL BASIC would be to have a preprocessor that checks for the required number of PLEASE statements, while possibly emitting a "Feature not supported" warning, with respect to the otherwise unreachable WHEN statement.  This, of course, could get messy, very messy, very fast.  Like what if in some version of INTERCAL the PLEASE statement does nothing, and the statement following the PLEASE statement simply executes as if the PLEASE statement were not there.  

Yet, then again, what if PLEASE statements in BASIC programs could be used to tell the interpreter or compiler that the program should attempt to launch a separate execution thread for the statement that follows the PLEASE statement? Now, things could get very interesting if all of the needed locks, semaphores, signals, or event handles could be taken care of automatically.  Then some operations, such as I/O, might be handled asynchronously, with any needed FIFOs, message queues, or other ways of storing intermediate values of various calculations queued up and processed accordingly.

Yet what would that imply with respect to how to interpret statements like PLEASE GOTO, or PLEASE END?  Perhaps a PLEASE GOTO might imply that the runtime should fork a copy of the currently running application, which on a system that has virtual memory with copy only upon modify semantics, might actually be able to be implemented with fairly good efficiency.  Thus, the currently running copy might be suspended before the branch is taken, and a forked copy might take over at the branch target, in effect taking a snapshot of all currently active variables, along with an appropriate time stamp, in effect creating an execution checkpoint, which might then turn out to be useful for such things as implementing transactional, or "journaling" file systems, with or without certain features such as "commit" or "roll back", as needed.  Yes, this is a VERY tricky problem, indeed.  Thus, it is also easy to see that INTERCAL's already included FORGET statement might come in useful.  Yet, like I said, VERY messy indeed.

Then there is the lack of a usable WHEN statement in most, if not all, programming languages that I know of, which is another matter that I will have something more to say about, that is to say, when I get around to it.

Now obviously, if you look up the Wikipedia article on INTERCAL, you will see that my proposed version of INTERCAL BASIC is substantially different from the original INTERCAL, being similar only in the use of the PLEASE statement, along with my very own new and improved proposed WHEN statement.  Thus, I could perhaps make INTERCAL BASIC more INTERCAL-like by making use of READ IN and WRITE OUT, for example, instead of INPUT and PRINT, like this:

10  WRITE OUT "Hello World"
20 FOR X=1 TO 10
30 PLEASE WRITE OUT X
35 PLEASE LET Y = X*X
40 TAKE IT TO THE TOP
50 PLEASE GOTO 100
60 PLEASE WRITE OUT "Error - Goto Failure"
70 WRITE OUT "Thanks for Playing"
80 WHEN "The Sun comes up", DISPENSE "Cat Food"
100 PLEASE END

The astute reader will notice that I mixed in a little bit of ROCKSTAR into the code.  Yet, maybe, just maybe, this is the direction where things might be headed.  Imagine using AI to create hybrid programming languages upon mere whim, some of which might have 1000's of well-defined keywords, or idioms, according the the needs of the application developer.  Consider this lovely quotation from "DR. JOHNSON'S ORIGINAL FOLIO EDITION, AND HIS GRAMMAR OF THE ENGLISH LANGUAGE.1812." which is available in public domain form from the Guttenberg library.

The agent, or person acting, is denoted by the syllable er added to the
verb, as lover, frighter, striker.

Substantives, adjectives, and sometimes other parts of speech, are changed
into verbs: in which case the vowel is often lengthened, or the consonant
softened; as, a house, to house; brass, to braze; glass, to glaze; grass,
to graze; price, to prize; breath, to breathe; a fish, to fish; oil, to
oil; further, to further; forward, to forward; hinder, to hinder.

Sometimes the termination en is added, especially to adjectives; as, haste,
to hasten; length, to lengthen; strength, to strengthen; short, to shorten;
fast, to fasten; white, to whiten; black, to blacken; hard, to harden;
soft, to soften.

From substantives are formed adjectives of plenty, by adding the
termination y: as a louse, lousy; wealth, wealthy; health, healthy; might,
mighty; worth, worthy; wit, witty; lust, lusty; water, watery, earth,
earthy; wood, (a wood) woody; air, airy; a heart, hearty; a hand, handy.

From substantives are formed adjectives of plenty, by adding the
termination ful, denoting abundance; as, joy, joyful; fruit, fruitful;
youth, youthful; care, careful; use, useful; delight, delightful; plenty,
plentiful; help, helpful.

Sometimes in almost the same sense, but with some kind of diminution
thereof, the termination some is added, denoting something, or in some
degree; as delight, delightsome; game, gamesome; irk, irksome; burden,
burdensome; trouble, troublesome; light, lightsome; hand, handsome; alone,
lonesome; toil, toilsome.

O.K. then, what if there are what seems like an endless list of rules for forming verbs from nouns, or nouns from verbs, adverbs from adjectives, and so on, even while we should be mindful of the fact that usually nouns are most likely to be associated with objects in OOP, while verbs are more likely to be associated with method calls, even as far back as the Apollo Guidance Computer, even then, back in the day, in its very own, properly functional, howbeit arcane fashion.

So I think that there is definitely something to be said about ad-hoc programming languages having an important place in an increasingly AI-driven landscape.  Yet I feel I must point out something from an earlier project, that always comes to mind, especially when I am given to consider the implications of the theory of so-called context-free grammars, and that is this partially sucessful effort to create a find called "pascal.h" that in theory would allow any sufficiently capable C/C++ pre-processor to chow down on PASCAL programs, or at least the occasional inclusion of some PASCAL code within a C/C++ function, by performing all needed conversions at compile time.

#define {            /*
#define }            */
#define PROCUEDURE    void
#define BEGIN        {
#define END          }
#define :=       ASSIGN_EQ
#define =        COMPARE_EQ
#define IF            if (
#define ASSIGN_EQ     =
#define COMPARE_EQ    ==
#define THEN        )
#define REPEAT        do {
#define UNTIL        } UNTIL_CAPTURE
#define UNTIL_CAPTURE    (!\
#define ;            );\
#undef            UNTIL_CAPTURE
#define ;           );
#define = [        = SET(\
#define ]        )\
#define )        \
#undef    =        [\
#undef    ]
// so far so good ....
#define WITH        ????????

Thus, hopefully, the reader understands the idea of there being an equivalence class that exists between the general theory of context-free grammars, and how the #define statement works in the C/C++ preprocessor, then hopefully it will be just as clear that whenever we need some "contextuality" inside a context-free grammar, we can create it, and un-create it as needed, as I am suggesting here as for one way to try to capture the conditional part of a PASCAL style REPEAT ... UNTIL statement, and turn into a functionally equivalent C/C++ style do ... while statement.

Quite simply put, therefore, the C/C++ preprocessor just hasn't been getting enough abuse lately, so there, at least for now.  Enjoy the chaos.  Even if this project, at least for now, still does nothing.

Discussions