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. HTML (Hypertext Markup Language) is op dezelfde manier alleen bedoeld 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 andere talen ook worden uitgedrukt. Verschillende basisfuncties zijn opgenomen in bijna al deze 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. Veilig in de zin dat de programma's minder snel bugs bevatten, 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
of 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
of
) als
invoer en rapporteert het resultaat van het combineren van alle items in de lijst met
behulp van die functie (bijvoorbeeld, ze opsommen of ze samenvoegen tot in één woord).
Dee code uit de vraag hierboven op de uitgebreide manier kunnen uitwerken in C:
maar met C kun je geen uitdrukking zoals
of
)
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 met getallen met miljoenen of miljarden cijfers, beperkt alleen 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 dat eer een een toepassing is die geen voordeel zou hebben 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 bedoeld om te leren programmeren zoals Snap!, zou het alleen maar ingewikkeld zijn als als gebruik gemaakt zou moeten worden van type-conversie. Maar de meeste talen die niet bedoeld zijn voor beginners, houden de twee gegevenstypen duidelijker gescheiden.
Programmeurs denken misschien dat abstractie te langzaam is. Dit was vroeger waar, en programmeurs van 3D-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 in machinetaal, dit is vaak het deel dat afbeeldingen op het scherm zet. Dit doen ze 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 het programma kan uitvoeren.
Legacy-code. Programmeurs in het bedrijfsleven hoeven bijna nooit een programma vanaf niks 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 toevoegingen aan de bestaande code in de huidige programmeertaal schrijven.
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 regel voor regel moeten vertalen naar machinetaal.
Betekent dat dat compilers beter zijn?
Dat zou zo kunnen zijn, maar het probleem is dat als je 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, een voorbeeld is de 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 de machinetaalcode, 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 na 2020 multicore processorchips met wel 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
.