Johdantoa ohjelmointikielten periaatteisiin



Samankaltaiset tiedostot
Tällä kurssilla tarkastellaan ohjelmointikieliä. Lienee tarpeen yrittää rajata, mitä

Johdanto Meta Kielten jaotteluja Historia. Aloitusluento. TIES542 Ohjelmointikielten periaatteet, kevät Antti-Juhani Kaijanaho

1. Olio-ohjelmointi 1.1

815338A Ohjelmointikielten periaatteet

Ohjelmointikielten periaatteiden taustaa

OHJELMOINTIKIELTEN PERIAATTEET ANTTI-JUHANI KAIJANAHO

TIEA341 Funktio-ohjelmointi 1, kevät 2008

Ohjelmointikielen määritteleminen (tai edes tyhjentävä luonnehtiminen) on todella vaikeaa. Voisi yrittää vaikka näin:

4. Lausekielinen ohjelmointi 4.1

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 3. joulukuuta 2015

Aloitus. TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 14. maaliskuuta 2011 TIETOTEKNIIKAN LAITOS. Aloitus.

TIEA255 Tietotekniikan teemaseminaari ohjelmointikielet ja kehitysalustat. Antti-Juhani Kaijanaho. 16. helmikuuta 2011

Ohjelmointikielten periaatteet. Antti-Juhani Kaijanaho

ELM GROUP 04. Teemu Laakso Henrik Talarmo

Ohjelmointikielten periaatteet. Antti-Juhani Kaijanaho

Rajoittamattomat kieliopit (Unrestricted Grammars)

Ohjelmointikielten kehityshistoriaa

.NET ajoympäristö. Juha Järvensivu 2007

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 30. marraskuuta 2015

PERL. TIE Principles of Programming Languages. Ryhmä 4: Joonas Lång & Jasmin Laitamäki

812341A Olio-ohjelmointi, I Johdanto

Sisällys. Ratkaisumallien historia. Ratkaisumalli. Ratkaisumalli [2] Esimerkki: Composite [2] Esimerkki: Composite. Jaakko Vuolasto 25.1.

Ohjelmointikielten periaatteet. Antti-Juhani Kaijanaho

Tähtitieteen käytännön menetelmiä Kevät 2009

815338A Ohjelmointikielten periaatteet

Ohjelmointikielten periaatteet Syksy Antti-Juhani Kaijanaho

Hajautettujen sovellusten muodostamistekniikat, TKO_2014 Johdatus kurssiin

Ruby. Tampere University of Technology Department of Pervasive Computing TIE Principles of Programming Languages

Lisää pysähtymisaiheisia ongelmia

11.4. Context-free kielet 1 / 17

TIE542 Ohjelmointikielten periaatteet, syksy Antti-Juhani Kaijanaho. 6. syyskuuta 2010

Tyyppiluokat II konstruktoriluokat, funktionaaliset riippuvuudet. TIES341 Funktio-ohjelmointi 2 Kevät 2006

C++ Ohjelmoijan käsikirja. Johdanto

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. FT Ari Viinikainen

.NET ja C# Virtuaalikone. Common Language Infrastructure (CLI) Periaate. Etuja. Haittoja. Mikä on CLI. CLI standardin merkitys (CLS, Ecma)

Concurrency - Rinnakkaisuus. Group: 9 Joni Laine Juho Vähätalo

Ongelma(t): Miten jollakin korkeamman tason ohjelmointikielellä esitetty algoritmi saadaan suoritettua mikro-ohjelmoitavalla tietokoneella ja siinä

Haskell ohjelmointikielen tyyppijärjestelmä

Sisällys. JAVA-OHJELMOINTI Osa 1: Ohjelmoinnin perusteita. Ohjelmoinnin kehityssuuntia. Ohjelmointi luvuilla. Ohjelmointi luvuilla

11/20: Konepelti auki

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 3. lokakuuta 2016

Maarit Harsu. O h j e l m o i n t i k i e l e t Periaatteet, käsitteet, valintaperusteet

Imperatiivisten ohjelmien organisointiparadigmojen. historia

Imperatiivisten ohjelmien organisointiparadigmojen historia

4. Lausekielinen ohjelmointi 4.1

Common Lisp Object System

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. II Johdanto olio-ohjelmointiin

1. Universaaleja laskennan malleja

Varhaiset oliokielet Modula, CLU ja Smalltalk. T : Seminar on the History of Programming Languages Kari Koskinen Otaniemi 29.9.

VHDL/Verilog/SystemC. Jukka Jokelainen


Johdatus ohjelmointiin

tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla

Ohjelmointikielien kehittyminen

Chapel. TIE Ryhmä 91. Joonas Eloranta Lari Valtonen

Pilveä standardisoidaan monessa ryhmässä

815338A Ohjelmointikielten periaatteet Harjoitus 7 Vastaukset

Esimerkki 1: Kahviautomaatti.

5. HelloWorld-ohjelma 5.1

TIES542 kevät 2009 Yhteismuistisamanaikaisuus

T Olio-ohjelmointi Osa 5: Periytyminen ja polymorfismi Jukka Jauhiainen OAMK Tekniikan yksikkö 2010

etunimi, sukunimi ja opiskelijanumero ja näillä

AS C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin

Ohjelmoinnin peruskurssien laaja oppimäärä

Rekursiolause. Laskennan teorian opintopiiri. Sebastian Björkqvist. 23. helmikuuta Tiivistelmä

Tietotekniikan valintakoe

Matematiikan ohjelmointi. Joakim von Wright

Olio-ohjelmointi Johdanto olio-ohjelmointiin

lausekkeiden tapauksessa. Jotkin ohjelmointikielet on määritelty sellaisiksi,

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 12. lokakuuta 2016

Laskennan teoria

TIES542 kevät 2009 Tyyppijärjestelmän laajennoksia

Ohjelmistojen mallintaminen, mallintaminen ja UML

Täydentäviä muistiinpanoja laskennan rajoista

Algoritmit 1. Luento 3 Ti Timo Männikkö

kontrollivuon analyysejä optimointiensa tueksi ja myös tiettyjen merkitysopillisten

Koodi. Antti-Juhani Kaijanaho. 11. marraskuuta Sisältö

Ohjelmoinnista. Ohjelmien toteutukseen tarjolla erilaisia välineitä:

Tarvitseeko informaatioteknologia matematiikkaa?

TIE Principles of Programming Languages CEYLON

T Ohjelmistojen määrittely- ja suunnittelumenetelmät

Teollisuusautomaation standardit Osio 9

Laskennan rajoja. TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 10. joulukuuta 2015 TIETOTEKNIIKAN LAITOS.

Algoritmin määritelmä [Sipser luku 3.3]

Käyttöjärjestelmien historia. Joni Herttuainen Henri Jantunen Markus Maijanen Timo Saksholm Johanna Tjäder Eetu Turunen

Attribuuttikieliopit

Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 5. marraskuuta 2015

Ohjelmoinnin peruskurssien laaja oppimäärä

5. HelloWorld-ohjelma 5.1

Algoritmit 1. Luento 2 Ke Timo Männikkö

Edward Sapir ja Benjamin Whorf esittivät viime vuosisadan alkupuolella kielitieteellisen


Se mistä tilasta aloitetaan, merkitään tyhjästä tulevalla nuolella. Yllä olevassa esimerkissä aloitustila on A.

Opettajatuutorointi-kurssin syksyn 2006 kyselyjen tulokset

Staattinen metaohjelmointi

Johnson, A Theoretician's Guide to the Experimental Analysis of Algorithms.

Computing Curricula raportin vertailu kolmeen suomalaiseen koulutusohjelmaan

TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 31. maaliskuuta 2011

Transkriptio:

Johdantoa ohjelmointikielten periaatteisiin Antti-Juhani Kaijanaho 12. tammikuuta 2009 1 Kurssin järjestelyitä 1.1 Opettajat Luennot Antti-Juhani Kaijanaho (antti-juhani.kaijanaho@jyu.fi), Ag C416.1, vastaanotto ke 12 14 Demot Ville Tirronen (ville.tirronen@jyu.fi), Ag C415.2, vastaanotto ti 12 14 1.2 Kurssikuvaus Ohjelmointikielten historiaa. Lausekielten periaatteet ja toteutustekniikan perusteet. Lausekekielten periaatteet. Oliokielten periaatteet. Ohjelmointikielten formaali määrittely ja keskeiset formaalit arkkityypit (mm. lambda-, sigma- ja piilaskento sekä systeemi F). Tyyppijärjestelmien teorian perusteet. Yhtäaikaisuuden hallinta ohjelmointikielissä. 1.3 Esitiedot Automaatit ja kieliopit sekä joko Diskreetit rakenteet, (matematiikan) Approbatur 3 tai matematiikan cum laude -opintoja. Käytännön ohjelmointitaito on välttämätön. 1.4 Tavoitteet 1) Nostaa opiskelijoiden ohjelmointikielikäsityksen abstraktiotasoa. 2) Valmentaa opiskelijat arvioimaan ohjelmointikieliä eri kriteereillä. 3) Antaa opiskelijoille riittävät teoreettiset työkalut ohjelmointikielten tutkimuksen seuraamiseen. 1

1.5 Lähiopetus Luennot 18 kertaa à 90 min maanantaisin klo 12 14 ja tiistaisin klo 10 12 ajalla 12.1. 10.3.2009. Luennot alkavat vartin yli; luennoilla pidetään tavallisesti luentotauko. Demotilaisuudet 9 kertaa à max 105 min tiistaisin klo 14 16 ajalla 20.1. 17.3.2009. Demotilaisuus aloitetaan vartin yli ja jatkuu (pääsääntöisesti) tauotta, kunnes kaikki tehtävät on käsitelty tai aikaraja tulee vastaan. Demotehtävät julkaistaan viimeistään demotilaisuutta edeltävänä keskiviikkona. Kurssiin ei tällä kertaa liity opiskelijaseminaaria. 1.6 Suoritustavat Oppimispäiväkirja on suositeltava tapa suorittaa kurssi. Oppimispäiväkirjaa kirjoitetaan kurssin kuluessa päiväkirjanomaisesti, pääsääntöisesti merkintä jokaiselta lähiopetuskerralta, jolla opiskelija on läsnä. Päiväkirjassa tarkoituksena on pohdiskella ja tarkastella käsiteltyjä asioita itsenäisesti, kyse ei ole perinteisistä luentomuistiinpanoista. Päiväkirjan tulee kattaa vähintään 14 luentokertaa (ellei jollakin kerralla ole force majeure -estettä). Tentti on perinteinen muistiin perustuva neljän tunnin koe, joka tehdään valvotussa koetilanteessa 3.4., 15.5. tai 3.7.2009 (kello 12:00 Agorassa). Tenttiin tulee ilmoittautua Korpin kautta. Tentti ei ole tarpeen, jos oppimispäiväkirja on hyväksytysti suoritettu. Kurssiin ei tällä kertaa liity opiskelijaseminaaria. 1.7 Arviointiperusteet Hyväksyttävään suoritukseen vaaditaan, että opiskelija osoittaa ymmärtävänsä keskeiset asiat vähintäänkin pinnallisesti mutta oikein. Tyypillinen tapa osoittaa tällainen ymmärrys on keskeisten asioiden toistaminen omin sanoin oppimispäiväkirjassa tai tentissä taikka alla esitettyjen vaativampien kriteerien täyttäminen. Pelkkä sanatarkka opetusmateriaalin kopioiminen tenttivastaukseen saati oppimispäiväkirjaan ei pääsääntöisesti riitä! Pääsääntö: mitä korkeampi arvolause, sitä syvällisempää osaaminen. Korkeimmat arvolauseet vaativat myös jonkin verran akateemista kypsyyttä. Arvolauseesta 2 alkaen vaaditaan, että opiskelija kykenee soveltamaan keskeisiä asioita tyypillisissä tilanteissa. Oppimispäiväkirjassa tai tentissä tällainen osaa- 2

mistaso osoitetaan esim. antamalla onnistuneita omatekoisia esimerkkejä ja käyttämällä kurssin tietoja onnistuneesti ongelmanratkaisuun. Arvolauseesta 3 alkaen vaaditaan, että opiskelija kykenee analysoimaan keskeisiä asioita. Oppimispäiväkirjassa tai tentissä tällainen osaamistaso osoitetaan tavallisesti esimerkiksi purkamalla käsitteitä osiinsa, tekemällä onnistuneita päätelmiä tai yleistyksiä, erottelemalla olennaisuudet epäolennaisuuksista sekä osoittamalla, mihin laajempaan kontekstiin kukin asia liittyy. Arvolauseesta 4 alkaen vaaditaan, että opiskelija kykenee luovaan synteesin. Tämän saavuttamiseen ei voi antaa reseptinomaista ohjetta, vaan oppimispäiväkirjasta tai tenttivastauksesta on käytävä ilmi opiskelijan luovuus ja omaperäisyys sovellettuna kurssin keskeisiin aiheisiin menemättä hölynpölyn puolelle. Yleensä hyvä lähtökohta on aloittaa soveltamisesta ja analyysistä. Arvolauseeseen 5 vaaditaan, että opiskelija kykenee kurssin aihepiiriin liittyvään itsenäiseen, kriittiseen ajatteluun. Tämänkään saavuttamiseen ei voi antaa reseptinomaista ohjetta. Opiskelija, joka saavuttaa tämän osaamistason, kykenee arvioimaan kurssin sisältöjä kriittisesti ja perustelemaan kritiikkinsä asianmukaisesti. Arvolausetta voidaan alentaa tenttivastauksissa tai oppimispäiväkirjassa olevien jatkuvien huolimattomuudesta johtuvien pienten asiavirheiden tai yksittäisten merkittävien asiavirheiden johdosta. Oppimispäiväkirjan tai tenttivastauksen kielija ulkoasulla ei ole merkitystä arvioinnissa, jos se ei haittaa ymmärtettävyyttä. Oppimispäiväkirja arvioidaan kokonaisuutena. Tehdyistä demotehtävistä annetaan hyvitys, joka korottaa oppimispäiväkirjalla tai tentillä saavutettua hyväksyttyä arvolausetta. Hyvitykseen lasketaan vain demotilaisuudessa tehdyiksi merkityt tehtävät, ellei Ville anna erityisestä syystä lupaa palauttaa tehtäviä muulla tavoin. 1.8 Kirjallisuus Kurssilla ei ole varsinaista kurssikirjaa, mutta luennot perustuvat osittain John C. Reynoldsin kirjaan Theories of Programming Languages (Cambridge University Press, 1998), jota on yliopiston kurssikirjastossa yksi lainakappale (14 vrk.) ja yksi lukusalikappale. Kirjastokappaleet olisi tosin suotavaa jättää itseopiskelijoiden käyttöön. Täydentävää luettavaa löytyy Korpin (ja opinto-oppaan) kurssikuvauksen kirjallisuuskohdasta. 3

Kurssin voi suorittaa kirjallisuuteen perustuvana lukukurssina, joka on ensisijaisesti tarkoitettu ulkomaalaisille opiskelijoille (ja siksi ohjeet on englanniksi). Katso tarkemmin kurssin kotisivuilta. 2 Ohjelmoinnista Ohjelmointi on ongelmien ratkaisemista. Asiaa voi katsoa kahdelta kannalta: voi keskittyä ymmärtämään ongelmaa tai ratkaisumalleja. Voidaan ajatella, että maailma jakautuu kahteen osaan, ongelma-avaruuteen ja ratkaisuavaruuteen. Ohjelmoijan tehtävänä on siirtää ongelma (joka elää ongelma-avaruudessa) ratkaisuavaruuteen, jolloin siitä tulee ratkaisu. Ohjelmointikieli on ohjelmoijan pääasiallisin työkalu, ja kielen toteutus (kääntäjä tai tulkki) auttaa ohjelmoijaa ratkaisun luomisessa: kielen ominaisuudet ratkaisevat, kuinka syvälle ratkaisuavaruuteen ohjelmoijan tulee ongelmaansa viedä ja mistä lähtien kielen toteutus tekee sen ohjelmoijan puolesta. 3 Mikä on ohjelmointikieli Tällä kurssilla tarkastellaan ohjelmointikieliä. Lienee tarpeen yrittää rajata, mitä tuo käsite tarkoittaa. Käytännössä tuo käsite on riittävän hyvin ymmärrettävissä, että kaikki sen tietävät. Vai tietävätkö? Olen monta kertaa itse törmännyt ihmisiin, jotka kiven kovaan puhuvat HTML:stä ohjelmointikielenä. Minä en pidä sitä ohjelmointikielenä (eikä moni muukaan), mutta miten sen voisi rajata jollakin yleisellä säännöllä käsitteen ohjelmointikieli ulkopuolelle? Ohjelmointikielen määritteleminen (tai edes tyhjentävä luonnehtiminen) on todella vaikeaa. Voisi yrittää vaikka näin: Ohjelmointikieli on väline, jolla ihminen kertoo tietokoneelle, mitä sen pitäisi tehdä. Ihan hyvä tuo on ensimmäiseksi yritykseksi. Siinä on kuitenkin ongelma. Se ei rajaa joitakin tärkeitä ei-ohjelmointikieliä pois: WIMP-käyttöliittymä (windows, images, menus and pointers) on väline, jolla ihminen kertoo tietokoneelle, mitä sen pitäisi tehdä. Samoin HTML tulee tulkituksi ohjelmointikieleksi. Tuosta ensimmäisestä yrityksestä puuttuu jotain oleellista: ohjelmointikielen täytyy olla ilmaisuvoimainen. Tässä päädytään äkkiä hyvin syvällisiin kysymyksiin mekaanisen laskennan ja muun sellaisen olemuksesta. Tässä riittänee muistaa, 4

mitä Automaatit ja kieliopit -kurssilla puhuttiin Turingin koneesta: se on idealisoitu tietokone, yksinkertainen kone, joka kykenee ratkaisemaan kaikki mekaanisesti ratkaistavissa olevat ongelmat. Ehkäpä Turingin koneesta löytyisi sopiva mitta ohjelmointikielen ilmaisuvoimalle. Voidaan esittää vaikkapa seuraavanlainen uusi yritelmä määritelmäksi: Ohjelmointikieli on väline, jolla ihminen kertoo tietokoneelle, mitä sen pitäisi tehdä ja jolla voidaan saada tuo kone simuloimaan universaalia Turingin konetta. Tässä määritelmässä on myös ongelmansa. Todelliset tietokoneet toimivat todellisessa maailmassa, jossa on ainainen resurssipula: olipa esimerkiksi muistia kuinka paljon tahansa, aina sillä on jokin raja. Turingin koneella puolestaan on ääretön nauha. Ehkäpä tätä voisi korjata raja-arvotarkastelulla: Tarkastellaan välinettä, jolla ihminen kertoo tietokoneelle, mitä sen pitäisi tehdä. Tämä väline on ohjelmointikieli, mikäli periaatteessa niiden ongelmien joukko, jotka on kuvattavissa tuolla välineellä niin, että tuon kuvauksen perusteella kyseinen tietokone kykenee ratkaisemaan ne, lähestyy rajatta Turingin koneella ratkaistavien ongelmien joukkoa, kun koneen resurssirajat kasvavat rajatta. Tämä saattaa olla oikein tai voi olla olematta. Tämä määritelmä on hankala, käyttää vaikeita käsitteitä eikä käytä niitä edes mitenkään oikealla tavalla. Muutama erottelu on kuitenkin tehtävä selväksi. Tällä kurssilla ei puhuta dokumentinkuvauskielistä (kuten HTML) paitsi jos ne ovat toisaalta myös ohjelmointikieliä (heh! viittaan tässä TEXiin ja Postscriptiin). Myös spesifiointikielet (kuten Z ja B) jätetään kurssin ulkopuolelle (Formaalien menetelmien kurssilla puhutaan niistä) ohjelmointikielen määritelmään täytyy jotenkin lisätä se, että kielellä kirjoitetut ohjelmat pitää olla käännettävissä algoritmisesti konekielelle. 4 Historia 4.1 Kaksi ensimmäistä sukupolvea: ennen vuotta 1955 Ensimmäiset ohjelmointikielet olivat konekieliä ja niillä kirjoitetut ohjelmat olivat bittijonoja tietokoneen muistissa. Ohjelmat syötettiin koneelle kytkimiä kääntelemällä. Konekieli on ratkaisuavaruuden sydämessä: konekielellä ei ole kääntäjää tai tulkkia, joka auttaisi ihmistä ongelman tuomisessa ratkaisuavaruuteen. Seuraavassa on Hello World -ohjelma erään tietokoneen konekiellä (esitettynä 16-lukujärjestelmässä tavujonona). 5

980901013d6e185798020100980600036f686a656c6d612e6d6d7300 98070002f4ff00000000070100000000980400039807000748656c6c 980700076f2c2057980700076f726c6498070007210a0000980a00ff 0000000000000100980b0000203a4050104040204d20612069026e01 00812053207410100272010c82000000980c0008 Kyseinen kone on Donald E. Knuthin legendaarisen kirjasarjansa The Art of Computer Programming uusia laitoksia varten suunnittelema RISC-prosessori MMIX 2009 1. Ohjelmien kirjoittaminen konekielellä on erittäin virhealtista ja toisaalta hyvin mekaanista puuhaa. Jo hyvin varhaisessa vaiheessa alettiin kirjoittaa ohjelmia, jotka auttoivat tässä prosessissa. Ihmiset kirjoittivat sopivalla tavalla muotoiltua tekstiä, ja nämä ohjelmat muunsivat sen konekieleksi. Tyypillisesti tässä syötteessä yksi rivi vastaa yhtä konekielen käskyä. Tätä ohjelmointikieltä kutsutaan symboliseksi konekieleksi (engl. assembler language), ja ohjelmaa, joka kääntää tällä kirjoitetun ohjelman konekielellä, sanotaan assembleriksi. Edellä esitetty ohjelma MMIX:n symbolisella konekielellä (MMIXAL) kirjoitettuna näyttää tältä: LOC #100 Main GETA $255,Str TRAP 0,Fputs,StdOut TRAP 0,Halt,0 Str BYTE "Hello, World!" BYTE #0a Konekielet muodostavat ohjelmointikielten ensimmäisen sukupolven ja symboliset konekielet ohjelmointikielten toisen sukupolven. Ongelmana näissä on ohjelmoinnin virhealttius ja vahva mekaanisuus sekä se, että jokaisella konetyypillä on oma konekielensä ja sitä vastaava symbolinen konekieli. Ohjelmia ei voitu siirtää konetyyppien välillä, vaan ne jouduttiin kirjoittamaan uudestaan aina kullekin uudelle konetyypille. 4.2 Automaattinen ohjelmointi ja ohjelmointikielten synty: 1955 1960 Ongelman ratkaisuksi esitettiin automaattista ohjelmointia, joksi sitä silloin 1950-luvun alkupuolella sanottiin. Kyse oli siitä, että ohjelmoija esittää tietokoneelle ongelman kuvauksen jollakin formaalilla kielellä, ja jokin erityinen ohjelma 1. Donald E. Knuth. MMIXware: A RISC Computer for the Third Millennium. Lecture Notes in Computer Science 1750. Berliini, Springer 1999. Katso myös sivua http://www-cs-staff. stanford.edu/~knuth/mmixware.html 6

tuottaa siitä konekielisen ohjelman, joka ratkaisee ongelman. Eivät ne formaalit kielet mitenkään kummoisia olleet, mutta senaikaiseen tietämykseen nähden ne olivat tekoälytutkimuksen (josta ei tuota nimeä vielä käytetty) huippua. Nykyään näitä formaaleja kieliä sanotaan korkean tason tai kolmannen sukupolven ohjelmointikieliksi ja ohjelmia, jotka tekevät niillä kirjoitetuista ongelmakuvauksista konekielisiä ohjelmia, sanotaan kääntäjiksi (compiler). Näitä varhaisia kieliä on esitelty Knuthin ja Trabb Pardon artikkelissa vuodelta 1977 2. Automaattiseen ohjelmointiin eivät useimmat ihmiset uskoneet, ennen kuin Fortran tuli kuvioihin 1950-luvun lopulla ensimmäinen versio julkaistiin keväällä 1957, mutta kielestä oli siinä vaiheessa puhuttu jo monta vuotta. Fortran oli ensimmäinen merkittävää kannatusta saavuttanut korkean tason ohjelmointikieli (ja kiinnostavaa kyllä, edelleen laajassa käytössä, tosin reilusti muuttuneena). Ensimmäinen Fortran-kääntäjä oli vaikea tehtävä: sitä tehtiin kolme vuotta ja siihen kului 18 ihmistyövuotta. Tätä työtä johti John Backus, joka on myöhemminkin ollut merkittävä tekijä ohjelmointikieliteknologian alalla. Fortanin merkitys ohjelmointikielten kehitykselle on kiistaton. Se oli alan pioneerityö: se sai ihmiset uskomaan korkean tason ohjelmointikieliin ylipäätään. Lisäksi monet sen ominaisuudet ovat edelleen ohjelmointikielissä tärkeitä: taulukkomuuttujat, muuttujan ohjaamat silmukat (ns. for-silmukat) sekä haarautuva if-lause (if statement) ovat nykykielissäkin peruskamaa. Fortran oli tarkoitettu tieteellisen laskennan ohjelmien kirjoittamiseen. John McCarthy, tekoälytutkimuksen kantaisä, halusi kielen symbolista tiedonkäsittelyä (esimerkiksi algebrallisten funktioiden symbolista derivointia) varten. McCarthy ja muutamat muut laajensivat Fortrania aluksi symbolista laskentaa varten, mutta tämän rajat tulivat pian vastaan. He aloittivat uuden kielen, Lispin, kehittämisen ensin paperilla ja käsikääntäen sillä kirjoitettuja ohjelmia paperille. Kun sitten huomattiin, että teoreettiseksi leluksi tarkoitettu Lisp-funktio eval toimii mainiosti Lisp-tulkkina, oli Lisp-toteutus valmis 3. Fortranin tapaan Lispin merkitys myöhemmille ohjelmointikielille on merkittävä. Lispin mukana näkivät päivänvalon mm. rekursiiviset aliohjelmat, muistinsiivous (garbage collection) ja if-lauseke (if expression). Nykyisin Lispistä on käytössä kolme merkittävää murretta: Emacs Lisp, Common Lisp ja Scheme. 2. Donald E. Knuth ja Luis Trabb Pardo. The Early Development of Programming Languages. Julkaistu alunperin J. Belzerin, A. G. Holzmanin ja A. Kentin toimittamassa kirjassa Encyclopedia of Computer Science and Technology, vol. 6, New York, Dekker, 1977. Julkaistu uudelleen mm. N. Metropolisin, J. Howlettin ja Gian-Carlo Rotan toimittamassa kirjassa A History of Computing in the Twentieth Century, New York, Academic Press, 1980. 3. John McCarthy. History of LISP. ACM SIGPLAN Notices, vol. 13, no. 8, August 1978 (preprints, ACM SIGPLAN History of Programming Languages Conference). 7

Algoritmien julkaisemiseen kehitettiin komiteatyönä 1950-luvun lopulla uusi kieli, Algol (tämän sanotaan usein olevan lyhenne sanoista Algorithmic language, mutta se viittaa myös samannimiseen kolmoistähteen). Algol 60 4 oli kolmas 1950-luvun loppupuolella kehitetty kieli, jolla on ollut merkittävää merkitystä ohjelmointikielten tulevalle kehitykselle. Algol 60 oli ensimmäinen lohkorakenteinen kieli. Sillä oli vapaamuotoinen, rakenteinen syntaksi. Siinä oli muuttujien tyyppien esittelyt ja arvovälitteiset (call-by-value) aliohjelmaparametrit. Nämäkin kaikki ovat lähes välttämättömiä nykykielissä. Tony Hoare kirjoitti Algol 60:stä vuonna 1973 seuraavasti: Tässä on kieli, joka on niin edellä aikaansa, että se oli paitsi edeltäjiään myös lähes kaikkia seuraajiaan parempi. 5 1950-luvun lopulla kehitettiin myös kaksi muuta suosiota saavuttanutta kieltä, Cobol ja APL. Kummankin merkitys ohjelmointikielten kehitykselle kokonaisuutena on kuitenkin vähäinen, joten niihin ei tämän enempää puututa. 4.3 Baabelin torni: 1960-luku 1960-luvulla suunniteltiin satoja uusia ohjelmointikieliä, joista hyvin harva jäi eloon. Nimet Adam, AED, Altran, CLP, Dyana ja Unicode eivät nykyään liity ohjelmointikieliin lainkaan mutta ne kaikki olivat vuonna 1967 käytössä olleita ohjelmointikieliä. Monet näistä kielistä oli tarkoitettu johonkin erityiseen tarkoitukseen. Algol-perhe sai uuden jäsenen, Algol 68:n, joka kokonsa ja vaikealukuisen määrittelynsä 6 vuoksi sai huonon maineen ja jäi pääosin käyttämättä. Samoihin aikoihin Niklaus Wirth ja Tony Hoare suunnittelivat oman seuraajansa Algol 60:lle, jota on kutsuttu Algol W:ksi. Norjalaiset Kristen Nygaard ja Ole-Johan Dahl kehittivät Simula-kielen simulointien kirjoittamiseen. Simulan merkitys nykykielille on ollut valtava, samaa suuruusluokkaa kuin Algol-perheen ja Lispin: Simulasta alkoi olio-ohjelmoinnin perinne jo Simula I:n yhteydessä puhuttiin olioista ja luokista. Perintä lisättiin Simula 67:ään. David Farber, Ralph Griswold ja Ivan Polonsky kehittivät Snobol-kielen merkkijonojen käsittelyä varten 1962. Snobol vaikutti suuresti tulevien kielten (esimerkiksi Perlin) merkkijono-ominaisuuksiin. 4. Peter Naur (toim.), J. W. Backus ym. Revised Report on the Algorithmic Language AL- GOL 60. Communications of the ACM, vol. 6 no. 1, January 1963. 5. C. A. R. Hoare. Hints on programming-language design. Julkaistu mm. C. A. R. Hoaren ja C. B. Jonesin kirjassa Essays in Computer Science, New York, Prentice Hall, 1989. 6. A. van Wijngaarden ym. (toimm.). Revised Report on the Algorithmic Language Algol 68, Berliini, Springer, 1976. 8

1960-luvun lapsia on myös BASIC. Dartmouth Collegessa haluttiin luoda tietokonejärjestelmä ja sille ohjelmointikieli, jotka ovat niin helppoja, että niiden käyttöä voitaisiin opettaa kaikille humanisteille. BASIC sai monia vaikutteita Algol 60:stä, mutta jätti monta (näin jälkiviisaasti sanoen: hyvin tärkeätä) sen ominaisuutta pois. Esimerkiksi lohkorakenne tiputettiin pois, koska sitä ei haluttu selittää humanisteille 7. IBM:n ja muun teollisuuden yhteistyönä kehitettiin 60-luvulla PL/I (oikeastaan PL/1, mutta ykkönen on tapana tässä tapauksessa kirjoittaa isona I-kirjaimena), joka oli yritys luoda eräänlainen universaali ohjelmointikieli. Aiemmin oli ohjelmointitehtävät ja ohjelmoijat jakautuneet kahteen selvään ryhmään: tieteellinen laskenta, jossa tarvittiin liukulukulaskentaa, taulukoita ja aliohjelmia, sekä hallinnollinen tietojenkäsittely, jossa tarvittiin kiintolukulaskentaa (fixed-point arithmetic), tehokasta siirräntää (input/output) ja merkkijonojen käsittelyä. 1960- luvulla tämä jako alkoi hämärtyä, ja eräs PL/I:n oleellisimmista tavoitteista oli toimia molempien ryhmien ohjelmointikielenä. Kieli oli 60- ja 70-luvuilla varsin suosittu ja IBM tukee sitä edelleen, mutta nykyisin sitä pidetään (yhdessä Algol 68:n kanssa) lähinnä varoittavana esimerkkinä laajasta ja vaikeasta kielestä. PL/I oli ensimmäinen ohjelmointikieli, joilla on muodollisesti (PL/I:n tapauksessa VDM:llä) määritelty merkitysoppi (semantics). 4.4 Modernismin alku: 1970-luku 1970-luvulla alettiin rakentaa edellisen vuosikymmenen Baabelin tornin raunioiden päälle. Tärkeinä lähtökohtina pidettiin kielen yksinkertaisuutta ja johdonmukaisuutta. Samaan aikaan puhuttiin paljon rakenteisesta ohjelmoinnista 8 (structured programming), ja monet 70-luvulla suunnitelluista kielistä oli nimenomaisesti suunniteltu rakenteista ohjelmointia ajatellen. 1970-luvun kielet ovat ensimmäisiä, joita voi kutsua moderneiksi. Edellisinä kahtena vuosikymmenenä oli kehitetty niin paljon kieliä, että niiden virheistä saattoi oppia jotain merkittävää. 1970-luvun jälkeen on myöskin ilmaantunut hyvin vähän radikaaleja, uusia ideoita ohjelmointikielten alalla kielet ovat kyllä kehittyneet mutta vähittäin. Niklaus Wirth ei todellakaan pitänyt Algol 68:sta. Hän alkoi suunnitella uutta kieltä Algol-perinteen sisällä aiemman Algol W:nsä pohjalta. Tulos oli Pascal, toisaalta opetukseen mutta toisaalta myös käytännön ohjelmointityöhön tarkoitettu 7. Thomas E. Kurtz. BASIC. ACM SIGPLAN Notices, vol. 13, no. 8, August 1978 (preprints, ACM SIGPLAN History of Programming Languages Conference). 8. O.-J. Dahl, E. W. Dijkstra ja C. A. R. Hoare. Structured Programming, Lontoo, Academic Press, 1972. 9

kieli. Pascalin eräs varhainen, aikoinaan suosittu toteutus perustui samantyyppiselle virtuaalikoneratkaisulle kuin Java nykyisin. Toinen Algol-perinteeseen kytkeytynyt uusi kieli oli Dennis Ritchien C. C oli tarkoitettu raakaan järjestelmäohjelmointiin: sillä oli tarkoitus kirjoittaa (ja kirjoitettiinkin) UNIX kokonaan uudestaan. C:n merkitystä myöhemmille kielille on vaikea yliarvioida, vaikka se sinänsä ei sisältänytkään juuri mitään kieliteknologista uutta sen merkittävyys johtuu siitä, että se on erittäin suosittu. Olio-ohjelmointi ei vielä 1970-luvulla ollut kovin merkittävässä asemassa. Xeroxin PARC-laboratorioissa kehitettiin WIMP-käyttöliittymää, ja merkittävä osa tätä kehitystyötä oli Smalltalk-kielen kehitys. Smalltalk on edelleen yksi puhtaimmista oliokielistä. Itse kieli on hyvin pieni, mutta sen peruskirjasto on järkyttävän suuri. Funktio-ohjelmointi oli 1970-luvulla rajoittunut lähinnä Lisp-sukuisten kielten käyttöön. Robin Milner kehitti Edinburghin yliopiston päättelyavustimen käyttöön metakielen (kielen, jolla kuvataan kieliä), jota hän kutsui ML:ksi (lyhenne sanasta meta-language). Sen tapa ajatella ohjelmia sai paljon vaikutteita Lispistä mutta sen syntaksi on Algol-tyyppinen. ML:n ehkä suurin merkitys ohjelmointikielten kehitykselle on Hindley Milner-tyyppijärjestelmä 9. Samoihin aikoihin Guy Lewis Steele, Jr. ja Gerald Jay Sussman kehittivät uutta Lisp-varianttia, jonka he nimesivät Schemeksi. Scheme käytti Lispin omintakeista Cambridgen-puolalaista 10 syntaksia mutta otti käyttöön Algoleista tutun lohkorakenteisuuden. Schemen kehittäjät olivat vahvasti sitä mieltä, että aliohjelmakutsun ei todellakaan tarvitse olla hidas operaatio 11, ja he suunnittelivat kielensä (ja sen toteutukset) tuon käsityksen ympärille. Schemen määrittelyyn kuuluu edelleen vaatimus häntäkutsun poistamisesta (tähän palattaneen tuonnempana), mitä juuri mikään muu kieli ei nykyisin vaadi, vaikka syytä olisi. 1970-luvun alussa syntyi ohjelmointikieli nimeltään Prolog, joka oli täysin erilainen kuin aiemmat kielet, eikä nykyisistäkään kielistä kovin monta samantyyppistä löydy. Prologin perusidea on predikaattilogiikan kaavojen tulkitseminen proseduraalisesti siten, että ohjelma koostuu kaavoista, jotka tulkitaan aliohjelmiksi, ja jonkin näistä aliohjelmista kutsuminen vastaa sitä vastaavan kaavan todistamista muiden toimiessa aksioomina ja päättelysääntöinä. 9. Robin Milner: A Theory of Type Polymorphism in Programming. Journal of Computer and System Sciences, vol. 17, no. 3, December 1978. 10. John McCarthy. History of LISP. emt. 11. Guy Lewis Steele, Jr. Debunking the Expensive Procedure Call Myth or, Procedure Call Implementations Considered Harmful or, LAMBDA: The Ultimate GOTO. Julkaistu James K. Kethchelin ym. toimittamassa konferenssijulkaisussa Proceedings of the 1977 annual conference, ACM, 1977. 10

4.5 Olio-ohjelmoinnin ja juontokielten nousu: 1980-luku 1980-lukua voi hyvällä syyllä sanoa olio-ohjelmoinnin popularisoinnin vuosikymmeneksi. Tällä vuosikymmenellä kehitettiin monta merkittävää olio-ohjelmointiin käytettyä kieltä. Samalla myös funktio-ohjelmoinnin tutkimus eteni, ja vaikka funktio-ohjelmointi ei saavuttanutkaan samaa suosiota kuin olio-ohjelmointi, myös sen kannalta merkittäviä kieliä kehitettiin. 1980-luvun alussa alkoi Bjarne Stroustrup kehitellä oliolaajennusta Ritchien C- kieleen. Hän kutsui tuota kieltä nimellä C with classes, mutta varsin pian nimi vaihtui C++:ksi. Vaikka C++ alkoikin oliokielenä, on siihen myöhemmin lisätty paljon muitakin ohjelmointityylejä tukevia ominaisuuksia esimerkiksi C++:n tyyppijärjestelmästä kehittyi oma funktiopohjainen ohjelmointikielensä C++:n sisälle! Toinen tunnettu 1980-luvulla kehitetty oliokieli on Bertrand Meyerin Eiffel. Se on puhdas oliokieli ja sisältää myös tukea ohjelmien formaalille verifioinnille (esija jälkiehdot sekä luokkainvariantit on mahdollista esitellä ja tarkastaa ajoaikana samoja ominaisuuksia löytyi muutamasta aiemmasta kielestä kuten Alphard ja Euclid). 1980-luvulla saatiin valmiiksi Yhdysvaltain puolustusministeriön toimeksiannosta kehitetty kieli Ada (Augusta Ada Byronin, Lovelacen kreivittären mukaan, jonka on sanottu olleen maailman ensimmäinen ohjelmoija). Adan tärkeimpiä sovelluskohteita olivat alunperin sulautetut järjestelmät ja tosiaikaohjelmistot, erityisesti asejärjestelmät. David Turner kehitti funktiokielen Miranda 1980-luvun puolessa välissä. Se muistutti monessa suhteessa ML:ää, mutta se käytti johdonmukaisesti laiskaa laskentaa (tähän palataan vielä) ja oli puhdas funktiokieli. Mirandan käyttöä rajoitti Turnerin tapa pitää kielestään voimakkaasti kiinni: hän jopa patentoi osia siitä. Samantyyppisiä omia kieliä oli lähes jokaisella funktio-ohjelmoinnista kiinnostuneella tutkijalla, joten vähän myöhemmin perustettiin komitea suunnittelemaan uutta Mirandan kaltaista ohjelmointikieltä. 1980-luvun loppupuolella syntyi kaksi merkittävää juontokieltä (scripting languages): John Ousterhoutin Tcl ja Larry Wallin Perl. Tcl:n pääideana oli olla kieli, jonka voisi upottaa ohjelmistoihin, Perl syntyi tarpeesta käsitellä tekstitiedostoja mitä erilaisimmin tavoin. 4.6 Internetin nousu: 1990-luku Vuonna 1993 alkoi Internetin ikuinen syyskuu, kun Internet alkoi vähitellen nousta tavallisten ihmisten tietoisuuteen. Samalla ohjelmoinnin fokus siirtyi kohti verkkosovelluksia. 11

James Gosling työryhmineen kehitti Java-kielen, vuonna 1995 julkaistun C-sukuisen oliokielen, joka on niin konservatiivisesti suunniteltu, ettei siinä ole juuri mitään uutta. Javan, kuten muidenkin C-sukuisten kielten, merkitys on sen suosikkiasemassa. Aivan 1990-luvun alussa sai edellisellä vuosikymmenellä muodostettu funktiokielikomitea työnsä päätökseen. Tulos oli Haskell, jonka tarkoitus on olla se oikea laiskasti laskeva, puhdas funktiokieli. Tämä tavoite onkin onnistunut. Vuonna 1999 valmistui kielen nykyinen määrittely, Haskell 98. Haskell näyttäisi ratkaisseen funktiokieliä vaivanneen ongelman siirrännästä varsin omintakeisella monadisen tietotyypin käsitteellään. Jo 1980-luvulla alkanut juontokielten kehitys jatkui 1990-luvulla. Guido van Rossum kehitti Pythonin vuosikymmenen alussa, Yukihiro Matsumoto kehitti Rubyn. 90-luvun lapsia ovat myös PHP ja ECMAScript (tunnetaan myös nimellä Javascript). 4.7 Tietoturva ja rinnakkaisuus: 2000-luku Vuonna 2001 Microsoft julkaisi Java-kielen kilpailijaksi tarkoitetun C#-kielen, joka on saavuttanut kuluvalla vuosikymmenellä merkittävän suosion. Historiastaan huolimatta C# on osoittautunut varsin edistykselliseksi kieleksi tuoden ohjelmoinnin valtavirtaan uusia, lähinnä tutkimuskielissä aiemmin tunnettuja ominaisuuksia (mm. LINQ). Maininnan arvoisia 2000-luvun kieliä ovat myös Martin Oderskyn Scala, Digital Marsin D ja Gnomen Vala. Ohjelmointikielten tutkimus on, kuten muukin tietojenkäsittelyn tutkimus, kuluvalla vuosikymmenellä keskittynyt liikkuvan tietojenkäsittelyn haasteisiin, erityisesti rinnakkaisuuden ja tietoturvallisuuden hallintaan, vaikka toki tutkimusta aiheesta kuin aiheesta on löydettävissä. 4.8 Sukupolvista Olen edellä viitannut ohjelmointikielten ensimmäiseen, toiseen ja kolmanteen sukupolveen. Kukaan ei näytä tietävän, mistä koko sukupolvijaottelu on peräisin, ja lähteet määrittelevät sukupolvet kukin omalla tavallaan. Edellä esittelemäni määritelmät kolmelle ensimmäiselle sukupolvelle ovat jonkinlainen lähteiden konsensus, vaikka poikkeaviakin esityksiä olen nähnyt. Useimmat lähteet puhuvat myös neljännestä ja viidennestä sukupolvesta, mutta mitään yksimielisyyttä niiden sisällöstä ei ole. 12

5 Kielten jaotteluja Itse käytän seuraavanlaista karkeaa jaottelua: Käskykielten (imperative languages) juuret ovat syvällä ratkaisuavaruudessa, von Neumannin arkkitehtuurin perusrakenteissa. Käskykielet näkevät maailman joukkona muistipaikkoja, joita muutellaan yksitellen von Neumannin pullonkaulaa pitkin. Käskykielille tyypillistä on tuhoava sijoitus - operaatio sekä eksplisiittinen, peräkkäistykseen ja silmukkaan perustuva toiminnanohjaus (flow of control). Käskykieliä on kahta päätyyppiä: Toimintokielet (procedural languages) abstrahoivat toimintaa aliohjelmiksi. Tunnettuja toimintokieliä ovat C, Pascal ja Fortran. Oliokielet (object-oriented languages) katsovat maailmaa simulaationa. Tunnettuja oliokieliä ovat Smalltalk, Eiffel ja Java. Myös mm. C++, Perl ja Python luetaan usein oliokielten joukkoon, vaikkeivät ne sitä varsinaisesti ole. Esittelykielten (declarative languages) juuret ovat ongelma-avaruudessa, ongelmien täsmällisessä kuvaamisessa yleensä matematiikan keinoin. Esittelykielten taustalla on vahva matemaattinen teoria, jota on sen verran rikottu, että näiden kielten toteutukset kykenevät itsenäisesti tekemään kielellä kirjoitetusta ongelman kuvauksesta enemmän tai vähemmän tehokasta konekieltä. Esittelykieliä on kahta päätyyppiä, jotka eroavat toisistaan lähinnä taustalla olevan matemaattisen teorian osalta: Funktiokielet (functional languages) perustuvat Churchin ja Kleenen 1930-luvulla kehittämään λ-laskentaan. Funktiokielten yksi pääviehätyksistä on viittausten läpinäkyvyys (referential transparency): jos lausekkeet ovat kerran yhtäsuuria, ne ovat aina yhtäsuuria. Puhtaita funktiokieliä on vähän: nykykielistä vain Haskell on puhdas funktiokieli. Funktiokielten joukkoon lasketaan usein myös Lispperheen kielet (Scheme ja Common Lisp) sekä ML-perheen kielet (Standard ML ja OCaml), vaikka nämä ovatkin ominaisuuksiltaan lähempänä käskykieliä niillä on kuitenkin mahdollista ohjelmoida kuten funktiokielellä, ja tämä onkin niiden suosituin käyttötapa. Logiikkakielet (logic languages) perustuvat predikaattilogiikan osaan nimeltä Hornin logiikka. Prolog on ainoa tunnettu logiikkakieli, mutta myös muita on. Monet kielet eivät kuitenkaan tipu siististi mihinkään näistä lokeroista. Hyvä esimerkki on C++, jossa on toimintokielen, oliokielen ja funktiokielen vikaa sama pätee myös esimerkiksi Perliin ja Pythoniin. Tällaisia kieliä sanotaan toisinaan moniparadigmakieliksi (multiparadigm languages). Toisaalta on kieliä, jot- 13

ka sijaitsevat koko jaottelun ulkopuolella. Hyvä esimerkki tällaisista kielistä on Prograph, jonka sanotaan kuuluvan visuaalisten ohjelmointikielten luokkaan. John Ousterhout 12 määrittelee järjestelmäohjelmointikielen ja juontokielen eron seuraavasti: järjestelmäohjelmointikieli Nämä kielet on tarkoitettu tietorakenteiden ja yksittäisten komponenttien toteuttamiseen siirrettävästi ja korkeammalla tasolla kuin assemblerilla kirjoitettaessa. Ne käyttävät vahvaa staattista tyypitystä. Järjestelmäohjelmointikieliä ovat esimerkiksi PL/I, Pascal, C, C++ ja Java. juontokieli Juontokielet olettavat, että on jo olemassa joukko hyödyllisiä komponentteja, jotka on kirjoitettu järjestelmäohjelmointikielillä. Juontokieliä käytetään komponenttien yhdistelemiseen, eräänlaisina liimoina (usein puhutaankin englanniksi glue language istä). Juontokielet käyttävät tyypillisesti dynaamista tyypitystä - tyypityksen vahvuus vaihtelee. (Ousterhout puhui tyypittömyydestä mutta hän tarkoitti dynaamista tyypitystä.) Juontokieliä ovat esimerkiksi Perl, Python, Rexx, Tcl, Visual Basic ja Unixin kuoret. 6 Ohjelmointikielten suunnitteluperiaatteita Tony Hoare kirjoitti 1970-luvun alussa poleemisen artikkelin 13, jossa hän antoi mielestään objektiiviset kriteerit ohjelmointikielen hyvyydelle. Ne ovat seuraavat. Kielen tulisi auttaa ohjelman suunnittelussa. Kielen tulisi auttaa ohjelman dokumentoinnissa. Kielen tulisi auttaa virheiden jäljittämisessä. Näiden pohjalta Hoare nimeää viisi avainlausahdusta, jotka kuvaavat hyvää ohjelmointikieltä: yksinkertaisuus Yksinkertaisuus on välttämätöntä, sillä muuten edes kielen kehittäjä ei voi arvioida tekemiensä valintojen seurauksia eikä kielen toteuttaja voi saavuttaa edes luotettavuutta saati sitten tehokkuutta ja nopeutta. Yksinkertaisuudesta hyötyy kuitenkin ensisijaisesti kielen käyttäjä. turvallisuus Turvallisuudella Hoare tarkoittaa sitä, että kielellä kirjoitettu ohjelma ei saa missään tilanteessa edes ohjelmoijan virheen seurauksena käyttäytyä hallitsemattomasti (esimerkiksi sekoittaa käyttöjärjestelmän tai muistinhallinnan tietorakenteita) tai eri järjestelmissä eri 12. John K. Ousterhout. Scripting: Higher-Level Programming for the 21st Century. Computer, vol. 31 no. 3, March 1998. 13. C. A. R. Hoare. Hints on programming-language design, emt. 14

tavoilla. Lisäksi kielen syntaksin tulee olla sellainen, ettei yksinkertainen kirjoitusvirhe muuta ohjelman merkitystä merkittävästi. Nykyisinä Internet-ohjelmoinnin aikoina turvallisuus on entistä merkittävämpi, sillä juuri ohjelmointikielten turvallisuuden puute on ollut merkittävä tietomurtoja edistävä tekijä. lyhyt kääntymisaika Käännösajan (se aika, joka kestää koodin muuttamisen päättymisestä siihen, kun muutettua ohjelmaa voi ajaa) tulee olla mahdollisimman lyhyt, jotta virheenjäljitys ja -korjaus onnistuisi mahdollisimman hyvin. Tämä vaikuttaa myös kielensuunnittelijan työhön, sillä eri ominaisuudet vaativat eri määrän työtä käännösaikana. ajonaikainen tehokkuus Ohjelmointikieli on työkalu ja siksi sen tulee olla tehokas. Tässä pätee sama kuin edellisessäkin kohdassa: kielensuunnittelija voi vaikuttaa paljon siihen, että onko hänen kielensä toteutettavissa tehokkaasti. luettavuus Ohjelman luettavuuden tärkeyden pitäisi olla kaikille selvä. Hoare antaa myös artikkelissaan monia ohjeita siitä, miten hänen mielestään näihin tavoitteisiin voitaisiin päästä, mutta monet niistä ovat jo varsin kyseenalaisia. Silti kielensuunnittelusta kiinnostuneen kannattaa tutustua Hoaren artikkeliin kokonaisuudessaan. Hoaren listaan voimme lisätä vielä yhden avainlausahduksen: stabiilius. Tuotantokäytössä olevan kielen tulee olla saavuttanut tietynasteinen kypsyys. Kielen käyttäjien tulee voida luottaa siihen, että juuri se kielen versio on validi vielä kahden, viiden ja aika usein vielä kymmenenkin vuoden kuluttua sekä ei pelkästään Windowsissa vaan myös Unixissa, Macissa ja vaikkapa GNU:ssa. Tässä auttaa voimakkaasti kielen standardointi, sillä standardi antaa stabiiliutta ja antaa yhteisen pohjan kielen eri toteutuksille. 7 Kielen määrittely Kielestä on aina syytä kirjoittaa määrittelydokumentti (specification) samaan aikaan kun sitä ensimmäistä kertaa toteutetaan tai heti sen jälkeen. Määrittelydokumentti kertoo ohjelmoijalle, mitä kieli tarjoaa, ja toteuttajalle, mitä hänen ohjelmansa tulee tehdä. Tämän dokumentin lisäksi on toki hyvä olla ohjelmoijan opas erikseen, koska määrittelydokumentti on ollessaan hyödyllinen tavallisesti suhteellisen vaikealukuinen. Määrittelydokumentissa kuvataan kaikki oleellinen kielestä riittävällä tarkkuudella. Tässä on valittavissa monta tarkkuustasoa: voidaan esittää asia epämuodollisesti tai sitten hieman muodollisemmin. Kielioppi esitetään nykyisin lähes 15

aina täysin muodollisesti käyttäen tiettyjä formalismeja (tavallisimmin Backus- Naur Form (BNF) tai sen muunnokset EBNF ja ABNF). Merkitysoppi on tapana ilmaista sanallisesti, koska olemassaolevat merkitysopin muodolliset kuvausmenetelmät (aksiomaattinen, denotationaalinen ja operationaalinen) ovat varsin vaikeita kirjoittaa ja lukea. Myös mahdollinen tyyppijärjestelmä voidaan kuvata muodollisesti esittelemällä se päättelysääntöjoukkona. Palaamme näihin kaikkiin formalismeihin myöhemmin. Uuden ohjelmointikielen määrittelydokumenttia levitetään tavallisimmin kielen alkuperäisen toteutuksen mukana. Toisinaan erityisesti yliopistoissa ja tutkimuslaitoksissa luotujen kielten määrittelydokumentti julkaistaan laitosraporttina tai jopa kansainvälisenä tutkimusartikkelina, ja monien määrittelyjen nimi onkin muotoa Report on the X Language Y, missä X on jokin kieltä Y kuvaava lausahdus. Tavallista on myös julkaista kielten paranneltuja versioita, jolloin saattaa tulla kyseeseen julkaista myös Revised Report on the X Language Y. Scheme on tästä mainio esimerkki: Scheme-raportista on nyt voimassa kuudes revisio (http://www.r6rs.org/). Kun kieli on saavuttanut tietyn kypsyystason ja käyttäjäjoukon, aletaan tavallisesti puuhata sen standardointia. Standardointia harrastavat monet järjestöt, tärkeimpinä ISO (kansainvälinen standardointijärjestö, http://www.iso.ch/), usein yhteistyössä IEC:n (kansainvälinen sähköteknillinen standardointijärjestö, http://www.iec.ch/) kanssa, ECMA (informaatio- ja kommunikaatojärjestelmiä standardoiva eurooppalainen järjestö, http://www.ecma.ch/) sekä IEEE (Institute of Electrical and Electronics Engineers, http://www.ieee.org/). Takavuosina merkittävässä asemassa olivat myös Yhdysvaltain kansallisen standardointijärjestön ANSI:n standardit, mutta nykyisin lähes kaikki ohjelmointikieliin liittyvät ANSI-standardit ovat myös kansainvälisiä ISO/IEC-standardeja. Usein tosin kielten standardointi tehdään näiden virallisten tahojen ulkopuolella (esimerkiksi Haskell-kielen standardointi tehtiin käyttäjä- ja toteuttajayhteisön sisällä kyseinen standardi julkaistaan kirjana kohtsillään). Seuraavassa on listattu joidenkin tunnettujen kielten standardit: C-kielestä on kolme standardia: ANSI X3.159-1989, ISO/IEC 9899:1990 ja ISO/IEC 9899:1999. Kaksi ensimmäistä ovat oleellisesti sama standardi ja käsittelevät sitä C:n versiota, jota on tapana kutsua ANSI C:ksi, C89:ksi tai C90:ksi. Kolmas standardi käsittelee C:n uutta versiota C99:ä. C++-kielen standardi on ISO/IEC 14882:1998. Scheme-kielen standardi on IEEE Std 1178-1990. C#-kielen standardi on ECMA-334. BASIC-kielestä on neljä standardia: ANSI X3.60-1978, ECMA-116, ANSI X3.113-1987 (R1998) ja ISO/IEC 10279:1991 (E). Ne kaikki käsittelevät 16

hieman eri versiota kielestä. Java-kielestä ei ole standardia. 8 Toteutustekniikoista Ohjelmointikielten toteutukset jaetaan kahteen pääluokkaan: on tulkkeja (interpreter) ja kääntäjiä (compiler). Rajanveto näiden luokkien välillä on hankalaa. Räikeimmissä tapauksissa se on suhteellisen helppoa: tulkki lukee ohjelmatekstiä ja suorittaa sitä lukiessaan, kääntäjä tuottaa ohjelmatekstistä konekielisen version, joka ajetaan erikseen. Käytännössä kuitenkaan puhtaita tulkkeja ei ole. Varsin suosittu tapa toteuttaa tulkki on rakentaa se kaksivaiheiseksi. Tulkkiin sisältyy eräänlainen esikääntäjä, joka kääntää ohjelman jonkin kuvitteellisen koneen konekielelle. Tämä kuvitteellinen eli virtuaalinen kone on suunniteltu siten, että sille on kyseinen kieli helppo kääntää ja toisaalta sitä on helppo simuloida ohjelmallisesti. Tulkin toinen osa on sitten tämän virtuaalisen koneen simulaattori, jota usein sanotaan virtuaalikoneeksi, joka sitten tosiasiassa tulkkaa tuon käännetyn tuloksen. Tämän virtuaalisen koneen konekieli on eräänlainen välikieli, jota tulkki käyttää apunaan. Sitä kutsutaan toisinaan tavukoodiksi (bytecode). Ohjelmointikielten kääntäjän (ja virtuaalikoneratkaisua käyttävän tulkin esikääntäjäosan) perusrakenne on kaksijakoinen: sillä on lähdekielestä riippuva etupää ja kohdekielestä (kohdekoneen konekieli) riippuva takapää. Etupää koostuu neljästä vaiheesta: leksikaalinen analyysi, syntaktinen analyysi, semanttinen analyysi ja välikoodin (intermediate code) tuottaminen. Takapää koostuu optimoimesta ja tuloskoodin (object code) tuottimesta. Tavallisesti osa näistä vaiheista tapahtuu limittäin, ei erillisinä vaiheina välituloksineen. Kääntäjätekniikan (jota myös tulkeissa käytetään) perusteos on ns. lohikäärmekirja 14, mutta se on suhteellisen vanha ja keskittyy lähinnä käskykielten kääntämiseen. Uudempi, ihan kohtuullinen kirja on Andrew Appelin Modern compiler implementation in Java 15, josta on olemassa versiot myös C- ja ML-kielille. Funktiokielten toteutusta käsittelee Peyton Jones 16. 14. Alfred V. Aho, Ravi Sethi ja Jeffrey D. Ullman. Compilers Principles, Techniques and Tools, Reading, MA, Addison-Wesley, 1988. 15. Andrew W. Appel. Modern compiler implementation in Java, Cambridge, Cambridge University Press, 1999. 16. Simon L. Peyton Jones. The Implementation of Functional Programming Languages, New York, Prentice Hall, 1987. 17