Common Lisp/Perusteet

Kohteesta Wikikirjasto
Siirry navigaatioon Siirry hakuun

Uusiin asioihin liittyy monesti tietyt perusteet, jotka tulee hallita ennenkuin voi ryhtyä varsinaisesti töihin. Tällä sivulla esittelemme sinulle perusasiat Common Lispistä. Jotkin näistä asioista pätevät soveltuvin osin myös muihin Lisp-murteisiin.

Listat[muokkaa | muokkaa wikitekstiä]

Common Lisp perustuu listojen käsittelylle, joten esitelemme ne ensimmäiseksi.

Common Lispin listat ovat linkitettyjä listoja. Ne koostuvat pareista, eli elementeistä joilla on kaksi solua. Pareista muodostetaan listoja seuraavasti: parin ensimmäinen solu sisältää lista-alkion ja toinen solu seuraavan tällaisen parin osoitteen. Listassa viimeisenä olevan parin toinen solu ei sisällä osoitinta, vaan 'atomin' joka ilmaisee että lista loppuu, eli NIL. NIL ilmaisee myös tyhjyyttä, väärää ja muita pahuuden voimia. Sen komplementti on T, joka ilmaisee jotakin olevaista, oikeata, ja muita hyviä asioita.

Tätä elementtiä kutsutaan nimellä CONS.

Muinaisen Lisp-koneen mukaisesti pari on nimeltään CONS, ensimmäinen (vasemmanpuoleinen) solu parista on nimeltään CAR, ja toinen (oikeanpuoleinen) solu on nimeltään CDR. Näitä nimiä vastaa funktiot, jotka toimivat hyvin johdonmukaisesti. Funktiolla CONS on kaksi parametriä ja se evaluoituu niistä muodostuvaksi pariksi. Funktiolla CAR on yksi parametri, jonka vasemmanpuoleiseksi soluksi se evaluoituu. CDR toimii samoin kuin CAR, paitsi että evaluoituu oikeanpuoleiseksi soluksi, tietenkin. Pareja voi siis linkittää "hännistään" yhteen siten että ne muodostavat listan! Muinaisessa Lisp-koneessa oli ilmeisesti käsky myös listan muodostamiselle, ja se oli list, joka löytyy myös nykyaikaisesta Common Lispistä.

(cons 1 (cons 2 (cons 3))) == (list 1 2 3)
(cons 1 2)         == (1 . 2)
(car (list 1 2 3)) == 1
(cdr (list 1 2 3)) == (list 2 3)

Ensimmäinen Malli Suorittimesta[muokkaa | muokkaa wikitekstiä]

Toisin kuin muissa kielissä, joissa ohjelma suoritetaan niin monimutkaisella tavalla jopa tulkissa, että tarkka selitys sen toiminnasta maallikolle on hepreaa, Lisp -ohjelmassa listat suorittava ohjelma on suhteellisen yksinkertainen ja siitä ei tarvitse tietää kaikkea kerralla. Seuraavassa esitetty kannatanee kuitenkin tietää.

Kun Lisp lukee ohjelmasta yhden listan, se antaa sen parametriksi eval-funktiolle, joka lukee listasta ensimmäisen solun. Jos siellä on symboli, se hakee vastaavan symbolin funktion nimiavaruudesta. Jos se löytää funktion, se kutsuu itseään lopuille listan elementeille ja syöttää tuloksena saadun evaluoidun listan aiemmin mainitulle funktiolle.

Piste[muokkaa | muokkaa wikitekstiä]

Listamuotoon kuuluu valinnainen piste, jolla voidaan ilmaista että lista ei lopukkaan tavalliseen tapaan NILliin, vaan johonkin muuhun. (cons 1 2) antaa samaa kuin '(1 . 2)

Don QUOTE[muokkaa | muokkaa wikitekstiä]

QUOTE on erikoinen komento, se estää parametriensä evaluoinnin ja palauttaa ne. Esim. (quote (sika possu apina)) palauttaa listan (sika possu apina), eikä sika-funktiolle yritetäkään syöttää possua tai apinaa. Quotella on myös yhden merkin muoto, ', jonka avulla esimerkin listan voisi kirjoittaa muotoon: '(sika possu apina) ja ' merkkiä voi siis ajatella eräänlaisena suorittimen lamauttajana, joka antaakin syöttää funktioille lukijalla suoraan tuotettuja listoja!

Esimerkkinä aiemmat listat nyt quote -muodolla.

'(1 2 3)
'(1 . 2)
(car '(1 2 3))
(cdr '(1 2 3))

Don FUNCTION (QUOTE)[muokkaa | muokkaa wikitekstiä]

FUNCTION on erikoinen komento jota voi käyttää nimeä/symbolia vastaavan funktion hakemiseen ja palauttamiseen. Esimerkiksi kun suoritat listan (function list), FUNTION selvittää onko argumentti symboli, jos on, se hakee funktionimiavaruudesta sille vastineen ja palauttaa saamansa tuloksen. FUNCTIONilla on erikoinen kahden merkin muoto, #', joka toimii samaan tapaan kuin quoten vastaava muoto.

Seuraavassa esimerkissä on komento, jota et ole vielä nähnyt tässä kirjassa:

(funcall #'list 1 2 3) tekee samaa kuin (list 1 2 3)

FUNCTION tulee käsittelyyn myöhemmin kun puhutaan korkeamman asteen funktioista.

Sulkeiden Tarina[muokkaa | muokkaa wikitekstiä]

LISP kielen on saattanut tunnistaa alusta alkaen sen sairaalloiselta näyttävältä sulkeidenkäytöltä. Varmaan jo synkän seitsenkymmenluvun alusta, LISPin syntaksia on yritetty parantaa tältä kantilta. Ehkäpä jopa sinä saatat yrittää jotakin. On hyvä yrittää uusia temppuja, mutta historia tuntuu vain toistavan itseään. Vaikka LISPin keino käyttää sulkeita lähestyy pitkälle äityneen perversion asteikkoa, se on toistaiseksi paras tapa esittää listoja merkkijonoin.

Koska niin moni on yrittänyt parantaa lispin syntaksia, parannusehdotuksia on runsaasti. Lisäksi jokainen uusi heppu ehdottaa alkajaisiksi perinteisiä parannusehdotuksia: infix-syntaksi prefixin tilalle on aika yleinen, niin myös sisennyksen huomioiminen. Mille tahansa ehdotukselle voidaan keksiä yksi hyvä puoli ja kaksikymmentä huonoa.

Sulkeiden tulevaisuus[muokkaa | muokkaa wikitekstiä]

On vaikea kuvitella hienoja tapoja esittää lista merkkijonoilla muuten kuin sulkeilla. Siksipä on epätodennäköistä, että sulkeet katoaisivat Lispistä merkkijonojen aikakaudella. Sen sijaan Lispissä lepää mahdollisuus muille tavoille esittää ohjelmakomentoja. Uusia tapoja antaa ja vastaanottaa tietokoneelta tietoa/komentoja kehittyy kokoajan. Kuka tietää, jos tulevaisuudessa tietokoneet ohjelmoidaankin hermostoon liitettävän kaapelin kautta? Tällöin tuskin enää tarvitaan turhan hankalia tapoja esittää listoja, koska linkin avulla mitä tahansa tietoa voi muokata ja lukea murto-osassa nykyisestä ajasta.

Nimeäminen[muokkaa | muokkaa wikitekstiä]

On tärkeää tietää oikea nimeämistyyli koska se saa koodin näyttämään selvemmältä ja tietyissä tapauksissa myös välttää hyvin ilkeitä virheitä.

Koska Lispissä väliviiva on laillinen merkki symboleiden nimeämisessä sitä käytetään ala_viivan tai camelCasen sijaan sanojen erottamisessa muuttujanimissä. Alaviivan käyttöä nimissä pidetään yleisesti hyvin epätyylikkäänä ratkaisuna.

Hyvässä nimeämiskäytännössä reunustetaan kaikki globaalit (tarkemmin sanottuna dynaamiset) muuttujat tähdillä, näin: *tama-on-globaali-muuttuja*. Muut symbolit nimetään normaaliin tapaan.

Vastaavasti vakiot ympäroidään yleensä +-merkeillä: (defconstant +vakio+ 1)

Joskus voidaan vain pakettien sisäiseen käyttöön tarkoitettujen nimien eteen liittää %-merkki. (defun %deep-magic () ...)