Mensen praten met elkaar in allerlei talen. Vaak hebben mensen dan ook moeilijkheden om elkaar te begrijpen, zelfs als ze dezelfde taal spreken. Soms drukken mensen zich niet helder genoeg uit, soms zijn zinnen op verschillende manieren uit te leggen. Natuurlijke talen zijn ook niet altijd even logisch. In het Engels is de uitspraak dat zeker niet. Een bekende vraag is hoe je `ghoti' uitspreekt. Welnu, de `gh' spreek je uit als in `laugh', de `o' als in `women', en de `ti' als in `nation': dus spreek je `ghoti' uit als `fish'.
Vertaalprogramma's hebben doorgaans de grootste moeite om zinnen te vertalen, vooral als het om vrij willekeurige teksten gaat. Het gaat beter als de zinnen uit een zeer specifiek domein, bijvoorbeeld de scheepsbouw, afkomstig zijn. Een vaak aangehaald voorbeeld is de automatische vertaling van de zin "the spirit is willing but the flesh is weak", die volgens de legende via het Russisch terug kwam als "the vodka is good but the meat is rotten". Van Groucho Marx is het citaat "Time flies like an arrow. Fruit flies like a banana. So just what ARE time flies, and why do they like an ARROW?".
Liefhebbers kunnen eens kijken bij http://babelfish.altavista.digital.com/ voor een werkend vertaalprogramma. Maar we zullen het hier niet over computerlinguïstiek hebben.
Eind vorige eeuw werden de eerste echte kunsttalen bedacht. In een
artikel in Onze Taal van april 1998 wordt de geschiedenis uit de doeken gedaan, zie:
http://www.onzetaal.nl/.
Bij de bedenkers waren mensen die de wereldvrede ermee dachten te
realiseren, maar ook lieden die talen als
Spokaans
of Klingon bedacht hebben - en spreken. Zamenhof construeerde
bijvoorbeeld de taal Esperanto, een voortzetting van het door Schleyer in
1879 bedachte Volapük. Ook al zijn er weinig native speakers van deze laatste
taal over, de naam blijft mooi gevonden - afgezien van het trema op de u.
In het midden van deze eeuw werd het van belang met computers te communiceren. Eerst moeizaam met rijtjes nullen en enen, later in eenvoudige assemblers, en nog weer later in talen als Fortran, Cobol, Algol, C en Pascal. Wat al deze `formele' talen gemeen hebben is hun eis voor duidelijkheid: een zin mag maar één ondubbelzinnige betekenis hebben. Iedereen kent foutmeldingen in de sfeer van `; vergeten' of `variabele onbekend'. Mensen snappen meteen wat de betreffende zin betekent, een computer wil meer formaliteit.
Je kunt programmeertalen op allerlei manieren onderscheiden. Zo kun je
er over discussiëren of Lisp een derde of vierde generatie taal is, of het maken
van een gebruikersinterface in Visual C++ nog wel iets met C++ van doen heeft of eigenlijk programmeren in een `visuele taal' is, en of functioneel
programmeren beter zou zijn dan imperatief
programmeren. Om dat laatste onderwerp aan te roeren: talen als C++ worden
vaak imperatief genoemd, immers de gebruiker geeft als het ware een serie
opdrachten die in zekere volgorde moeten worden uitgevoerd om het doel te bereiken. Daar tegenover staan zogeheten
functionele (of algemener declaratieve) talen als Lisp, Clean en Haskell, waarin eerder
de eigenschappen van functies worden beschreven, waarna het programma
zelf zijn weg zoekt naar de of een oplossing. Overigens zijn er ook nog logische talen als Prolog, waarin de logische
verbanden tussen variabelen voldoende zijn om de klus te klaren. In Prolog zit backtracking ingebakken, in plaats
van het uit C++ bekende één voor één
in volgorde uitvoeren van de statements. Eens gedane keuzes voor de
waardes van variabelen kunnen in een later stadium worden teruggenomen als blijkt dat ze toch nergens toe leidden.
Een andere eigenschap die programmeertalen kunnen hebben is of ze object-georiënteerd zijn. Zo kent C++ objecten en bijpassende methoden. Objecten zijn programma-eenheden die van een bepaalde blauwdruk, hun zogeheten klasse, afkomstig zijn. Zo zijn de lezers van dit stukje allemaal van de klasse mens. Allemaal hetzelfde, maar beslist ook zeer verschillend. Nu kun je met klassen allerlei prachtige dingen doen, waaronder van elkaar erven. Verder wordt van sommige functies pas tijdens het runnen van het programma duidelijk bij welk object ze precies horen: `late binding'; in traditionele talen ligt dit altijd van te voren al vast. De taal C++ is - enerzijds helaas - nogal sterk gebaseerd op het veel oudere C, waardoor niet altijd een even consequent object-georiënteerde taal verkregen is.
Iedere taal heeft zijn eigen eigenaardigheden. In de ene kun je het bekende `dames-op-schaakbord'-probleem in enkele regels programmeren (bijvoorbeeld omdat backtracking al ingebakken zit), in de andere kost het meer werk: zie het college Algoritmiek. Het `dames-op-schaakbord'-probleem vraagt om alle manieren om een n-tal dames op een n-bij-n-schaakbord te zetten, zodanig dat geen enkele dame een andere direct kan slaan. Zie voor referenties: http://www.liacs.nl/home/kosters/nqueens.html
Wat alle serieuze programmeertalen wel toelaten is het volgende. (Dat ze het overigens kunnen is een gevolg van een heel algemene stelling.) Gevraagd wordt een programma te schrijven dat zijn eigen programmatekst afdrukt op het beeldscherm. Daarbij zijn `flauwe' oplossingen in de sfeer van
herhaal lees letter uit programmatekst en schrijf deze naar scherm totdat klaarverboden: er mag niet verder uit een file worden gelezen of andere invoer gepleegd worden. In sommige talen blijft het echter flauw: in Basic voldoet het programma `LIST', in Lisp het programma `NIL'. Maar nu serieus. Een oplossing in een Pascal/C-achtige taal gaat ruwweg als volgt.
Laten we aannemen dat een commando als output ("tekst", x) de string "tekst" (zonder de aanhalingstekens) en de waarde van x op het beeldscherm zet. Als je ook aanhalingstekens wilt afdrukken moet je een conventie gebruiken, bijvoorbeeld dat een aanhalingsteken binnen een string wordt voorgesteld door twee aanhalingstekens direct na elkaar. Dus output("ab""cd""""ef") zet ab"cd""ef op het scherm; merk op dat de string intern ook zo wordt gerepresenteerd. Verder spreken we af dat een statement als x:="help" er voor zorgt dat de string x de waarde "help" krijgt, en bij x:=y krijgt x de waarde van y.
x:=";y:=x met elke "" veranderd in """";output(""x:="""""",y,"""""""",x);";
y:=x met elke " veranderd in "";
output("x:=""",y,"""",x);
Uiteraard moet dit nog preciezer, want er staan in het tweede statement nog te veel Nederlandse woorden (die je met behulp van functies kunt wegwerken), en verder moet je nog met regelovergangen en een eventuele maximale stringlengte rekening houden, maar dit is het principe. Ik houd me aanbevolen voor een correcte C++-versie.
Je ziet: een tien voor taal is ook in de computerwereld een gewild cijfer.
PS1 Met dank aan de IMPACT-redactie voor het HTML-en van de tekst.
PS2 Van Vincent Icke kwam een aanvulling over de ghoti:
Maar in het origineel (afkomstig van George Bernard
Shaw) is het nog leuker, want het hoort te zijn
ghotib.
De "b" wordt niet uitgesproken, zoals de tweede b in "bomb".
PS3 En Ray Dassen vond deze
leuke link.