# INTERCAL

INTERCAL est une parodie de langage de programmation, et la référence canonique des langages de programmation exotiques. Ce langage a été créé par Don Woods et James M. Lyon (ru), deux étudiants de l'Université de Princeton, en 1972. Il tourne en dérision certains aspects des langages de programmation de l'époque, ainsi que la prolifération des propositions de construction de langage et de notation dans les années 1960. En conséquence, son humour peut paraître plutôt désuet pour des lecteurs modernes ayant grandi avec le C ou le Java.
Selon le manuel original des auteurs :
   « Le nom complet du compilateur est « Langage compilé n'ayant aucun acronyme prononçable », ce que, pour d'évidentes raisons, nous abrégerons en « INTERCAL ». »
Il existe actuellement deux versions maintenues d'INTERCAL : C-INTERCAL (maintenu par Eric S. Raymond), et CLC-INTERCAL (maintenu par Claudio Calvelli).

## Introduction

INTERCAL a pour vocation d'être complètement différent de tout autre langage informatique. Les opérations courantes dans d'autres langages ont une syntaxe cryptique et redondante en INTERCAL. D'après le Manuel de Référence d'INTERCAL :
   « C'est un fait bien connu et amplement démontré qu'une personne dont le travail est incompréhensible est tenue en haute estime. Par exemple, si quelqu'un devait affirmer que la manière la plus simple de stocker la valeur 65536 dans une variable 32-bit en INTERCAL est :
   n'importe quel programmeur intelligent dirait que c'est absurde. Comme il s'agit effectivement de la méthode la plus simple, ce programmeur prendrait instantanément un air ahuri devant son responsable, qui aurait eu de toute évidence la bonne idée d'apparaître à ce moment-là, comme les responsables ont l'habitude de le faire. L'effet n'en serait pas moins radical pour le programmeur ayant eu raison. »
Le Manuel de Référence d'INTERCAL contient de nombreuses instructions paradoxales, insensées, ou autrement humoristiques (à la manière du jeu Kamoulox) :
   « Attention ! Ne confondez en aucune circonstance la grille avec l'opérateur d'interpolation, excepté en cas de circonstances pouvant porter à confusion ! »
Le manuel contient également une « amygdale », comme expliqué dans cette note de bas de page : « 4) Comme tous les autres manuels de référence ont des annexes (appendices en anglais), il a été décidé que le manuel d'INTERCAL devrait contenir un autre type d'organe retirable. »
INTERCAL possède de nombreuses autres fonctionnalités prévues pour le rendre encore plus esthétiquement déplaisant au programmeur : il utilise des impératifs comme "READ OUT" (« lit à voix haute »), "IGNORE", "FORGET" (« oublie »), et des modificateurs comme "PLEASE" (« s'il te plaît »). Ce dernier mot-clé fournit deux raisons au compilateur pour rejeter le programme : si "PLEASE" n'apparaît pas assez souvent, le programme est considéré comme insuffisamment poli, et le message d'erreur en fait part ; s'il apparaît trop souvent, le programme peut être rejeté pour cause d'obséquiosité. Bien que cette fonctionnalité existât dans le compilateur INTERCAL d'origine, elle n'était pas documentée.
Le manuel d'INTERCAL donne des noms volontairement ridicules à tous les caractères ASCII non alphanumériques (à l'exception de l'esperluette, qui garde son nom anglais « ampersand » car, comme l'affirme le Jargon File, « que pourrait-il bien exister de plus idiot ? ») : les apostrophes et les guillemets sont des « étincelles » et des « oreilles de lapin » respectivement. L'opérateur d'assignation, représenté par un signe d'égalité (une « demi-grille » selon INTERCAL) dans de nombreux autres langages de programmation, est en INTERCAL une flèche gauche, « ← », à laquelle on se réfère sous le nom de « reçoit », et est faite avec un « angle » et un « ver ».
L'implémentation originelle de Princeton utilisait des cartes perforées et le jeu de caractères EBCDIC. Afin de permettre à INTERCAL de fonctionner sur des ordinateurs utilisant l'ASCII, des substitutions durent être faites sur deux caractères : $ remplaça ¢ en tant qu'opérateur MINGLE (« mélanger »), lequel « représente le coût croissant du logiciel comparativement au matériel », et ? remplaça ∀ comme opérateur ou exclusif unaire pour « exprimer correctement la réaction de l'individu moyen lors de sa première rencontre avec un ou exclusif unaire ». Dans les versions récentes de C-INTERCAL, les anciens opérateurs sont supportés en tant qu'alternatives ; et les programmes INTERCAL peuvent maintenant être encodés en ASCII, Latin-1, ou UTF-8.
Le groupe de discussion Usenet alt.lang.intercal est voué à l'étude et à l'appréciation d'INTERCAL avec d'autres langages ésotériques.
Bien que le langage soit intentionnellement obtus et bavard, INTERCAL est néanmoins Turing-complet : pour peu qu'il dispose d'assez de mémoire, INTERCAL peut résoudre n'importe quel problème qu'une machine de Turing universelle puisse résoudre. La plupart des implémentations d'INTERCAL le font très lentement. Un test de performance basé sur un crible d'Eratosthène, calculant tous les nombres premiers inférieurs à 65536, a été évalué sur un ordinateur Sun SPARCStation-1 (en). En C, il fallut moins d'une demi-seconde ; le même programme en INTERCAL prit un peu plus de dix-sept heures.
Il convient de noter que de nombreux langages de programmation permettent d'écrire du code abscons, comme le démontre entre autres l'International Obfuscated C Code Contest. Cependant, il s'agit généralement d'efforts intentionnels pour coder de manière illisible ce qui pourrait l'être de manière claire. Au contraire, la conception d'INTERCAL force quasiment tout code à être illisible.
Selon le manuel d'INTERCAL, « l'objectif en concevant INTERCAL était de n'avoir aucun antécédent », à supposer ni en fonctionnalités de contrôle de flux, ni en opérateurs de manipulation de données. Les concepteurs ont presque réussi ; le seul antécédent connu est une instruction machine dans un ordinateur central BESM-6 (en) soviétique, sorti en 1967, et qui est effectivement équivalente à l'opérateur SELECT d'INTERCAL.

## Dialectes

L'INTERCAL Woods–Lyon original était très limité dans ses capacités d'entrée/sortie : les seules entrées acceptables étaient des nombres épelés en toutes lettres, et la seule sortie possible était une version étendue des chiffres romains. Un peu plus tard, il y eut une 'implémentation Atari', au sujet de laquelle des notes sont fournies dans le manuel de référence d'INTERCAL ; elle « diffère de la version originelle de Princeton principalement dans l'utilisation de l'ASCII plutôt que de l'EBCDIC ».
La réimplémentation C-INTERCAL, disponible sur Internet, a rendu le langage plus populaire parmi les dévots de la programmation ésotérique. Le dialecte C-INTERCAL possède quelques différences par-rapport à l'INTERCAL original et introduit quelques nouvelles fonctionnalités, comme une commande COME FROM (« arrive de ») et un moyen de réaliser de l'E/S de texte basé sur le Modèle de Texte de Turing.
Les auteurs du C-INTERCAL ont également créé la variante TriINTERCAL, basée sur le système trinaire et en généralisant les jeux d'opérateurs d'INTERCAL.
Une variante plus récente est Threaded Intercal, qui étend la fonctionnalité de COME FROM pour supporter le multithreading.

## Syntaxe
### Structures de données

INTERCAL-72 (la version originale d'INTERCAL) connaissait seulement quatre types, l'entier 16-bit (représenté par un ., appelé un 'spot'), l'entier 32 bits (:, un 'double-spot'), le tableau d'entiers 16 bits (,, une 'queue'), et le tableau d'entiers 32 bits (;, un 'hybride'). Il y a 65 535 variables disponibles de chaque type, numérotées de .1 à .65535 pour les entiers 16 bits, en l'occurrence. Néanmoins, chacune de ces variables a sa propre pile sur laquelle elle peut être poussée ou reprise (STASHée et RETRIEVée, en terminologie INTERCAL), augmentant la possible complexité des structures de données (les versions plus modernes d'INTERCAL ont dans les grandes lignes conservé les mêmes structures de données, avec des modifications appropriées ; TriINTERCAL, qui modifie la base avec laquelle les nombres sont représentés, peut utiliser un type 10 trits plutôt qu'un type 16 bits, et le CLC-INTERCAL implémente nombre de ses propres structures de données, comme les 'classes et conférences', en faisant stocker plus d'information aux types de données de base plutôt que d'ajouter de nouveaux types). Les tableaux sont dimensionnés en leur assignant un nombre comme s'ils étaient un type scalaire. Des constantes peuvent aussi être utilisées, et sont représentées par une # ('grille') suivie de la constante elle-même, écrite sous forme d'un nombre décimal ; seules les constantes entières de 0 à 65535 sont supportées.

### Opérateurs

Il y a seulement cinq opérateurs en INTERCAL-72 ; les implémentations diffèrent selon quel caractère représente quelle opération, et beaucoup acceptent plus d'un caractère, c'est pourquoi plus d'une possibilité est donnée pour de nombreux opérateurs.
Source de cette table$^,$$^,$ :
| Opérateur | caractères INTERCAL-72 | caractères Atari | caractères C-INTERCAL | caractères CLC-INTERCAL |
| INTERLEAVE (« intercaler ») / MINGLE (« mélanger ») | c retour arrière / | $ | ¢, $, c retour arrière / | ¢ |
| SELECT (« sélectionner ») | ~ | ~ | ~ | ~ |
| AND (« et ») | & | & | & | & |
| OR (« ou ») | V | V | V | V |
| XOR (« ou exclusif ») | V retour arrière - | ? | V retour arrière -, ?, ? | V retour arrière -, ¥ |
Contrairement à la plupart des autres langages, les opérateurs AND, OR, et XOR sont des opérateurs unaires, qui fonctionnent sur les bits consécutifs de leur argument ; le bit de poids fort du résultat est l'opérateur appliqué aux bit de poids fort et bit de poids faible de l'entrée, le second bit de poids fort du résultat est l'opérateur appliqué au premier et second bit de poids fort, le troisième bit de poids fort du résultat est l'opérateur appliqué au second et troisième bit de poids fort, et ainsi de suite. L'opérateur est placé entre le signe de ponctuation qui spécifie un nom de variable ou une constante et le nombre qui spécifie de quelle variable il s'agit, ou simplement à l'intérieur de marqueurs de regroupement (c'est-à-dire un caractère plus loin qu'il le serait dans des langages de programmation comme le C). SELECT et INTERLEAVE (également connu sous le nom de MINGLE) sont des opérateurs binaires infixes ; SELECT prend les bits de sa première opérande qui correspondent aux bits à '1' de sa seconde opérande et supprime les bits qui correspondent à '0', décalant vers le bit de poids faible et remplissant avec des zéros (ainsi 51 (110011 en binaire) SELECT 21 (10101 en binaire) donne 5 (101 en binaire)) ; MINGLE alterne les bits de sa première et seconde opérande (de telle manière que le bit de poids faible de la seconde opérande soit le bit de poids faible du résultat). Il n'y a pas de précédence des opérateurs ; des marqueurs de regroupement doivent être utilisés pour expliciter la priorité dans les cas où elle serait ambigüe (les marqueurs de regroupement disponibles sont ' ('étincelle') qui est à mettre en rapport avec une autre étincelle, et " ('oreilles de lapin') qui est à mettre en rapport avec d'autres oreilles de lapin ; le programmeur de l'utilisation de celles-ci de telle manière qu'elles rendent l'expression non ambigüe).

### Structures de contrôle

Les commandes en INTERCAL commencent toutes par un 'identificateur de commande' ; en INTERCAL-72, ceci peut être DO, PLEASE, ou PLEASE DO, chacun desquels ayant la même signification en ce qui concerne le programme (mais l'utilisation de l'un d'entre eux en excès provoque le rejet du programme, une fonctionnalité non documentée d'INTERCAL-72 qui fut mentionnée dans le manuel du C-INTERCAL), ou bien par une forme inversée (avec NOT ou N'T ajouté à l'identificateur). Backtracking INTERCAL, une variante moderne, autorise également des variantes comme MAYBE (« peut-être », qui peut être combiné avec PLEASE ou DO) en tant qu'identificateurs de commande, ce qui introduit la notion de hasard. Avant l'identificateur, un numéro de ligne optionnel peut être donné (un entier encadré par des parenthèses) ; après l'identificateur, un pourcentage de chance que la ligne soit exécutée peut être donné au format %50, lequel prend par défaut la valeur 100 %.
En INTERCAL-72, les structures de contrôle principales sont NEXT (« suivant »), RESUME (« reprend »), et FORGET (« oublie »). DO (ligne) NEXT branche le programme à la ligne indiquée, en se souvenant de la ligne suivante qui aurait été exécutée s'il n'y avait pas eu ce NEXT sur la pile d'appel (d'autres identificateurs que DO peuvent être utilisés sur n'importe quelle commande, DO est simplement donné ici comme exemple) ; DO FORGET expression supprime les entrées égales à expression du haut de la pile d'appel (ceci est utile pour éviter l'erreur qui survient autrement lorsqu'il y a plus de 80 entrées), et DO RESUME expression supprime les entrées expression de la pile d'appel et branche le programme à la dernière ligne mémorisée.
C-INTERCAL fournit aussi l'instruction COME FROM, qui s'écrit DO COME FROM (ligne) ; le CLC-INTERCAL et les versions les plus récentes du C-INTERCAL fournissent également des versions calculatoires de COME FROM (DO COME FROM expression) et NEXT FROM, qui fonctionne comme COME FROM mais sauvegarde également une adresse de retour sur la PROCHAINE pile.
Des moyens alternatifs d'affecter le flux du programme, disponibles à l'origine en INTERCAL-72, sont d'utiliser les instructions IGNORE et REMEMBER (« souviens-toi ») sur des variables (ce qui permet que les écritures sur cette variable soient discrètement ignorées puis reprennent effet, de sorte que des instructions puissent être désactivées), et les instructions ABSTAIN (« abstiens-toi ») et REINSTATE (« réhabilite ») sur des lignes ou sur des types de commande, ce qui désactive la ligne ou la réactive respectivement.

### Divers

L'entrée (qui utilise l'instruction WRITE IN) et la sortie (qui utilise l'instruction READ OUT) n'emploient pas le format habituel ; en INTERCAL-72, WRITE IN gère l'entrée d'un nombre écrit en toutes lettres en langue anglaise (comme SIX FIVE FIVE THREE FIVE), et READ OUT l'imprime en chiffres romains. Les versions plus récentes ont leur propre système d'E/S$^,$. Les commentaires peuvent être réalisés en utilisant les inverseurs d'identificateur de commande NOT ou N'T ; ceux-ci provoquent l'abstention d'exécution (ABSTAIN) de ces lignes de sorte qu'elles n'ont pas d'effet (une ligne peut être en abstention même si elle ne possède pas une syntaxe valide ; les erreurs de syntaxe surviennent à l'exécution, et seulement à ce moment-là quand la ligne n'est pas en abstention).

## Hello, world

Le programme "Hello, world!" traditionnel démontre combien INTERCAL est différent des langages de programmation standard. En C, il ressemble à ceci :
Le programme équivalent en C-INTERCAL est plus long et plus difficile à lire :
En INTERCAL-72, le programme équivalent n'est pas possible étant donné que cette version du langage ne peut produire de sortie qu'en chiffres romains.

## Abandonnez toute santé mentale

Dans l'article « A Box, Darkly: Obfuscation, Weird Languages, and Code Aesthetics », INTERCAL est décrit sous le titre « Abandonnez toute santé d'esprit, vous qui entrez ici : INTERCAL ». Le compilateur et la stratégie de commentaire sont parmi les fonctionnalités « étranges » décrites :
   « Le compilateur, adéquatement nommé « ick », continue la parodie. Tout ce que le compilateur ne peut pas comprendre, ce qui dans un langage de compilation normal résulterait en une erreur de compilation, est simplement ignoré. Cette fonctionnalité de "pardon" rend le fait de trouver des bogues très difficile ; elle introduit aussi un système unique d'ajout de commentaires de programme. Le programmeur n'a en gros qu'à insérer du texte non compilable n'importe où dans le programme, en faisant attention à ne pas inclure accidentellement une portion de code valide au milieu de son commentaire. »