APL (ohjelmointikieli)

Wikipedia
Loikkaa: valikkoon, hakuun
Tämä artikkeli käsittelee ohjelmointikieltä. APL on myös asteroidi.

APL (A Programming Language, myös Array Processing Language) on kanadalaisen Kenneth E. Iversonin (17. joulukuuta 1920 - 19. lokakuuta 2004) vuonna 1957 Harvardin yliopistossa kehittämään notaatioon perustuva sääntiökieli.

APL:n periaatteena on ilmaista matemaattiset ja tietojenkäsittelylliset perustoiminnot omilla symboleillaan tai niiden yhdistelmillä; luku- ja merkkijoukkoja operoidaan kokonaisuuksina. APL:n primitiivit ovat kaikki yhden merkin symboleita, mikä tekee kielestä tiiviin ja monien mielestä kryptisen. APL-ohjelmointiympäristö on hyvin salliva (kysehän on notaatiosta), joten ohjelmointikuri on käyttäjän vastuulla.

APL toimii (käytännöllisesti katsoen aina) tulkkiperiaatteella: ohjelmia ei käännetä vaan ne suoritetaan alkuperäiskoodia suoraan tulkitsemalla. Tämä mahdollistaa ohjelmaympäristön jäljittämisen, ohjelmakoodin ja muuttujien tarkastelun ja muokkauksen kesken suorituksen. Sovellus voidaan siten keskeyttää (joko tahallaan tai virhetilanteeseen) ja suoritusta voidaan jatkaa tehtyjen muutosten jälkeen suoraan keskeytyskohdasta. APL onkin ollut aina tehokas prototyyppikehitin.

Lyhyt historia[muokkaa | muokkaa wikitekstiä]

Alun alkaen Iversonin tarkoituksena oli kehittää tietojenkäsittelyn opetus- ja tutkimuskäyttöön yleinen matemaattispohjainen merkintätapa (Iversonin notaatio).

Iversonin notaatiota käytettiin menestyksekkäästi IBM:n tuolloisen lippulaivan, System/360:n arkkitehtuurin kuvaukseen. Tiivis notaatio osoittautui muita käytettyjä tapoja selkeämmäksi, ja samalla se toi esiin aiemmin havaitsemattomia vikoja. Notaation esitystapa hioutui samalla yksinkertaisemmaksi. Vuonna 1962 Iverson julkaisi teoksen A Programming Language (mistä kielen lyhenne 'keksittiin' myöhemmin) ja vuonna 1964 tehtiin ensimmäinen APL-ohjelmointikieliympäristö. Iversonille myönnettiin Turingin palkinto vuonna 1979.

APL-kieltä kehitettiin IBM:ssä 1960-luvulla, Iversonin lisäksi mukana olivat Adin Falkoff ja Donald Sussenguth. APL julkistettiin 1970-luvulla, ja sen käyttö levisi IBM:n keskustietokoneissa laajalle. IBM:n lisäksi muut keskeiset tietokonevalmistajat tarjosivat APL:n omiin tuotteisiinsa, ja APL-käyttäjät alkoivat järjestää käyttäjätapaamisia (vuonna 1984 pidettiin APL-konferenssi Helsingissä). Muutamat tehokkaat APL-tuotteet edesauttoivat tuotteen leviämistä: mm. kuvien ja kaavioiden tekoon tarkoitettu Graphpak, tehokas tietokantajärjestelmä ADI ja APE-sovelluskehitin.

Alkuperäinen APL oli ISO-standardoitu ja eri valmistajien tuotteet hyvin yhteensopivia, mutta toisen sukupolven APL:t alkoivat eriytyä toisistaan. Iverson siirtyi IBM:stä I.P. Sharpin palvelukseen (Sharpilla oli tuolloin ainutlaatuinen ajantasainen suhdannepalvelu, jonka käyttö perustui maailmanlaajuiseen tiedonsiirtoverkkoon - myöhemmin Reuters osti I.P. Sharpin). James A. Brownin johdolla IBM:n kehittämä APL2, joka julkistettiin 1983, erosi muutamassa keskeisessä ominaisuudessa Iversonin johdolla kehitetystä SharpAPL:stä.

APL:n keskuskonekäytössä tarvittiin erillinen APL-näppäimistö, ohessa muistinvarainen kaavio IBM:n suomalaisesta APL2-näppäimistöstä.

IBM:n APL2-päätteen näppäimistökartta.

Nykyään (2010 lopulla) on valmistaja- ja tuotejakauma suunnilleen seuraavanlainen: IBM:n APL2 on saatavissa laajalti (VM/CMS, MVS/TSO, Windows, Unix), brittiläis-tanskalainen Dyalog (Windows, Unix, PDA-laitteet) on noussut kielen tärkeimmäksi kehittäjäksi, yhdysvaltalainen APLNow (entinen APL2000 entinen Manugistics entinen STSC) nousi PC:iden myötä kehityksen kärkeen (Windows, Unix), brittiläisen 'MicroAPL:n tulkki on saatavissa eri ympäristöihin ja siis myös Mac-koneisiin, Soliton jatkaa Sharp-APL:n perinteitä (VM/CMS, MVS/TSO, Unix).

Iverson kehitti yhdessä Roger Huin kanssa uuden sääntiöajatteluun perustuvan ohjelmointikielen, J:n, jossa käytetään vain Ascii-merkkejä. Athur Whitney kehitti Morgan-Stanleylle APL-pohjaisen tehokkaan erikoiskielen A+ (joka on nykyään saatavilla vapaasti mm. Linuxille). Hänen 1990-luvulta kehittämäänsä K-sääntiökieltä voi luonnehtia erikoistuneeksi ja erittäin tehokkaaksi, erityisesti suurille datamassoille ja transaktioille hiotun tietokantaratkaisunsa ansiosta.

APL on modernisoitunut ajan myötä. Esimerkiksi DyalogAPL sisältää seuraavia kielen ja ympäristön laajennuksia: nimitilat (rakenteiset työtilat), oliolaajennukset (mm. GUI-, OLE- ja TCP-liittymät on toteutettu oliosyntaksilla), .NET-yhteensopivuus, kontrollirakenteet, dynaamiset funktiot (D-kieli, funktionaalinen APL:n alikieli), säie- ja olio-ohjelmointi. APLNow Inc:n APL+Win on kehittänyt Internet-ominaisuuksiaan.

APL:n nykyinen käyttö[muokkaa | muokkaa wikitekstiä]

APL:ää käytetään edelleenkin mitä erilaisimmissa tehtävissä muun muassa finanssipalveluissa sekä matemaattis-tilastollisissa tietojenkäsittelytehtävissä. Merkittävän käyttäjäryhmän muodostavat vakuutusmatemaatikot.

APL:n käytön historiaa[muokkaa | muokkaa wikitekstiä]

APL:ää on historiansa aikana käytetty hyvin erityyppisten ongelmien ratkaisuun. Sitä on hyödynnetty taloudellis-hallinnollisilla aloilla, matematiikassa, robotiikassa, insinöörialoilla, erilaisissa erikoistehtävissä ja nopeana prototyyppikehittimenä erityyppisten ad hoc -ongelmien ratkaisuissa. Muiden muassa seuraavilla aloilla on käytetty/käytössä APL-pohjaisia ratkaisuja (lista ei ole kattava): valtion budjetti, pankkien ja vakuutusyhtiöiden erikoisohjelmistot, öljynjalostuksen tuotannonohjaus, ydinvoimalaitosten riskianalyysit ja erilaiset moniulotteiset taloussimulaatiomallit.

Erikoisuutena mainittakoon vuoden 1991 Persianlahden sodassa suoritettu Patriot-ohjusten kauko-ohjelmointi: irakilaisten Scud-iskujen eliminoimiseksi asennettujen Patriot-ohjusten ohjaussäädöt tarkistettiin taistelutoiminnan jälkeen (tiedot siirrettiin satelliititse Coloradoon) ja säädettiin ajan voittamiseksi ensin APL:llä, valmis koodi muunnettiin Adaksi (koska vain Ada-koodia sai asentaa Yhdysvaltain armeijan laitteisiin), joka sitten siirrettiin satelliitilla takaisin ohjuksiin.

APL:n perusteet[muokkaa | muokkaa wikitekstiä]

APL on perusteiltaan yksinkertainen.

Käytössä on kolmentyyppisiä objekteja: operaattoreita, funktioita ja muuttujia (dataa). Funktiot käsittelevät argumentteinaan saamaansa dataa ja palauttavat muokattua tulosdataa. Operaattorit saavat operandeikseen funktioita tai muuttujia ja luovat uuden (johdetun) funktion.

Muuttujien datatyyppejä on kolme: numeerinen, looginen ja merkkityyppi. Looginen tyyppi käsittää totuusarvot tosi ja epätosi, joiden esityksessä käytetään kokonaislukuja 1 ja 0. Koska näitä voi käyttää suoraan laskennassa, on looginen tyyppi vain numeerisen tyypin alijoukko. Numeerinen tyyppi sisältää sekä kokonais- että reaaliluvut, APL2:ssa voidaan lisäksi käyttää kompleksilukuja. Tulkki pitää huolen eri numeeristen tyyppien keskinäisistä muunnoksista, joten ohjelmoijan huolena on yleensä vain itse ongelmaan keskittyminen. Nollaa pienempien lukujen etumerkkinä käytetään ylämiinusta, koska miinusmerkki on vähennyslaskussa käytettävä funktio. Desimaalierotin on piste, ja tuhaterottimia ei käytetä. Merkkityyppi erotetaan syötettäessä lainausmerkein, tekstin sisäinen lainausmerkki kahdennetaan.

Muuttuja voi rakenteeltaan olla joko skalaari (yksittäinen merkki tai luku) tai sääntiö, moniulotteinen taulukko. Yksiulotteinen muuttuja on vektori, jonka alkiot ovat jonossa (alkioita voi olla myös 0 kappaletta). Kaksiulotteinen muuttuja, matriisi, koostuu riveistä ja sarakkeista, jokaisella rivillä on yhtä monta alkiota. Kolmiulotteisessa muuttujassa, kuutiossa, on tasoja, jotka kaikki koostuvat samanmuotoisista matriiseista.

Yleisesti rakenteinen APL-muuttuja voi olla suorakulmainen n-ulotteinen sääntiö (n:n enimmäisarvo riippuu tulkin implementaatiosta, esimerkiksi APL2 sallii 256-ulotteiset sääntiöt). Suorakulmaisuus tarkoittaa sitä, että moniulotteisen taulukon jokaisessa suunnassa on yhtä monta alkiota (esimerkiksi matriisin jokainen rivi on yhtä pitkä) eikä yhden suunnan pituus riipu muiden suuntien pituuksista.

Muuttujan, itse luodun funktion tai operaattorin nimi ei voi sisältää APL-erikoismerkkejä eikä välilyöntejä. Muuttujalle annetaan arvo sijoitusnuolella, joka voidaan tässä yhteydessä mieltää kaksiargumenttiseksi funktioksi. Muuttujia ei tarvitse alustaa etukäteen, tulkki huolehtii sekä tyypityksestä että tilanvarauksesta suorituksen aikana. Toisen sukupolven APL:t sallivat lisäksi sisäkkäiset tietorakenteet.

Funktioilla voi olla joko yksi (monadinen), kaksi (dyadinen) tai ei yhtään (niladinen) argumenttia. Kaksiargumenttinen funktio on aina argumenttiensa välissä, yksiargumenttinen on argumenttinsa vasemmalla puolella (ns. infix-notaatio). Lisäksi funktio voi joko palauttaa arvon tai ei. APL:n perusfunktiot (primitiivifunktiot) ovat aina argumentillisia ja ne palauttavat arvon. Sama symboli voi kuvata sekä yksi- että kaksiargumenttista funktiota, esimerkiksi miinusmerkki on sekä vähennyslasku- (kaksiargumenttinen) että vastalukufunktion symboli. Funktiot luodaan yleensä erillisen funktioeditorin avulla.

Operaattori voi olla joko yksi- tai kaksioperandinen, ja operaattorin tulosfunktio voi olla lisäksi joko yksi- tai kaksiargumenttinen. Yksioperandinen operaattori on operandifunktionsa oikealla puolella ja kaksioperandinen operandiensa välissä. Joissain APL-tulkeissa voidaan luoda omia operaattoreita (mm. APL2 ja DyalogAPL).

APL-lausekkeen suoritusjärjestys on oikealta vasempaan, ellei sulkein toisin ohjata. Toisin sanoen funktion oikeana argumenttina on sen oikealla puolella olevan lausekkeen arvo.

APL-sovellukset tallennetaan yleensä työtiloihin, joita käsitellään APL-istunnossa. Työtilassa ovat käytettävissä kaikki APL:n perusfunktiot sekä ne APL-objektit jotka sinne on luotu tai kopioitu. Työtila sisältää siten koko työskentely-ympäristön.

Esimerkkejä[muokkaa | muokkaa wikitekstiä]

Ensin se pakollinen Hello World:

'Hello World!'

Hello World!

Sijoitetaan muuttujaan VEC viisi lukua, joista kaksi on nollaa pienempiä:

VEC ← 2 ¯4 6 ¯7 10

Lukujen summan voi laskea sijoittamalla joka luvun väliin yhteenlaskufunktion:

2 + ¯4 + 6 + ¯7 + 10

7

Näppärämpi tapa on käyttää pelkistysoperaattoria (/) ja yhteenlaskufunktiota:

+/ VEC

7

Lukujen tulon voi laskea samalla operaattorilla vain funktiota vaihtaen:

×/ VEC

3360

Vektorin alkioiden lukumäärän saa yksiargumenttisella kokofunktiolla:

⍴VEC

5

Vektorin alkioiden keskiarvo saadaan nyt yhdistämällä lausekkeet:

(+/VEC)÷⍴VEC

1.4

Samaa lauseketta voi tietenkin käyttää myös muihin vektoreihin - sijoitetaan VEC-vektoriin luvut 1-10 kokonaissarjafunktion avulla ja lasketaan keskiarvo.

VEC ← ⍳10
(+/VEC)÷⍴VEC

5.5

APL:n teho tulee esille sitten lukujoukkojen käsittelyssä, lasketaan kokonaislukujen 1-987654 keskiarvo:

(+/VEC)÷⍴VEC ← ⍳987654

493827.5

Seuraava APL-algoritmi etsii kaikki kokonaislukua N pienemmät alkuluvut; kokeillaan ensin N:n arvoa 10:

N←10 ⋄ (~VEC∊VEC∘.×VEC)/VEC←1↓⍳N

2 3 5 7

Lausekkeen toiminnan ymmärtämiseksi luetaan sitä suoritusjärjestyksessä oikealta vasempaan. Muuttujan VEC arvoksi tulevat luvut 1-10, joista pudotusfunktiolla poistetaan ensimmäinen alkio (koska ykköstä ei lasketa alkuluvuksi):

VEC←1↓⍳N ⋄ VEC

2 3 4 5 6 7 8 9 10

Sisätulo-operaattorin ja tulofunktion avulla muodostetaan vektorin alkioiden kertotaulu:

VEC ∘.× VEC
 4  6  8 10 12 14 16 18  20
 6  9 12 15 18 21 24 27  30
 8 12 16 20 24 28 32 36  40
10 15 20 25 30 35 40 45  50
12 18 24 30 36 42 48 54  60
14 21 28 35 42 49 56 63  70
16 24 32 40 48 56 64 72  80
18 27 36 45 54 63 72 81  90
20 30 40 50 60 70 80 90 100

Nyt etsitään ne luvut, jotka sisältyvät kertotauluun (eivätkä siten ole alkulukuja). Etsimiseen sopii APL:n jäsenyysfunktio, joka palauttaa ykkösen, jos vasemman argumentin alkio löytyy oikeasta argumentista, muuten nollan:

VEC ∊ VEC∘.×VEC

0 0 1 0 1 0 1 1 1

Alkulukujen pelkistämistä varten vaihdetaan totuusarvot päinvastaisiksi loogisen negaatiofunktion avulla:

~ VEC∊VEC∘.×VEC

1 1 0 1 0 1 0 0

Lopuksi pelkistetään saadulla bittivektorilla alkuluvut vektorista:

(~VEC∊VEC∘.×VEC)/VEC

2 3 5 7

Etsitään alkuluvut joukosta 1-100:

N←100 ⋄ (~VEC∊VEC∘.×VEC)/VEC←1↓⍳N

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

Algoritmi ei ole kovinkaan tehokas, mm. väliaikaisesti käytetty ulkotulo vaatii hetkellisesti paljon muistia, joten tuotantokäyttöön ei algoritmista juuri ole. Algoritmia voi heti parantaa pienellä koodauksella: pelkistetään alkulukujen 2 ja 3 kerrannaiset pois alkuvektorista ja lisätään ne tuloksen alkuun:

2 3,(~VEC∊VEC∘.×VEC)/VEC←1↓(N⍴1 0 0 0 1 0)/⍳N

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

Lopuksi graafisen käyttöliittymän Hello World -esimerkki DyalogAPL:llä: Luodaan GUI-ikkuna fm, annetaan sen koko pikseleinä ja koodataan sille sinertävä tausväri RGB-koodattuna:

'fm' ⎕WC 'Form' 'Hola Mundo!' ('Coord' 'Pixel') ('Size' 100 310) ('BCol' 153 153 255)

Luodaan fm-objektin lapseksi kirjasinobjekti ja käännetään sitä pii radiaania (180 astetta) Australiaa varten:

'fm.fn' ⎕WC 'Font' 'Times New Roman' ('Size' 64) ('Rotate' (○1))

Kirjoitetaan teksti ikkunaan halutusta sijainnista luotua kirjasinta käyttäen:

'fm.tx' ⎕WC 'Text' 'Hello World' ('Points' 90 300) ('FontObj' 'fm.fn')

Tulos näyttää tältä:

APL helloworld3.gif

Aiheesta enemmän[muokkaa | muokkaa wikitekstiä]