Loading AI tools
programmeertaal Van Wikipedia, de vrije encyclopedie
APL is een programmeertaal. De taal is ontstaan uit een boek dat in 1962 werd geschreven door Kenneth E. Iverson en waarin een wiskundige notatiewijze werd geïntroduceerd. Met enkele aanpassingen werd uit dit voorstel de programmeertaal ontworpen. De naam APL is ontleend aan de titel van het boek: A Programming Language.
APL | ||||
---|---|---|---|---|
Paradigma | functioneel, multi-paradigma | |||
Verschenen | 1962-1964 | |||
Ontworpen door | Kenneth Eugene Iverson | |||
Ontwikkeld door | Kenneth Eugene Iverson | |||
Typesysteem | dynamisch | |||
Implementaties | IBM APL2, Dyalog APL, APL2000, Sharp APL | |||
Dialecten | A+ en anderen | |||
Beïnvloed door | wiskundige notatie | |||
Invloed op | J, K | |||
|
Zoals gezegd, de taal is ontstaan naar aanleiding van de publicatie van Kenneth E. Iverson. Hoewel zijn boek in 1962 uitkwam, ontdekte en ontwikkelde hij de taal al in 1957. Als programmeertaal werd APL al snel populair in vooral de wetenschappelijke en financiële wereld vanwege de krachtige mogelijkheden die de taal biedt om om te gaan met meer-dimensionale arrays met data. Oorspronkelijk draaide APL op (IBM)-mainframes en over de loop van jaren ontstonden er verschillende dialecten van de taal. Na de opkomst van de pc begin jaren 80 van de twintigste eeuw, en de afname van de populariteit van mainframes kwam er een versie van APL uit voor de pc onder de naam APL*Plus/PC van ontwikkelaar STSC (zie eventueel: STSC (Engels)). De eerste versie voor de pc kwam in 1982 op de markt en in het midden van de jaren 80 kwam er ook een 32-bit versie voor de Unix systemen op de markt als APL*Plus/Unix). Tot 1995 bleef STSC APL*Plus verder ontwikkelen, maar verkocht de rechten in dat jaar aan LEX2000 Inc. wat vervolgens in 1999 weer in handen kwam van Cognos. De belangstelling voor en het gebruik van APL zijn de laatste jaren erg teruggelopen, natuurlijk mede onder invloed van de komst van nieuwe ontwikkelomgevingen als C (en de opvolgers C+ / C++) en later Java). Er bestaat nog wel een groep die-hards die APL en varianten/dialecten als A+[1] gebruiken en ontwikkelen.
De overgang naar de nieuwe pc-omgeving vereiste natuurlijk wel wat toevoegingen om op een nieuwe manier om te gaan met –vooral– de uitvoer van gegevens en andere specifieke eigenaardigheden van de pc. De eerste versies draaiden (uiteraard) onder MS-DOS en dat waren specifiek single-user- en single-taskomgevingen. Dit vraagt een heel andere benadering van geheugengebruik, en commando's die verband houden met je rechten hoeveel gebruik jouw programma mag maken van de CPU hebben weinig nut. Om portering van bestaande programma's van mainframeomgevingen naar de pc te vereenvoudigen bleven in de pc-versie commando's en functies bestaan die feitelijk niets deden, maar wel de compabiliteit van workspaces verhoogden. (Na de overstap van MS-DOS naar Windows kwam je weer terug in een multi-user- en multi-taskingomgeving; maar wel op een andere wijze dan bij mainframesystemen.)
Hoewel het gebruik sterk is teruggelopen, blijft er een enthousiaste groep gebruikers die via internet nieuwe ontwikkelingen gebaseerd op APL ontwikkelt.
De programmeertaal verschilt in veel opzichten van andere talen.
Een groot voordeel van APL is dus dat er heel compact en snel gecodeerd kan worden. Tegelijkertijd is dat een nadeel. Een APL-source is vaak lastig te lezen vanwege de vele vreemde tekens.
Voor het invoeren van APL-symbolen is een speciaal toetsenbord nodig. Het getoonde toetsenbord heeft geen aparte hoofd- en kleine letters: de lettertoetsen geven in combinatie met Shift een symbool.
En nog heeft het toetsenbord te weinig toetsen. Daarom kunnen er ook combinaties (overstrikes) worden gemaakt. Wenst men bijvoorbeeld een uitroepteken om de functie faculteit uit te voeren, dan typt men een aanhalingsteken (shift K), een backspace en een punt. Op dezelfde wijze kunnen ook de letters (andere tekens niet) onderstreept worden.
Er zijn verder diverse APL-editors. Om invoer te vergemakkelijken kan men van veel symbolen de naam invoeren.
Gegevens kunnen, zoals bij elke programmeertaal, uit arrays bestaan. Maar bij APL wordt een array als eenheid beschouwd. Een array kan een willekeurig aantal dimensies hebben. Een array van twee dimensies heet 'matrix', een array van een dimensie heet 'vector'. Een array van nul dimensies bestaat ook, dat is een scalar.
De dimensie van een array kan desnoods de lengte nul of één hebben. Dat lijkt niet erg zinvol, maar een array met een dergelijke dimensie kan door een programma uitgebreid worden.
Een vector (2 of langer) kan als constante worden ingevoerd als een reeks getallen met spaties ertussen, bijvoorbeeld 1 4 9 16 25. Geeft men een enkel getal op, dan is dat een scalar. Wil men een andere array, dan zal men een functie moeten gebruiken.
De bekendste functie om een array te maken is reshape ⍴. Bijvoorbeeld, de expressie 2 4⍴9 8 1 12 16 25 14 14 maakt een matrix van 2 bij 4, met de daarachter opgegeven getallen als waarden.
Een andere veel gebruikte functie is de indexgenerator ⍳ die een vector van natuurlijke getallen maakt. ⍳5 levert dus de vector 1 2 3 4 5. Het ziet er niet erg zinvol uit, maar deze functie is vaak heel handig.
De meeste functies zijn erg vergevingsgezind als een argument de verkeerde vorm heeft. Bijvoorbeeld, de hierboven genoemde functie ⍴ heeft als linkerargument in principe een vector nodig, maar een scalar is ook goed.
Een array kan, zoals in elke programmeertaal, geïndiceerd worden: A[I]. Zijn er twee of meer indices, dan worden ze gescheiden door ;. Het is beslist niet nodig dat op deze wijze een enkele waarde uit een array wordt gehaald: door een array als index te gebruiken of een index weg te laten is het mogelijk een deel uit een array te selecteren: de expressie R[;3 4] heeft als resultaat een matrix bestaande uit de derde en de vierde kolom van de matrix R — de hele kolommen omdat de eerste index, tussen [ en ; is weggelaten.
Het is zelfs mogelijk een constante vector te indiceren, bijvoorbeeld 1 3 8 5[I].
Onderstaande regel is een programma dat alle priemgetallen van 1 tot R vindt:
(∼RεR∘.×R)/R←1↓⍳R
en de beschrijving van rechts naar links:
Er zijn monadische functies met één argument en dyadische functies met twee argumenten. De syntaxis is zoals gebruikelijk bij de klassieke wiskundige functies, bijvoorbeeld A+B en −B. Deze syntaxis is consequent doorgevoerd voor alle functies, ook voor faculteit (uitroepteken links van de operand, niet rechts) en absolute waarde (verticale streep links van de operand, niet aan weerszijden).
Verder worden de functies onderscheiden in scalaire functies en gemengde functies. De laatste zijn in het bijzonder bedoeld voor het werken met arrays.
Worden scalaire functies op een array toegepast, dan werken ze op ieder element van de array apart. Men kan bijvoorbeeld twee arrays bij elkaar optellen, mits beide arrays dezelfde vorm hebben, dus arrays van evenveel dimensies met dezelfde waarden. Het resultaat heeft weer dezelfde vorm. Bijvoorbeeld: 3 5 4 + 2 4 6 geeft 5 9 10. Hierop geldt een uitzondering: men kan een scalaire dyadische functie uitvoeren op twee arrays waarvan een enkel getal is. Bijvoorbeeld: 3 + 2 4 6 geeft 5 7 9.
Teken | Math | Unicode (hex) | Dyadisch | Monadisch | ||||
---|---|---|---|---|---|---|---|---|
+ | Plus | Optelling | Plus | onveranderd | ||||
− | Min | Aftrekking | Min | Negatie | ||||
× | \times | Maal | Vermenigvuldiging | Teken | 1 als argument positief is, ¯1 als argument negatief is, 0 als argument nul is | |||
÷ | \div | Delen | Deling | Omgekeerde | Omgekeerde | |||
⌈ | 2308 | Maximum | Het grootste der twee argumenten | Ceiling | Het kleinste gehele getal dat niet kleiner is dan het argument | |||
⌊ | 230a | Minimum | Het kleinste der twee argumenten | Floor | Het grootste gehele getal dat niet groter is dan het argument | |||
* | 2217 | Machtsverheffen | A in de macht B | e-macht | Macht van e | |||
⍟ | \circledast | Logaritme | Logaritme van B met grondtal A | Natuurlijke logaritme | ||||
| | Rest | Rest bij deling van B door A | Absolute waarde | |||||
! | Binomiaalcoëfficiënt | Faculteit | Faculteit (of gammafunctie van B+1) | |||||
? | zie gemengde functies | Willekeurig | Willekeurig getal uit ⍳B | |||||
ο | \circle | 2394 | trigonometrische functies | het linker argument (tussen ¯7 en 7) bepaalt welke functie wordt uitgevoerd | pi maal | product van pi | ||
Logische functies: enige toegestane argumenten zijn 1 (true) en 0 (false) | ||||||||
∧ | \land | 22c0 | En | |||||
∨ | \lor | 22c1 | Of | |||||
⍲ | 2372 | Niet en | ||||||
⍱ | 2371 | Niet of | ||||||
∼ | \sim | Niet | Verandert 1 in 0 en 0 in 1 | |||||
Vergelijkingen: het resultaat is 1 (true) of 0 (false) | ||||||||
< | kleiner | Kan alleen op getallen worden toegepast | ||||||
≤ | \le | 2264 | kleiner of gelijk | |||||
> | groter | |||||||
≥ | \ge | 2265 | groter of gelijk | |||||
= | gelijk | Kan op getallen en tekens worden toegepast | ||||||
≠ | \ne | 2260 | ongelijk |
Gemengde functies zijn speciaal voor het bewerken van arrays. Sommige functies kunnen zelfs van een index worden voorzien. Bijvoorbeeld A↑[I]B. In dit geval wordt de functie A↑B langs de index I uitgevoerd. De index is dus een geheel getal, behalve bij de functie Lamination. Wordt er geen index opgegeven, dan wordt de functie langs de laatste dimensie uitgevoerd.
Teken | Math | Unicode (hex) | Dyadisch | Monadisch | ||||
---|---|---|---|---|---|---|---|---|
⍴ | 2374 | Reshape | Maak een array. het linkerargument bepaalt de vorm van de array, de waarden van de array komen uit het rechterargument. | Dimensie | Maakt een vector met de vorm van het rechterargument. | |||
⍳ | 2373 | Zoeken | Zoekt de waarden van het rechterargument in het linkerargument en geeft terug op welke positie de waarden voorkomen. Het linker argument moet een vector zijn. | Index | Maakt een vector met de natuurlijke getallen van 1 tot n. | |||
, | Catenation (indiceerbaar) | Een komma koppelt twee arrays aan elkaar tot een nieuwe array. Alle dimensies van de twee arrays moeten identiek zijn, behalve de dimensie waarlangs de functie wordt uitgevoerd. | Ravel | Een monadische komma maakt een vector van het argument. | ||||
, | Lamination (de index is verplicht en moet een gebroken getal zijn, uitzondering: als beide argumenten scalair zijn is geen index nodig) | Koppelt twee arrays aan elkaar tot een nieuwe array. Alle dimensies van de twee arrays moeten identiek zijn, en de nieuwe array heeft een dimensie meer, met de waarde 2. Voor deze functie is een gebroken index nodig. Bijvoorbeeld A,[3.5]B koppelt de arrays tussen de derde en vierde dimensie aan elkaar. | ||||||
↑ | \uparrow | 2191 | Take (indiceerbaar) | Neemt een deel uit het tweede argument, namelijk zo veel elementen als door het tweede argument is aangegeven. Is het eerste argument positief, dan worden de eerste N elementen genomen, is het negatief, dan worden de laatste −N elementen genomen. | ||||
↓ | \downarrow | 2193 | Drop (indiceerbaar) | Verwijdert een deel uit het tweede argument, namelijk zo veel elementen als door het tweede argument is aangegeven. Is het eerste argument positief, dan worden de eerste N elementen verwijderd, is het negatief, dan worden de laatste −N elementen verwijderd. | ||||
/ | Compressie (indiceerbaar) | Het linker argument is een logische vector. De waarden die met een nul corresponderen worden uit het rechter argument verwijderd. Bijvoorbeeld 1 0 1 0 / 2 3 5 4 resulteert in 2 5. | Het teken / kan niet monadisch worden gebruikt, maar vormt dan met het voorafgaande teken een gecombineerde functie. Zie volgende tabel. | |||||
⌿ | 233f | Compressie | Hetzelfde als /[1] | |||||
\ | Expansie (indiceerbaar) | Het linker argument is een logische vector. In het rechterargument worden waarden tussengevoegd op de plaatsen die corresponderen met een nul in het linkerargument. Bijvoorbeeld 1 0 1 0 \ 2 5 resulteert in 2 0 5 0. | ||||||
⍀ | 2340 | Expansie | Hetzelfde als \[1]. | |||||
⍋ | 23c3 | Grade up | Vector, zodanig dat V[⍋V] gesorteerd is. | |||||
⍒ | Grade down | Vector, zodanig dat V[⍒V] omgekeerd gesorteerd is. | ||||||
⌽ | 23c0, 233d | Roteren (indiceerbaar) | De volgorde van de elementen van het rechterargument wordt opgeschoven | Omkeren | Het rechterargument wordt andersom gezet | |||
⊖ | Roteren | Hetzelfde als ⌽[1] | Omkeren | |||||
⌹ | 2339 | Matrixdeling | Omgekeerde van inwendig matrixproduct | Inverse van matrix | ||||
? | Deal | A getallen, willekeurig gekozen uit ⍳B | zie scalaire functies | |||||
⌶ | 2336 | I beam | Diverse functies, alleen voor de systeembeheerder, sommige met neveneffecten. Onder andere "peek" en "poke" in het geheugen, systeem afsluiten. | I beam | Diverse systeeminformatie, zoals datum, tijd, geheugenruimte, aantal aangemelde gebruikers. Voor de systeembeheerder zijn er nog meer mogelijkheden. |
Verder zijn er gecombineerde functies. Hierbij wordt uit een scalaire dyadische functie (of twee scalaire dyadische functies) een nieuwe gemengde functie gemaakt. In de voorbeelden hieronder kan ⎕ worden vervangen door een willekeurige scalaire dyadische functie.
Teken | Math | Unicode (hex) | Dyadisch | Monadisch | ||||
---|---|---|---|---|---|---|---|---|
⎕/B | Reductie | De dyadische functie ⎕ wordt toegepast op de hele vector, bijvoorbeeld +/3 5 8 komt overeen met 3+5+8 | ||||||
⎕⌿B | 233f | Hetzelfde als ⎕/[1]B | ||||||
A∘.⎕B | 2218 | Uitwendig product | Uitwendig product van twee arrays. Elke dyadische scalaire functie kan als ⎕ worden gebruikt. | |||||
A⎕.⎕B | Inwendig product | Het gewone matrixproduct is A+.×B |
Teken | Math | Unicode (hex) | Dyadisch | Monadisch | ||||
---|---|---|---|---|---|---|---|---|
← | \gets | 2190 | toekenning | Het linker argument is een variabele die de waarde krijgt van het rechter argument | ||||
→ | \to | 2192 | sprongopdracht | De uitvoering van het programma gaat verder op het aangegeven regelnummer. Is het argument een array, dan geldt het eerste element van de array. Is het argument een lege array, dan gaat de uitvoering verder met de volgende regel. Door expressies te gebruiken zijn voorwaardelijke sprongen mogelijk. Wordt naar regel nul gesprongen, dan wordt de uitvoering van de routine beëindigd. |
De laatste bewerking die op een regel wordt uitgevoerd, is vrijwel steeds → (sprongopdracht) of ← (toekenning).
Bijvoorbeeld:
→3+5 spring naar regel 8
A←3+5 A krijgt de waarde 8
Staat er iets anders, bijvoorbeeld 3+5, dan wordt de optelling uitgerekend, maar er staat niet wat er met het resultaat moet gebeuren. In dat geval wordt het resultaat geprint.
Het is ook mogelijk tussenresultaten van een expressie te printen, en wel met de combinatie ⎕←. Bijvoorbeeld: A←3+⎕←5 De waarde 5 wordt geprint en A krijgt de waarde 8.
Wil men in de loop van het programma invoer vragen, dan gebruikt men het teken ⎕, maar niet links van een pijltje. Bijvoorbeeld 2.20371×⎕: er wordt om invoer gevraagd en het resultaat wordt met 2.20371 vermenigvuldigd.
Het is natuurlijk mogelijk zelf een functie te definiëren. Een zelfgedefinieerde functie kan dyadisch, monadisch en ook niladisch zijn, dat wil zeggen dat er 2, 1, of 0 argumenten zijn.
Een zelfgedefinieerde functie wordt niet aangeduid met een teken maar met een naam, een identifier dus. De syntaxis is echter niet anders: een dyadische functie wordt aangeroepen met de naam en aan weerszijden de beide argumenten en een monadische functie met de naam en daarachter het argument. Deze wijze van aanroepen is heel anders dan in andere programmeertalen.
Als voorbeeld geven we de volgende functie. Het teken ∇ duidt de header van de functie aan. Daaronder staat de body, in dit geval slechts een regel, met daarvoor tussen haken het regelnummer.
∇SOM←U VREL V
[1] SOM←(U+V)÷1+(U×V)÷9E16
In de kopregel staat links van het pijltje de variabele die als terugkeerwaarde dient. Rechts daarvan staan drie namen, het is dus een dyadische functie. De middelste daarvan is de naam van de functie en de twee andere zijn de argumenten.
APL gaat op een bijzondere manier om met opslag van zowel de gegevens alsook de programmabroncode zelf in vergelijking met veel andere talen. Je kunt drie soorten bestanden onderscheiden:
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.