
JavaScript, Python, Snap!, C++, Java, Scheme, Prolog... Waarom zijn er zoveel programmeertalen? Waarom kiezen we niet gewoon de beste, of ontwerpen we een nieuwe, en houden we ons daar aan?
Sommige talen hebben zeer beperkte doelen; deze worden special-purpose (speciaal-doel) talen genoemd. Microsoft Word heeft bijvoorbeeld een programmeertaal ingebouwd die "Word-macro's" wordt genoemd en die alleen is bedoeld voor het genereren van gegevens en opmaak in een document. Net zo is HTML (Hypertext Markup Language) alleen voor het structureren van webpagina's.
General-purpose (Algemeen-doel) talen hebben geen specifiek doel voor ogen. In zekere zin zijn
deze talen allemaal hetzelfde: als een programma in één van deze talen kan worden uitgedrukt, kan het in
alle talen worden uitgedrukt. Verschillende basisfuncties zijn opgenomen in bijna alle talen, waaronder
rekenkundige functies ( +
, -
, *
, ÷
) en
Boolean-functies ( en
, of
, niet
). De verschillen tussen zulke
talen gaan meestal over abstractieniveaus.
Een taal op hoog niveau(zoals Snap ! of Schema) bevat veel ingebouwde abstracties waarmee je je gemakkelijker kunt concentreren op het probleem dat je wilt oplossen in plaats van op hoe de computer werkt. Een taal op laag niveau (zoals C) heeft minder abstracties, waardoor je veel moet weten over de architectuur van je computer om een programma te schrijven.
Talen op hoog niveau kunnen veiligere programma's produceren - die minder snel bugs hebben - omdat de abstracties rommelige details wegwerken waarover programmeurs kunnen struikelen.
Talen op hoog niveau verminderen bugs in geheugengebruik. Oudere talen op laag niveau vereisten dat de programmeur het geheugen van de computer beheerde met instructies zoals: "Geef me een stuk geheugen dat groot genoeg is om 100 getallen te bevatten" en andere instructies die zeggen "Oké, ik ben klaar met dit stukje geheugen; het kan worden gebruikt voor iets anders."
Dit is lastig om over na te denken en menselijke programmeurs zijn er slecht in. In talen op laag niveau is een veel voorkomende fout dat een deel van een programma zegt: "Ik ben klaar met dit geheugenblok" terwijl een ander deel van het programma het nog steeds gebruikt. Talen op hoog niveau regelen dit voor ons met een techniek genaamd garbage collection (afvalinzameling) . Deze techniek laat de computer automatisch weten wanneer een geheugenblok niet meer in gebruik is.
Talen op hoog niveau kunnen programmeren ook gemakkelijker maken omdat ze meer abstracties bevatten. Een
voorbeeld hiervan is een functie van hogere orde (zoals map
, keep
,
combine
en for each
) die de programmeur kortere en opgeruimdere code laten
schrijven.
for each
in
Hoofdstuk 2 Les 2: Verwerken van elk item in een lijst.keep
in
Hoofdstuk 2 Les 3: Houd
items van lijsten.map
in
Hoofdstuk 3 Les 1: Transformeren van alle items in een lijst.combine
in
Hoofdstuk 5 Les 3: Algoritmes vergelijken. Keep
neemt een predikaat (een vraag) als invoer en rapporteert een
lijst met items die dat predikaat waar maken.
Combine
neemt een predikaat met 2 lege (zoals
In C kan je dit op de lange manier doen:
maar met C kun je geen uitdrukking nemen (zoals
of
)
en het in een functie van hogere orde zoals
map
plakken:
De beste reden om talen op laag niveau te gebruiken is om besturingssystemen te schrijven (zoals Windows, Mac OS X, Android of iOS). Je vindt meer informatie over Besturingssystemen op de pagina Het Softwaredomein: Besturingssystemen .
Applicatieprogrammeurs beslissen niet vaak: "Ik ga dit programma in een taal op laag niveau schrijven." Ze realiseren zich misschien eenvoudigweg niet dat hogere abstractieniveaus mogelijk zijn. De hardware van een computer beperkt bijvoorbeeld de grootte van getallen die de rekeneenheid in één stap kan toevoegen. Vier miljard - ongeveer tien cijfers - is een algemene limiet voor gehele getallen. Programmeurs die Java, JavaScript, Python, C of C ++ gebruiken, denken misschien dat deze limiet onvermijdelijk is. Maar programmeurs die talen op een echt hoog niveau gebruiken, zoals Scheme of Common Lisp, weten dat ze kunnen rekenen op getallen met miljoenen of miljarden cijfers, alleen beperkt door de grootte van het geheugen van de computer. Zoals je later zult zien, heeft Snap! een bibliotheek waarmee dit ook mogelijk is.
Mensen zeggen vaak dat verschillende programmeertalen goed zijn voor verschillende soorten programma's, maar behalve voor 3D-videoverwerking (volgende paragraaf) is het moeilijk voor te stellen een toepassing die moeilijker zou zijn met zaken als garbage-collection (afvalinzameling) of functies van een hogere orde. Er zijn slechts enkele gevallen waarin mensen opzettelijk talen ontwerpen met functies die voor sommige toepassingen misschien niet gewenst zijn. Hier is een voorbeeld: in Snap!, wordt een tekstreeks van alleen cijfers als een getal beschouwd; je kunt ermee rekenen. In een taal voor leerlingen maakt expliciete conversie tussen datatypes het alleen maar moeilijker om te beginnen met programmeren. Maar de meeste talen die niet bedoeld zijn voor beginners, houden de twee gegevenstypen gescheiden.
Programmeurs denken misschien dat abstractie te langzaam is. Dit was vroeger waar, en programmeurs van 3-D Videogames hebben nog steeds alle snelheid nodig die ze kunnen krijgen omdat hun programma's de snelheid van moderne computers belasten. Daarom schrijven ze vaak een deel van hun programma's, het deel dat afbeeldingen op het scherm zet, in machinetaal, puur voor de snelheid. Maar de meeste programmeurs schrijven applicaties die computers helemaal niet belasten. Wanneer je een e-mail of sms-bericht verzendt, is de beperkende factor hoe snel je kunt typen, niet hoe snel je computer programma's kan uitvoeren.
Legacy-code. Programmeurs in de industrie moeten bijna nooit een programma vanaf het begin schrijven. Veel vaker onderhouden ze een programma dat iemand jaren geleden schreef, en die persoon werkt misschien niet eens meer voor dat bedrijf. Op de lange termijn is het misschien beter om het programma in een modernere taal te herschrijven, maar op de korte termijn is er geen tijd om dat te doen, zodat ze uiteindelijk de bestaande code in de bestaande programmeertaal wijzigen.
Zowel talen op hoog als laag niveau worden door mensen gebruikt om computerprogramma's te schrijven. De hardware van een computer begrijpt alleen een soort ultralage taal, genaamd machinetaal. Speciale programma's genaamd compilers en interpreters (tolken) worden gebruikt om menselijke programmeertalen te vertalen naar machinetaal die door de computer kan worden uitgevoerd.
Een compiler is een programma dat een programma op hoog of laag niveau (de broncode ) als invoer gebruikt en een programma geschreven in machinetaal maakt (de objectcode ) als resultaat. Eenmaal geproduceerd, kan het programma in machinetaal zo vaak uitgevoerd worden als je wil, zonder dat het originele programma opnieuw moet worden gecompileerd. Als je de broncode aanpast, moet je natuurlijk wel opnieuw het programma compileren.
Een interpreter is een programma dat een programma op hoog of laag niveau als invoer gebruikt en machinetaalinstructies uitvoert. Het vertalen gebeurt pas als de regels code nodig zijn om het programma uit te voeren. Het produceert dus geen los programma in machinetaal en zal de code de volgende keer als het wordt uitgevoerd opnieuw moeten herhalen.
Betekent dat dat compilers beter zijn?
Dat zou zo kunnen zijn, maar het probleem is dat als je programma schrijft, je vaak het programma moet testen en debuggen. Tijdens het debuggen kan een interpreter helpen door informatie te verstrekken over de voortgang van het programma, zoals de visuele stepping-functie in Snap !. Daarnaast kan je met een interpreter kleine veranderingen in het programma maken zonder dat je iedere keer een compiler hoeft uit te voeren. In Snap ! kan je bijvoorbeeld een blok naar een script slepen terwijl het blok actief is. Een compiler zou daar niet mee om kunnen gaan.
Voor professionele programmeurs is de beste regeling om beide te hebben een interpreter en een compiler voor dezelfde taal. De programmeur schrijft en debugt het programma met behulp van een interpreter, en zodra ze zeker weten dat het werkt, compileren ze het. Dan kan de compiler langzaam zijn gang gaan en veel moeite stoppen in het optimaliseren van het programma in machinetaal, zodat je het snelste mogelijke gecompileerde programma krijgt.
Een van de functies die Snap ! biedt, is dat je stukken tekst in het midden van een blok kan
plaatsen. Zoals "kantlengte: " in het blok hieronder.
veelhoek
gebouwd in
Hoofdstuk 1: Grafische kunst.
veelhoek(30, 15)
Een reden om nieuwe programmeertalen te maken is om het eenvoudiger te maken om parallelle programma's te schrijven. Dat zijn programma's die meer dan één processor tegelijkertijd kunnen gebruiken. Tegenwoordig hebben computers en smartphones in 2020 multicore processorchips met mogelijk 2, 4 of 8 processors die allemaal tegelijkertijd code draaien. (Het aantal processors zal in de loop van de tijd nog verder toenemen.) Grote bedrijven zoals Google gebruiken nog meer parallellisme; ze hebben clusters van duizenden computers, die allemaal hetzelfde programma uitvoeren.
Functionele programmeertalen (talen waarin programmeurs de waarde van een variabele nooit
veranderen) zijn bijzonder geschikt voor parallellisme omdat er geen gevaar bestaat dat de ene processor de
waarde wijzigt van een variabele die een andere processor gebruikt. We hebben je, waar mogelijk, tijdens
deze cursus kennis laten maken met functionele programmeertechnieken, waaronder het schrijven van
rapporteurs en het gebruiken van hogere orderfuncties ( map
, keep
en
combine
).
maak
,in een functionele programmertaal zou je invoervariabelen van recursieve functies gebruiken. Andere
voorbeelden zijn deze vier functies die met lijsten werken: voeg toe
, verwijder
, voeg in
en vervang
, een functionele
programmertaal zou alleen gebruik maken van voorafgaand aan
, item 1 van
en
alles behalve de eerste
.