Lisp, mutta mikä niistä?

muokkaa

"The MacLisp community is not in a state of chaos. It consists of four welldefined groups going in four well defined directions." -- Scott Fahlman


Vaikka Lisp-maailman tila onkin paljon vakaampi kuin Fahlmanin puheen aikoihin 1980-luvun alussa, voi se aloittelijasta vaikuttaa kaoottiselta. Valitukset 'Lisp-yhteisön' hajaannuksesta ja murteiden moninaisuudesta ovat yleisiä ja aloittelija voi olla aika hukassa yrittäessaan valita Lisp-toteutuksista tai -murteista itselleen sopivinta.

Jos Lispin tilannetta verrataan vaikkapa C:hen, voisi väittaa 'C-yhteisön' olevan kaoottisessa tilassa murteiden ja toteutusten paljouden vuoksi. On C, C++, D, Java, C#, Objective-C, jne. sekä lisäksi suuri määrä eri toteutuksia em. kielistä. Käytännössähan asia ei ole näin paha, vaan jokainen edellämainituista kielistä on oma itsenäinen kokonaisuutensa.

Tässä mielessa Lispin ja C-sukuisten kielten tilanne muistuttaa toisiaan. Käytannössä nykyään on käytössä tasan kaksi vakavasti otettavaa erillista Lisp-murretta, Common Lisp ja Scheme. Erilaisten ohjelmien skriptaamiseen on myös kehitetty useita toisistaan poikkeavia Lispejä, joista tärkeimpänä Emacs Lisp.

Aloittelijalle silmiinpistävin ero CL:n (Common Lispin) ja Schemen välillä on standardin laajuus. Siinä missä CL sisältää oliojärjestelmän, kehittyneen poikkeusten käsittelyn, läjäpäin hyödyllisiä pikkufunktioita, tietorakenteita ym., Schemen standardi on tarkoituksella mahdollisimman minimaalinen. CL vastaa laajuudeltaan lähinnä C++:aa, Schemeä vastaisi ehkä parhaiten C ilman standardikirjastoa. Toisin kuin C, Scheme on kuitenkin helposti ja saumattomasti laajennettavissa käsittämään kaiken tarvittavan ja isommat Scheme-toteutukset ovatkin toiminnallisuudeltaan CL:ää vastaavia tai jopa laajempia. Tosin pienestä standardista johtuen eri Scheme-toteutukset voivat erota toisistaan hyvinkin paljon.

Tarkempia tietoja lispin sukupuusta ja CL:n ja Schemen eroista.

Laajuteensa lisäksi CL vastaa C++:aa myös siinä mielessä että se on standardoitu kieli, josta on olemassa useita eri toteutuksia jotka yrittävät parhaansa mukaan toteuttaa standardin vaatimukset. Suurimmat erot eri CL:ien välillä liittyvät siihen, miten niissä on toteutettu standardin ulkopuolella olevia ominaisuuksia, esimerkiksi moniajoon tai C-kielisten kirjastojen käyttöön liittyviä. Koska epästandardien ominaisuuksien käyttöön on kehitetty erilaisia yhteensopivuusrajapintoja ja näiden de facto standardien voi tulevaisuudessa odottaa yleistyvän, ei aloittelijan kannata turhautua 'oikean' Common Lispin valinnan kanssa. Lisäksi kannattaa muistaa että hyvin kirjoitettu CL-koodi on yleensäkin helposti portattavissa toteutuksesta toiseen.

lisp, Lisp, LISP

muokkaa

Koska nimitystä 'lisp' voidaan käyttää hyvinkin laajassa merkityksessä aloittelijan voi välillä olla vaikea erottaa mitä sillä missäkin yhteydessä tarkoitetaan, asiaa ei varmaankaan auta se että kaikki lispit näyttävät päällepäin hyvin samanlaisilta. Tässä joitain suuntaa antavia neuvoja:

  • Nimitystä 'lisp' käytettäessä tarkoitetaan yleensä laajemmin koko lisp-tyyppisten kielten perhettä, samaan tapaan kuin puhutaan esimerkiksi Algol-tyyppisista kielistä tai Wirth-kielistä. Yhdistävänä tekijänä näillä kielillä on yleensä (lispmäinen (s-exp (notaatio)). Yleisimmät tämän perheen kielet ovat siis Common Lisp ja Scheme. Koska hyvinkin erityyppisiä kieliä voidaan pitää 'lispinä' kannattaa välttää turhan yleistäviä kommentteja, kuten "lisp on funktionaalinen kieli" (mikään nykyään yleisesti käytössä olevista lispeista ei ole puhtaasti funktionaalinen). Lisäksi kieliä jotka ulkoisesti eivät muistuta 'lispiä' (kuten nykyinen Dylan) voidaan joissain tapauksissa pitää 'lispinä'.
  • 'Lisp' viittaa yleensä Common Lispiin. Joissain tapauksissa (esim. kirjassa 'Structure And Interpretation Of Computer Languages') voidaan Lispillä tarkoittaa myös Schemeä, mutta koska CL ja Scheme ovat monella tapaa erilaisia kieliä, olisi hyvä puhua jälkimmäisestä sen omalla nimellä. Lisäksi sekä CL:n että Schemen käyttäjien taholta kuulee välillä argumentteja puolesta ja vastaan siitä voiko Schemeä pitää Lispinä vai ei.
  • Nimitys LISP on nykyään poistunut käytöstä ja sillä viitataan yleensä McCarthyn LISP1.5:n. Jos siis henkilö sanoo "koodaavansa LISP:llä", hän todennäköisesti ei tiedä mistä puhuu tai on kiinnostunut ohjelmointikielten historiasta.
  • Joskus näkee aloittelijoiden käyttävän Common Lispistä virheellisesti nimitystä CLisp. CLisp on yleinen Common Lisp toteutus, eikä nimeä pidä käyttää puhuttaessa Common Lispistä kielenä.

Mikä Common Lisp toteutus on?

muokkaa

Koska kaikkiin Common Lisp toteutuksiin -- CLispiä ja ABCL:ää lukuun ottamatta -- kuuluu jonkinlainen natiivikääntäjä, ei CL:n yhteydessä yleensä puhuta 'lisp-tulkeista', vaan mieluummin lisp-järjestelmistä tai lisp-toteutuksista. Kannattaa huomata, että sellaisissakin toteutuksissa joissa on vain natiivikääntäjä (esim. SBCL), järjestelmä toimii interaktiivisesti REPL:in kautta, mikä saattaa olla yksi syy siihen että lispiä yleensä pidetään 'tulkattuna kielenä'.

Common Lispin määritelmä ei ota kantaa siihen miten järjestelmän tekninen toteutus pitää hoitaa ja antaa siinä mielessä toteuttajalle varsin vapaat kädet. Standardi määrittelee järjestelmän toiminnan niin, että standardia noudattavan ohjelman on oltava siirrettävissä eri Lisp-toteutusten ja -järjestelmien välillä ongelmitta. Tästä syystä eri Common Lisp -järjestelmät voivat erota tekniselta toteutukseltaan hyvinkin paljon toisistaan, vaikka ne ovatkin lähdekooditasolla yhteensopivia. Luonnollisesti eri toteutustekniikoilla on etunsa ja haittansa, mikä voi joissain tapauksissa olla hyvä ottaa huomioon CL-toteutusta valittaessa.

Common Lisp toteutuksia

muokkaa

Vapaat:

Vapaiden toteutusten mukana ei tule IDE:ä vaan yksinkertaisimmillaan järjestelmää käytetään REPL:stä (lisp-järjestelmän komentorivi). Käytännössä lähes kaikki vapaat CL toteutukset toimivat ja niitä käytetään SLIME:n kautta joka tarjoaa kehittyneen Emacs-pohjaisen IDE:n.

CMUCL:sta haarautunut Steel Bank Common Lisp on vapaiden CL-toteutusten lippulaiva. Tästä nopeasti kehittyvästä CL-toteutuksesta löytyy mm. nopeaa koodia tekevä natiivikääntäjä ja käyttöjärjestelmätason säikeistys (alustariippuvainen). SBCL on saatavilla monille eri alustoille, tosin sen Windows-tuki on tätä kirjoitettaessa (7.6.06) kesken, mutta vaikuttaa lupaavalta. SBCL on mahdollisesti tuleva CL-maailman gcc (GNU Compiler Collection).

Vapaiden CL toteutusten grand-old-man. Näkyvimmät erot SBCL:ään käyttäjätason säikeistys sekä natiivikoodin lisäksi mahdollisuus käyttää tavukoodia tulkin avulla.

Pieni tavukoodiksi kääntävä CL. Etuina laaja alustatuki ja binäärien pieni koko, mahdollisina haittoina hitaus ja säikeiden puute.

ECL kääntää tavukoodiksi ja C:n kautta natiivikoodiksi. Etuna laaja alustatuki, binäärien pieni koko, mahdollisuus tehdä dynaamisia kirjastoja ja yleensäkin helppo yhteistyö C:n kanssa. Haittana muihin Lispeihin verrattuna epämukava kehitysympäristö. Parhaimmillaan käännettäessä valmiita CL ohjelmia C:ksi.

Kuin ECL mutta heikompi yhteensopivuus standardiin(?)

Armed Bear Common Lisp on tuorein ja vielä hieman keskeneräinen CL. Se kääntää ohjelmat Javan tavukoodiksi.

Raa'alla x86 raudalla pyörivä CL.

Kaupalliset:

Kaupallisiin toteutuksiin kuuluu yleensä laaja valikoima kirjastoja ja IDE (tosin ainakin Lispworks ja Allegro toimivat myös SLIME:n kautta). Korkean laadun ja hyvän tuen vastapainona on yleensä korkea hinta. Mikäli vapaat CL ympäristöt tuntuvat vaikeilta, voi vaikkapa Lispworksin tai Allegron ilmainen kokeiluversio olla hyvä harjoitusalusta.