zondag 4 december 2011

Programma's begrijpen: De programmeertaal


“Een taalcursus is alleen praktisch als je ook de zinsopbouw begrijpt”
                                                                                                            - Sam Rain
Het internet staat er vol mee; de artikelen over programmeren zijn uitgebreid en gedetailleerd van de meest excentrieke ‘talen’ tot de industrie standaarden. Het grote nadeel is dat ze vooral gericht zijn op techneuten waardoor sympathisanten snel ongeïnteresseerd raken. Programmeren wordt hierdoor ook ‘mystiek’; het vakjargon is duizelingwekkend en vaak ook misbruikt; dezelfde begrippen worden vaak herbruikt voor tegenstrijdige doelen en zijn zelden echt hyperoniem of zelfs associatief. De realiteit valt echter reuze mee; als iemand het maar goed uitlegt.
Programmeertalen zijn ‘middelen’. Ze zijn bedoelt voor mensen en niet voor computers. Iedere ‘broncode’ wordt door een ‘vernuftig’ programma vertaald naar uitvoerbare code, ongeacht welke taal. Dit programma (of verzameling van programma’s) doet deze transformatie conform een aantal regels; deze ‘wet’ is de programmeertaal. Concreet betekent dit dat je leert spreken via een tolk, die een beperkt aantal zinnen begrijpt en deze vertaald naar hiëroglyfen. Deze ‘tolk’ stelt al deze zinnen beschikbaar voor de ‘programmeur’ als een ‘taal’. Er zijn verschillende soorten ‘tolken’, afhankelijk van hoe gek men het wilt maken. Sommigen hebben genoeg aan een gids voor een korte vakantie, anderen willen de alfa status bereiken om ieder detail te beheersen.
De programmeertaal is daarom opgebouwd in ‘sleutelwoorden’ (‘keywords’) om de mogelijkheden van de computer te benutten: wiskundige berekeningen, herhalende opdrachten en condities. Deze sleutelwoorden zijn handelingen die de computer moet verrichten als ware het een bevel. De ‘tolk’ vertaald deze als ‘instructies’. Om instructies beter te begrijpen is er al een serie van artikelen beschikbaar (zie hier )schetst een redelijk beeld. Alle andere informatie in de ‘broncode’ zijn bedoeld als daadwerkelijke gegevens. Om deze informatie gescheiden te houden maken programmeertalen gebruik van ‘variabelen’. Dit zijn zelfbedachte sleutelwoorden die uniek zijn voor ieder programma en niet vast liggen in de taal en dus ‘vergeten’ worden. Dit proces heet ‘declareren’.
Een programma heeft ook een ‘werk’ volgorde nodig; meestal begint de ‘tolk’ boven ieder bestand en gaat regel-voor-regel de ‘broncode’ af. Echter beginnen de interessante delen pas wanneer er echt verwerkt kan worden, dat pas kan als alle informatie beschikbaar is. Om hier controle over te krijgen, kan de ‘broncode’ gerangschikt worden in ‘blokken’; een soort paragraaf van meerdere regels, gekoppeld aan een ‘eigen’ sleutelwoord. Zo’n paragraaf wordt een ‘procedure’ genoemd en wordt pas uitgevoerd als het zelfbedachte sleutelwoord wordt gebruikt. Zo kan met meerdere paragrafen een specifieke volgorde worden gevolgd, bekend als de ‘flow’ (vrij vertaald: ‘stroom’). Dit proces heet ‘aanroepen’; het vaststellen van een paragraaf of een ‘blok’ gegevens heet definiëren.
Computers zijn ‘domme’ apparaten; ze kunnen zelf geen verschil zien tussen getallen en tekens. Veel programmeertalen doen dit tegenwoordig voor je, toch blijft het belangrijk om te begrijpen hoe dit technisch wordt ‘opgelost’. Om het verschil te ‘zien’, gebruiken programmeertalen en computers speciale structuren: primitieve datatypes. Omdat computers eerst geheugen moet vrijmaken om er waarden aan toe te voegen is het belangrijk voor ze om te weten hoeveel ze daarvoor nodig hebben. Het cijfer ‘1’ en het cijfer ‘300.000’ zijn even ‘groot’ voor een computer, echter een zin van 3 regels kost meer geheugen. De oplossing is het gebruik van speciale ruimten in het geheugen. Elk ‘type’ ruimte heeft zijn eigen vooraf bepaalde grootte. Wanneer er een ‘decleratie’ moet plaatsvinden zal er dus geheugen ‘gereserveerd’ moeten worden. Deze primitieve datatypes hebben een eigen ‘sleutelwoord’ maar werken als bijvoeglijke naamwoorden: ze vertellen ‘hoeveel’ geheugen er nodig is voor de informatie. Dit proces heet ‘reserveren’ of beter gezegd: ‘toewijzen’.
Veel talen kennen dezelfde ‘primitieven’ voor gegevens; sommige talen kennen er velen, sommige bepalen dit zelf door de waarde te analyseren. De meest gangbare zijn de volgende ‘primitieven’:
Primitief
Bevat
Integer
Float
Char
String
Array
Hele nummers (dus geen ‘komma’ getallen)
Decimale getallen (getallen achter de komma)
Enkel ‘leesteken’
Verzameling ‘leestekens’
Verzameling van gegevens

Deze ‘engelse’ structuren zijn het meest gebruikt voor informatie verwerking. Ze kunnen de nodige gegevens bewaren en met deze ‘primitieven’ kunnen we zelf eigen, complexere structuren maken. Er zijn natuurlijk veel meer primitieven echter zijn die voor mechanische oplossingen binnen de programmeertaal, deze zijn gangbaar voor ‘informatie liefhebbers’. Programmeertalen hebben eigen documentatie over welke primitieven zij ondersteunen, maar zullen 99% van allen een vorm van getallen, leestekens en lijsten bevatten.
Een ‘programma’ bevat dus de volgende onderdelen:
-       het ‘declareren’ van informatie die gebruikt zal worden door middel van geheugen te reserveren en de informatie aan dit geheugen toe te wijzen
-       het ‘definieren’ van blokken welke aangeroepen kunnen worden voor daadwerkelijke verwerking
-       de ‘flow’, de volgorde waarin de blokken aangeroepen moeten worden.
Zoals ‘echte’ talen zijn er ook regels voor de ‘grammatica’ nodig. Deze heet in vakjargon de ‘conventie’ en zijn afspraken waar een programmeur zich aan moet houden zodat het programma ook klopt. Hoewel elke taal ‘eigen’ regels hanteert, zijn er vaak overeenkomsten tussen talen. Broncode wordt van ‘links-naar-rechts’ verwerkt en daar moet handig gebruik van gemaakt worden, de ‘syntax’ is hierdoor begrijpelijk voor het vertalende programma.
Naast de conventie voor het plaatsen van broncode zijn er ook conventies tussen programmeurs; deze liggen niet ‘vast zoals bij de grammatica maar bevorderen de ‘leesbaarheid’. Computers zijn niet geïnteresseerd in witruimte, echter worden programma’s uitgebreider en complexer waardoor het terugvinden van fouten moeilijker wordt zonder deze regels. Deze conventies zijn alleen cosmetisch van aard.
De conventie voor veel talen is bijvoorbeeld het ‘toewijzen’ van informatie aan een ‘variabele’. De variabele is een ‘label’ voor een gereserveerde ruimte. Bij een taal die expliciet vereist om een ‘primitief’ aan te geven gelden dan de volgende regels:
-       de naam van een variabele mag niet beginnen met een getal;
-       de naam moet aan elkaar geschreven zijn (er mag geen spatie in zitten);
-       het ‘primitieve’ type hoort voor de variabele geschreven te worden.
GOED                                                            FOUT
Als voorbeeld:           integer MijnNummer                                    1mijnNummer Integer
                                  string MijnOmschrijving                              String Mijn Omschrijving
Vanzelfsprekend mogen de woorden van een taal niet gebruikt worden als ‘label’ voor een variabele. Sommige talen zijn niet hoofdlettergevoelig, echter zijn dit tegenwoordig uitzonderingen. Speciale tekens zijn vaak ook niet toegestaan.
Een ‘operator’ is verantwoordelijk voor bewerkingen op wiskundig gebied. Deze zijn feitelijk ‘ingebouwde’ procedures voor veelvoorkomende berekeningen. Meestal worden deze ‘aan’ een variabele geschreven zonder spatie: een variabele ‘integer’ verhogen met ‘1’ is bijvoorbeeld verkort te schrijven met ++; als MijnNummer de waarde ‘2’ bevat en deze zo wordt geschreven: MijnNummer++, dan zal de nieuwe waarde ‘3’ zijn. Overigens hoeft een variabele maar eenmalig ‘gedeclareerd’ te worden. Wanneer een programma weet wat het ‘primitieve type’ is, blijft het bekend en is het ‘label’ voldoende om te werken met de inhoud ervan.
Procedures zijn ‘speciale’ variabelen; ze bevatten uitvoerbare ‘code’ in plaats van informatie en doen dit via ‘blokken’. Echter zijn procedures pas handig als ze met informatie kunnen werken; daarom accepteren ze ‘argumenten’ (parameters); informatie die binnen het ‘blok’ gebruikt kan worden, welke van ‘buiten’ het blok kan komen. Daarvoor gebruiken talen de haakjes ( ) om de argumenten aan te geven, met de komma als eventueel scheidingsteken. Omdat ‘niets’ ook een waarde is (niet te verwarren met het cijfer 0!!) worden de haakjes zonder waarde toch vaak gebruikt. Ter illustratie:
(pseudo-code)
Definitie MijnProcedure (Integer getal, Integer ander_getal)
getal+ander_getal
einde
Hoewel dit voorbeeld geen rekening houdt met visuele uitvoer is het wel ‘geldig’. Wanneer de procedure als volgt wordt aangeroepen:
MijnProcedure(1,5)
Zal het getal 6 berekend worden. Deze mechaniek tezamen met de toewijzing van informatie naar geheugen stellen de grondbeginselen van ieder programma. Alles wat eigenlijk geen ‘data’ is, is min of meer een procedure met het doel om te vereenvoudigen.
Het toewijzen van informatie aan een variabele kan ingewikkeld overkomen; vaak wordt de ‘=’ als operator gebruikt voor toewijzing:
MijnNummer = 1            MijnOmschrijving = “dit omschreven.”
De ‘=’ is dus niet zoals we bij rekenen gewend zijn; daarvoor wordt meestal de ‘==” ,zonder spaties, gebruikt. Getallen worden zonder aanhalingstekens geschreven, in tegenstelling tot leestekens en tekst.
Dankzij toewijzingen kan de uitkomst van procedures ‘veiliggesteld’ worden; door de procedure te ontwerpen, opdat deze een waarde teruggeeft, kan het opgevangen worden. Vaak is dit impliciet door de gewenste waarde als laatste op te geven of expliciet met een ‘sleutelwoord’ dat er voor bestemd is: ‘return’.
Integer EersteGetal
Integer TweedeGetal                                                                        (Decleratie)
Integer Uitkomst
EersteGetal = 1
TweedeGetal = 5                                                                           (Toewijzing)
Definitie MijnProcedure (integer getal_a, integer getal_b)
            Integer getal _x
            Getal_x = getal_a + getal_b                                                (Definitie)
            Return getal_x
Einde
Uitkomst = MijnProcedure (EersteGetal,TweedeGetal)            (Aanroepen)

Wanneer een ‘broncode’ geschreven is, wordt deze vertaald door de ‘tolk’ naar uitvoerbare code. Dit proces heet de ‘compilatie’. Elke keer als het programma veranderd moet worden, wordt alleen de ‘broncode’ opnieuw aangepast en zal het hele compilatieproces van voor af aan moeten beginnen, ongeacht de grootte van de wijziging. Daarom is ieder programma altijd ‘nieuw’ en zal het herstart moeten worden; de nieuwe versie moet de oude versie vervangen.
Een programmeertaal is een middel, geen doel. Het doel heiligt de middelen en niet andersom. Er bestaat dus geen ‘beste’ taal, alleen een toepasselijke taal voor specifieke doeleinden.
Meer lezen? Klik hier voor de inhoudsopgave voor alle artikelen in deze serie!
©SamRain
Programmeertaal

Geen opmerkingen:

Een reactie posten