INTERCAL

From Bauman National Library
This page was last modified on 1 June 2016, at 17:15.
INTERCAL
Paradigm esoteric
Designed by John Woods, James M. Lyon
First appeared 1972
License GNU General Public licence
Website INTERCAL
Influenced
Befunge, Brainfuck, Malbolge, Unlambda, LOLCODE
Don Woods in 2010
Jimbo Lyon in 2005

INTERCAL (abbr. The Compiler Language With No Pronounceable Acronym) - esoteric programming language created in 1972 by Don Woods and James Lyon as a joke-parody for many programming languages of that time. Despite it's so exotic language, INTERCAL is Turing-complete. It means that it can calculate everything than regular language does.

History

Language is Language standardized mainly by its first implementation, INTERCAL-72. More recent versions are trying to be compatible with this version. Most implementations bring to the language something different, whether it is an alternative format of input-output, or elements of quantum computing. Old features (for example, random errors or style error messages) are stored and carefully transferred to the new implementation.

Features

INTERCAL was intended to be completely different from all other computer languages. Common operations in other languages have cryptic and redundant syntax in INTERCAL. From the INTERCAL Reference Manual:

The simplest way to store a value of 65536 in a 32-bit INTERCAL variable is:

DO :1 <- #0¢#256

Any sensible programmer would say that that was absurd.

INTERCAL has many other features designed to make programming even more unpleasing to the programmer: it uses statements such as "READ OUT", "IGNORE", "FORGET", and modifiers such as "PLEASE". This last keyword does nothing, but if "PLEASE" does not appear often enough, the program is considered insufficiently polite, and the error message says this; if too often, the program could be rejected as excessively polite.

Despite the language's intentionally obtuse and wordy syntax, INTERCAL is nevertheless Turing-complete: given enough memory, INTERCAL can solve any problem that a Universal Turing machine can solve. Most implementations of INTERCAL do this very slowly, however. For example, counting all prime numbers from 0 to 65535 took 17 hours for INTERCAL program, when C program did it by 0.5 seconds.

Manual

Modern esoteric languages focus their strangeness in the very essence of language, and their manuals only consist of factual description of the commands and features. INTERCAL authors went the other way: the description of the programming language "The INTERCAL Programming Language Reference Manual" is filled with epigraphs from "Alice in Wonderland" and funny comments, said quite seriously. In addition, especially for the language authors have developed a system of euphemisms used for special characters: ' — spark, " — rabbit's ears, . — spot, : — double spot, , — tail, ; — hybrid, $ — big money, ~ — flourish and so on. 1.

Some quotes

  • Since it is an exceedingly easy language to learn, one might expect it would be a good language for initiating novice programmers. Perhaps surprising, than, is the fact that it would be more likely to initiate a novice into a search for another line of work.
  • INTERCAL recognizes 5 operators--2 binary and 3 unary. In a sense, all 5 operators are binary, as they are all bit-oriented, but it is not our purpose here to quibble about bits of trivia.
  • Precedence of operators is as follows: (rest of the page is empty. Language has no precedence).

Error messages

In usual languages error messages are informative and point to reasons of what happened. In INTERCAL they don't. Messages are to abstract, or give wrong info. Errors are very hard to understand without a dictionary:

  • E252 «I’VE FORGOTTEN WHAT I WAS ABOUT TO SAY» — This run-time error message is caused by the compiler running out of memory whilst trying to do I/O.
  • E182 «YOU MUST LIKE THIS LABEL A LOT!» — At present, it’s impossible to have more than one line with the same line number.
  • E405 «PROGRAM REJECTED FOR MENTAL HEALTH REASONS» Your program used a construct that only makes sense when multithreading or backtracking (WHILE, MAYBE, GO BACK, or GO AHEAD), but you didn’t specify the -m option.
  • E017 «DO YOU EXPECT ME TO FIGURE THIS OUT?» — This error occurs when there is an attempt to use a constant with a value outside the onespot range.
  • E127 «SAYING ’ABRACADABRA’ WITHOUT A MAGIC WAND WON’T DO YOU ANY GOOD» — Your program asked to include a system library.

Some error are specific only for INTERCAL:

  • E079 «PROGRAMMER IS INSUFFICIENTLY POLITE» and E099 «PROGRAMMER IS OVERLY POLITE» are occure when comand please is used to rarely or to often.
  • E774 «RANDOM COMPILER BUG» No compiler is perfect; sometimes errors just happen at random. Next compilation would not raise an error.
  • E995 «DO YOU REALLY EXPECT ME TO HAVE IMPLEMENTED THAT?» Some parts of the code haven’t been written yet.

Syntax

Input (using the WRITE IN instruction) and output (using the READ OUT instruction) do not use the usual formats; in INTERCAL-72, WRITE IN inputs a number written out as digits in English (such as SIX FIVE FIVE THREE FIVE), and READ OUT outputs it in "butchered" Roman numerals. More recent versions have their own I/O systems.

Comments can be achieved by using the inverted statement identifiers involving NOT or N'T; these cause lines to be initially ABSTAINed so that they have no effect. (A line can be ABSTAINed from even if it doesn't have valid syntax; syntax errors happen at runtime, and only then when the line is un-ABSTAINed.)

Data structures

INTERCAL-72 (the original version of INTERCAL) had only four data types: the 16-bit integer (represented with a ., called a "spot"), the 32-bit integer (:, a "twospot"), the array of 16-bit integers (,, a "tail"), and the array of 32-bit integers (;, a "hybrid").

There are 65535 available variables of each type, numbered from 1 to 65535. However, each of these variables has its own stack on which it can be pushed and popped (STASHed and RETRIEVEd, in INTERCAL terminology), increasing the possible complexity of data structures.

Arrays are dimensioned by assigning to them as if they were a scalar variable.

Constants can also be used, and are represented by a # ("mesh") followed by the constant itself, written as a decimal number; only integer constants from 0 to 65535 are supported.

Operators

There are only five operators in INTERCAL-72. Implementations vary in which characters represent which operation, and many accept more than one character, so more than one possibility is given for many of the operators.

INTERCAL operators
Operator INTERCAL-72 characters C-INTERCAL characters CLC-INTERCAL characters
INTERLEAVE / MINGLE c backspace / ¢, $, c backspace / ¢
SELECT ~ ~ ~
AND & & &
OR V V V
XOR V backspace - V backspace -, ?, V backspace -, ¥

Contrary to most other languages, AND, OR, and XOR are unary operators, which work on consecutive bits of their argument. The most significant bit of the result is the operator applied to the most significant and least significant bits of the input, the second-most-significant bit of the result is the operator applied to the most and second-most significant bits, the third-most-significant bit of the result is the operator applied to the second-most and third-most bits, and so on.

The operator is placed between the punctuation mark specifying a variable name or constant and the number that specifies which variable it is, or just inside grouping marks (i.e. one character later than it would be in programming languages like C.)

SELECT and INTERLEAVE (which is also known as MINGLE) are infix binary operators. SELECT takes the bits of its first operand that correspond to "1" bits of its second operand and removes the bits that correspond to "0" bits, shifting towards the least significant bit and padding with zeroes (so 51 (110011 in binary) SELECT 21 (10101 in binary) is 5 (101 in binary));

MINGLE alternates bits from its first and second operands (in such a way that the least significant bit of its second operand is the least significant bit of the result). There is no operator precedence; grouping marks must be used to disambiguate the precedence where it would otherwise be ambiguous (the grouping marks available are ' ("spark"), which matches another spark, and " ("rabbit ears"), which matches another rabbit ears; the programmer is responsible for using these in such a way that they make the expression unambiguous).

Control structures

INTERCAL statements all start with a "statement identifier"; in INTERCAL-72, this can be DO, PLEASE, or PLEASE DO, all of which mean the same to the program (but using one of these too heavily causes the program to be rejected) or an inverted form (with NOT or N'T appended to the identifier).

Before the identifier, an optional line number (an integer enclosed in parentheses) can be given; after the identifier, a percent chance of the line executing can be given in the format %50, which defaults to 100%.

In INTERCAL-72, the main control structures are NEXT, RESUME, and FORGET.

DO (line) NEXT branches to the line specified, remembering the next line that would be executed if it weren't for the NEXT on a call stack (other identifiers than DO can be used on any statement, DO is given as an example);

DO FORGET expression removes expression entries from the top of the call stack (this is useful to avoid the error that otherwise happens when there are more than 80 entries);

code>DO RESUME expression</code> removes expression entries from the call stack and jumps to the last line remembered.

C-INTERCAL also provides the COME FROM instruction, written DO COME FROM (line) and NEXT FROM, which is like COME FROM but also saves a return address on the NEXT STACK.

Alternative ways to affect program flow, originally available in INTERCAL-72, are to use the IGNORE and REMEMBER instructions on variables (which cause writes to the variable to be silently ignored and to take effect again, so that instructions can be disabled by causing them to have no effect), and the ABSTAIN and REINSTATE instructions on lines or on types of statement, causing the lines to have no effect or to have an effect again respectively.

Code examples

Traditional "Hello, world!" program demonstrates how much INTERCAL differs from regular programming languages.C version:

#include <stdio.h>

int main(void) {
    printf("Hello, world!\n");
    return 0; // _exit(0);
}

INTERCAL version is much longer and strange:

DO ,1 <- #13
PLEASE DO ,1 SUB #1 <- #238
DO ,1 SUB #2 <- #108
DO ,1 SUB #3 <- #112
DO ,1 SUB #4 <- #0
DO ,1 SUB #5 <- #64
DO ,1 SUB #6 <- #194
DO ,1 SUB #7 <- #48
PLEASE DO ,1 SUB #8 <- #22
DO ,1 SUB #9 <- #248
DO ,1 SUB #10 <- #168
DO ,1 SUB #11 <- #24
DO ,1 SUB #12 <- #16
DO ,1 SUB #13 <- #162
PLEASE READ OUT ,1
PLEASE GIVE UP

Program increments .1 variable:

(2000)	PLEASE DO STASH .1 + .2 + .3
	DO .2 <- #1
	DO (2001) NEXT
(2001)	PLEASE FORGET #1
	DO .3 <- "?!1~#1'$#1"~#3
	DO (2002) NEXT
	PLEASE DO .2 <- !2$#1'~'#65535$#1'
	DO .1 <- .1~#65534
	DO (2001) NEXT
(2002)	PLEASE DO (2003) NEXT
	DO RETRIEVE .1
	DO .3 <- .1
	PLEASE DO .1 <- '?.2$.3'~'#0$#65535'
	DO RETRIEVE .2 + .3
	DO RESUME #2
(2003)	DO RESUME .3

References