Nationale Programmeertaal

Citrine/NL

Citrine/NL (download, broncode) is een eenvoudige, Nederlandstalige programmeertaal geschreven in C, die gebruikt kan worden voor allerlei zaken.

Laten we eens kijken naar een voorbeeld.
Zo maakt u, met een paar regels, een gokspelletje:

☞ te raden getal := Getal tussen: 1 en: 10.

✎ schrijf: 'Wat is het getal?↵'.
☞ antwoord van gebruiker := Programma vraag.

(antwoord van gebruiker = te raden getal) waar:
{
 ✎ schrijf: 'Goed!'.
},

anders:
{
 ✎ schrijf:
 (
 'Onjuist, antwoord was: getal'
  getal: te raden getal 
 ).
}.

Speel zelf eens met Citrine of bekijk de uitgebreide handleiding (gevorderd).

Hoe werkt Citrine?

Citrine denkt in objecten. Een computerprogramma geschreven in Citrine is een gesprek tussen objecten. Objecten praten met elkaar door de uitwisseling van berichten.

☞ x := 3.6 afgerond.
☞ x := 3.6 afgerond even?.

Op de eerste regel van bovenstaand voorbeeld sturen we het bericht 'afgerond' naar het getalsobject 3.6. Als antwoord krijgen we nu 4. Dit getal 4 bewaren we onder de naam x. Op de tweede regel sturen we een paar berichten naar 3.6, eerst 'afgerond' (levert 4 op) gevolgd door 'even?'. Op die laatste vraag zal het getal 4 antwoorden met 'Waar'. Dit antwoord bewaren we onder naam x. Dus x zal gelijk zijn aan de bewering Waar (ook een object). Naast deze enkelvoudige berichten zijn er ook berichten met invulvelden (argumenten), dit noemen we meervoudige berichten:

☞ q := Getal tussen: 1 en: 10.

In bovenstaand voorbeeld sturen we het bericht 'tussen:__en:__' naar Getal met de argumenten 1 en 10. Op die manier trekken we een willekeurig getal tussen 1 en 10 welke we bewaren onder de naam q. Een bericht dat bestaat uit slechts één enkel symbool noemen we ook wel een tweevoudig bericht. Dergelijke berichten worden altijd gevolgd door een enkel argument zonder dubbele punt.

☞ x := 2 + 3.

In bovenstaand voorbeeld ontvangt object 2 het tweevoudig bericht + 3 en antwoord met object 5, dat vervolgens in x gestopt wordt. Met een komma kunnen we meerdere meervoudige berichten aaneenschakelen.

✎ schrijf: 'hallo ', schrijf: 'allemaal!'.
hallo allemaal!
>_

De loop van het programma

Ter groepering van een reeks instructies gebruiken we accolades { en }. Om een codeblokje te herhalen vermenigvuldigen we de code met het gewenste aantal iteraties:

{ :x ✎ schrijf: x. } * 5.
01234
>_

Bovenstaande code zal de reeks 01234 tonen omdat bij elke keer dat het blokje code wordt gedraaid het volgnummer wordt meegegeven in parameter :x.

Willen we een lus tussentijds afbreken, bijvoorbeeld na de derde ronde (volgnummer 2) dan schrijven we:

{ 
  :volgnummer

  ✎ schijf: volgnummer. 
  (volgnummer = 2) afbreken.
}
* 5.

Om een blokje voorwaardelijk uit te voeren schrijven we:

(geld ≥ prijs) waar: {
	product kopen.
}.

U kunt een foutafhandelingsclausule toevoegen als volgt:

{ 2 / 0. } afhandelen:
{
	:fout

	✎ schrijf: fout.
},
start.
Deling door nul.
>_

Let op het gebruik van de komma, de komma zorgt ervoor dat we het bericht 'start' naar de oorspronkelijke foute code sturen, zonder die komma zouden we direct de foutafhandelingsclausule starten.

Reeksen en Lijsten

Een reeks is een verzameling objecten. Zo maakt u bijvoorbeeld een reeks tekstjes:

☞ taken := Reeks nieuw
• 'afwassen'
• 'stofzuigen'
• 'boodschappen doen'.

✎ schrijf: (taken samenvoegen: ',').
afwassen,stofzuigen,boodschappen doen
>_

of een reeks getallen:

☞ oneven := Reeks ← 1 ; 3 ; 5.

Een lijst is een verzameling waarbij elke ingang bestaat uit een sleutel en een waarde.

☞ prijs := Lijst
kroket: 2 gulden,
slavink: 3 gulden,
pannekoek: 4 gulden.

✎ schrijf: prijs pannekoek.
4
>_

Let u trouwens eens op de leuke truuk die we hier uithalen met de gulden. U kunt aan elk getal een kwalificatie geven (dat is een eigenschap van het getalsobject). Met die kwalificatie kunt u makkelijk rekenen tussen valuta. U kunt de kwalificatie ook opvragen:

✎ schrijf: prijs pannekoek kwalificatie.
gulden
>_

Objecten

Zoals gezegd is alles in Citrine een object. Om uw eigen object te maken schrijft u:

☞ kat := Object nieuw.

U heeft zojuist een katobject gemaakt. Om het mogelijk te maken om onze kat een naam te geven, definiëren we het volgende gedrag:

kat bij: 'naam:' doen: {
  :genoemd

  ⚿ identiteit := genoemd.
}.

Vanaf nu is het mogelijk om de kat een naam te geven. Bij het ontvangen van het bericht naam: X zal de kat nu reageren door de opgegeven naam X te bewaren als eigenschap identiteit. Alle eigenschappen zijn alleen van binnenuit aan te passen, dit wordt aangegeven met het sleuteltje (). Om onze kat Diva te noemen kunnen we nu schrijven:

kat naam: 'Diva'.

Hoewel onze kat zich nu bewust is van haar naam, heeft ze nog niet de mogelijkheid om zich voor te stellen. Dat moeten we dus nog even toevoegen:

kat bij: 'naam' doen: {
   ↲ ⚿ identiteit.
}.

Bij ontvangst van het eenvoudige bericht naam (dus zonder dubbele punt), antwoordt () onze kat met de intern opgeslagen identiteit. We kunnen nu aan onze kat vragen hoe zij heet:

✎ schrijf: kat naam.

Geavanceerde onderwerpen

U kunt ook objecten baseren op eerder gemaakte versies (prototypische overerving). Zo kunnen we een verwaande kat maken die gebaseerd is op de hiervoor besproken kat:

☞ kapsoneskat := Kat nieuw.
kapsoneskat bij: 'naam' doen: {
   ☞ naam := ⛏ `naam.
   ☞ tekst := 'Uwe hoogheid kat'.
   tekst kat: naam.
   ↲ tekst.
}.

In bovenstaand voorbeeld overschrijven we het gedrag voor het bericht naam.

Bij ontvangst van het bericht naam stuurt de kapsoneskat eerst een bericht naar het overerfde object (kat) met behulp van het afspeelicoon ().

Omdat er nu echter twee gedragingen zijn (naam van de kapsoneskat en naam van de originele kat) moeten we aangeven dat we nu wél het originele gedrag voor naam van de basiskat willen. Dit doen we door een accentje aan het bericht toe te voegen: `naam.

Om nu de naam van de kapsoneskat (Diva) in de tekst op te nemen, sturen we het bericht kat: naam naar de tekst. Omdat het bericht kat: niet wordt herkend door het object tekst, neemt het object tekst aan dat u een deel van de tekst gerepresenteerd door het bericht wilt vervangen met hetgene achter de dubbele punt. Het resultaat:

Uwe hoogheid Diva.
>_

U kunt het gedrag van bestaande objecten ook aanpassen. Stel dat u bijvoorbeeld het × teken wilt gebruiken om stukjes code te herhalen, dan schrijft u:

Getal bij: '×' doen: {
   :blokje
   
   blokje * ⛏. 
}.

7 × { :i ✎ schrijf: i. }.

Als objecten zich geen raad weten met een ontvangen bericht, dan geven ze een algemene reactie. Ook dit gedrag kunt u aanpassen door blokjes code te definieren voor de berichten 'reageer:' 'reageer:en:' en 'reageer:en:en:'.

Voorbeeld:

☞ nagalm := Object nieuw.
nagalm bij: 'reageer:' doen: {
   :geluid

   2 * {
      ✎ schrijf: geluid.
   }.
}.
nagalm ho!.
ho!ho!
>_

Opdrachten in Citrine worden gescheiden door spaties. Soms willen we echter ook een spatie gebruiken in de naam waaronder we een waarde opslaan. In bovenstaand voorbeeld hebben we de naam kapsoneskat gebruikt. Stel dat we de naam koninklijke kat zouden willen gebruiken dan kan dat mits we voor de spatie een haarspatie gebruiken. Als u de bijgeleverde pictogrammen en macros gebruikt kunt u deze produceren met toetscombinatie ALT+; .

Plug-ins & Systeem

U kunt uitbreidingen voor Citrine eenvoudig installeren. Zodra u begint te praten tegen een object dat niet bestaat (binnen Citrine) zal de programmeertaal gaan zoeken of er uitbreidingen beschikbaar zijn die een object onder de gevraagde naam aanbieden. U dient deze objecten op de volgende locatie neer te zetten:

mods/{plugin}/libctr{plugin}.so

Als u systeemcommando's voor het Linux/UNIX besturingssysteem wilt laten uitvoeren, stuurt u het bericht opdrachtregel naar het object Programma:

Programma opdrachtregel: 'ls -la'.

Vertalingen

Om een programma van de ene taal te laten vertalen naar een andere doet u:

ctr -t nl2en.dict programma.ctr

Woordenboeken
(.dict-bestanden) zijn in het volgende formaat:

t "BRONTAAL" "DOELTAAL"
s "BRONTAAL" "DOELTAAL"

Hierbij staat t voor token (een taalelement) en s voor een string (een stukje tekst tussen aanhalingstekens). U kunt automatisch een woordenboek laten maken met de kopbestanden van een tweetal Citrine-versies in verschillende talen:

ctr -g /en/dictionary.h /nl/dictionary.h

Vraag & Antwoord

Welke objecten zijn er?

Voor een overzicht van alle berichten en objecten waarmee u een programma kunt schrijven, raadpleeg de Volledige Citrine Handleiding. Deze handleiding is meertalig. Per onderdeel is een Nederlandse sectie ingevoegd onder het kopje 'Dutch:'.

Hoe krijg ik de icoontjes?

Installeer het meegeleverde lettertype 'Citrine.ttf'. Als u Geany gebruikt, kunt u gebruik maken van de comfortabele Geany Macros:

cp ~/.config/geany/plugins/Geany_Macros/settings.conf ~/.config/geany/plugins/Geany_Macros/settings_backup.conf

cp macros.ini ~/.config/geany/plugins/Geany_Macros/settings.conf

$_

Lijst van symbolen:

pictogram hexadecimaal toetscombinatie
26CFALT.
26BFALTk
261EALT=
2190ALT+
21B2ALT,
270EALT'
2264ALT<
2265ALT>
2260ALTu
2022ALT*
2009ALT; (haarspatie)

Kan ik ook webapplicaties maken?

Ja, Citrine wordt geleverd met een CCGILIB-HTTP plug-in (mods/request/libctrrequest.so) om GET (vraag), POST (zending), FILE (bestand) en COOKIE (koekje) verzoeken te beantwoorden.

Voorbeelden:

zoek    := Verzoek vraag: 'zoek'.
lijst   := Verzoek vragen: 'bestellingen[]'.
bericht := Verzoek zending: 'bericht'.
lijst   := Verzoek zendingen: 'bestellingen[]'.
bestand := Verzoek bestand: 'foto'.

Waarom Citrine?

Volgens de Citrine hypothese help programmeren in uw eigen taal om complexe problemen beter op te lossen doordat u ze beter kunt beschrijven (1), geeft het minder technisch onderlegde personen een kans om mee te lezen en uw gedachtegang te volgen (2), maakt het het mogelijk om op jonge leeftijd kennis te maken met programmeren (nog voordat men de Engelse taal beheerst) (3), zou het kunnen helpen om tot een wereldwijde gemeenschappelijke vocabulaire te komen voor objecten (4), kan het dienen als DSL (domeintaal) om overmatig complexe grafische bedieningspanelen te vervangen (5) en kan het tenslotte gebruikt worden als een brug tussen nieuwe en oude programmatuur (6).

The Citrine Programming Language Project