Common Lisp/Pikakelaus

Kohteesta Wikikirjasto
Siirry navigaatioon Siirry hakuun
Varoitus! Se on tarttuvaa.

"Lisp-polku on kivinen, mutta samalla se on oikea polku" - kuten moni kokeneempi Lisp -harrastaja tietää. Lisp on ohjelmointikielenä erilainen kuin monet muut ja nämä erot jakavat jyrkästi mielipiteitä kielestä. Moni karsastaa Lispiä sen runsaan sulkeiden käytön takia, mutta löytyy myös niitä, jotka rakastavat sitä. Tämä kirja on osoitus siitä, että ne jotka rakastavat Lispiä, rakastavat sitä enemmän kuin Lispiä vihaavat henkilöt rakastavat suosikkiohjelmointikieltänsä. Tämä kirja on olemassa, jotta Lispistä kiinnostuneet suomalaiset voisivat tyynnyttää mielenkiintonsa sen lyhyeen mutta hyvin ytimekkääseen kuvaukseen.

Vaikka Lisp on vihattu, se on samalla hyvin ilmaisuvoimainen ja kaunis kieli. Niiden, jotka sitä vihaavat, pitäisi myös pelätä sitä.

Koska alkuunpääseminen on vaikeaa, kirjassa on kiinnitetty hyvin paljon huomiota juuri siihen. Tämä sivu kertoo, mitä sinun kannattaisi tietää ennenkuin lähdet lukemaan muita sivuja.


Miten Lisp eroaa useista muista ohjelmointikielistä?[muokkaa | muokkaa wikitekstiä]

Lisp lähestyy ohjelmointia eri tavalla kuin muut kielet yleensä. Lispissä ohjelmat rakennetaan listoiksi kun taasen muissa kielissä ne ovat yleensä tietynlaisia lauseita, jotka ohjelmointikieli tarkasti jäsentelee ja tekee lauseessa määritellyn toiminnon. Useat kielet eivät suosi tapaa kirjoittaa monta asiaa yhdelle riville. Lispillä on ominaisuuksia mitä muissa kielissä ei yksinkertaisesti vain ole. Lisp on myös omaksunut muille kielille epätavallisia tapoja, kuten tavan muuttaa sanoissa olevat pienet kirjaimet automaattisesti isoiksi kirjaimiksi, käyttää kivoja erikoismerkkejä nimissä ja erottaa funktiot ja muuttujat erillisiin nimiavaruuksiin. Nämä piirteet helpottavat nimeämistä Lispissä hyvin paljon.

Vertailun vuoksi tässä on sama ohjelma, kirjoitettuna C:llä, Pythonilla ja Common Lispillä:

/* C-funktio joka lisää x:ään yhden ja kertoo sen sitten itsellään. */
int mult_add(int x)
{
    return (x + 1) * x;
}

# python
def mult_add(x):
    "Funktio joka lisää x:ään yhden ja kertoo sen sitten itsellään."
    return (x + 1) * x

;;; Lisp
(defun mult-add (x) 
  "Funktio joka lisää x:ään yhden ja kertoo sen sitten itsellään."
  (* (+ x 1) x))

Kehitystyökalut[muokkaa | muokkaa wikitekstiä]

Editorit[muokkaa | muokkaa wikitekstiä]

Osasyy Lispin erikoiseen syntaksiin se, että sitä editoidessa on kautta historian käytetty hyvin tehokkaita tekstieditoreita sen sijaan, että syntaksista oltaisiin tehty monimutkaisempi. Tämä on osa Lispin kauneutta. Se, että editoreista voidaan ylipäätänsä tehdä avuliaampia, on osittain yksinkertaisen syntaksin ansiota. Syntaksin, joka on tarkoitettu yhtälailla niin koneelle kuin ihmisellekin.

Tämän vuoksi editorin valintaa kannatta harkita. Esimerkiksi Windowsin Notepad ei kelpaa laisinkaan. Editorin minimivaatimukset ovat, että se auttaa sinua asettelemaan sulkeet ja sisentää koodin sinulle valmiiksi. Tapoja sulkeiden asetteluun on yhtä monta kuin editoreitakin, muutamia kiinnostavia vaihtoehtoja on lueteltu tämän kappaleen lopussa. Jos aikaa riittää, kannattaa opetella joko emacs tai vi yleiskäyttöön. Emacs on laaja ja vi nopea, ja kumpi tahansa kelpaa koodin kirjoittamiseen. Molemmat ovat myös paljon parempia kuin mikään graafinen tekstieditori on nykyään. Joitakin tapoja miten tehokas editori voi auttaa käyttäjää sulkeiden kanssa:

* Värittää suljepareja sateenkaarivärein.
* Vinkkaa avaussuljetta kun kirjoittaa sille sulkevan sulkeen pariksi.
* Piirtää yhden supersulkeen vaikka kolmen samansuuntaisen sulkeen jälkeen.
* Ryhmittää koodia sulkeiden mukaan sitä mukaa kun sitä kirjoitetaan.
* Värittää parillisen sulkeen alueen pohjan sateenkaarivärein.
* Piirtää laatikon sulkeen alueelle ja piilottaa kyseiset sulkeet tekstistä.

Emacs-editorista kannattaa lukea sen manuaalista, sikäli kun kukaan sitä tunteva ei kirjoita tähän kohtaan siitä lisää.

Vi-editorista on eri variaatioita: vi, vim ja gvim, joista jotkut toimivat myös windowsilla. *vi* ovat hyvin nopeita käynnistymään ja ne ovat hyvin tehokkaita tekstin muokkaamiseen.

Hyödyllisiä komentoja vi:lle:
* set expandtab -- muuttaa sarkainlyönnit välilyönneiksi.
* set sm        -- vinkkaa avaussuljetta kun kirjottaa sille sulkevan sulkeen.

Slimellä Emacs-editorin saa liitettyä suoraan käyttämäänsä lisp-toteutukseen.

Suosittelen Slimen ja Emacsin käyttämistä.

Toteutus[muokkaa | muokkaa wikitekstiä]

Common Lispille ei ole olemassa vain yhtä hyvää toteutusta. Eri toteutukset ovat eri tavalla hyviä. Valitsemme siis kolme mielestäni oleellisinta toteutusta: SBCL:n, ECL:n ja CLISP:in. Käsittelemme tarkemmin eri toteutusten asentamista koneelle sivulla Asennus (Samaisella sivulla puhutaan myös muitten työkalujen asentamisesta.)

SBCL on paljon käytetty toteutus. Olisin kertonut ainoastaan siitä, jos siitä olisi ollut tarpeeksi hyvä toteutus Windowsille kun kirjoitin tätä kirjaa. SBCL pystyy kääntämään koodin melkein yhtä nopeaksi kuin C kääntää vastaavan koodin. Se on myös hyvin testattu ja vakaa toteutus. SBCL:stä löytyy myös kaikki tarvittava Slimestä vuorovaikutteiseen tulkkiin.

CLISP on Windowsillakin toimiva toteutus, joka kääntää hieman hitaampaa koodia kuin SBCL. Myös sen saa Slimeen kiinni.

ECL on kaikilla käyttöjärjestelmillä toimiva toteutus, joka kääntää ohjelmat kääntämällä ne ensiksi C-koodiksi ja sitten kääntämällä ne gcc:llä joko suoritettavaksi ohjelmaksi tai .fas -kirjastoksi.

Jokainen toteutus näistä tukee CFFI:tä. CFFI on rajapintakirjasto vieraskielisiin funktioihin. CFFI:stä kerrotaan lisää sivulla Vieraskieliset Funktiot

Vuorovaikutteinen Tulkki[muokkaa | muokkaa wikitekstiä]

REPL (Read Eval Print Loop) eli vuorovaikutteinen tulkki on elintärkeä ominaisuus Lispissä. REPL:issä voi suorittaa Lisp-listoja ja tämän vuoksi se on erinomainen työkalu funktioiden testaamiseen, ellei editori tarjoa ominaisuutta jolla lisp-listoja voi syöttää editorista käsin REPLille ja REPL syöttää editorille vastauksen. REPL menee virhetilaan jos sille syöttää väärin muotoillun tai muutoin huonon listan. Tällöin REPL tarjoaa vaihtoehtoja tilanteen korjaamiseksi. REPL:istä kerrotaan lisää sivulla Tulkki.

Näppäimistöasettelu[muokkaa | muokkaa wikitekstiä]

QWERTY-näppäimistöasettelu on 130 vuotta sitten tehty asettelu jolla estettiin kirjoittajaa vahingoittamasta kirjoituskonetta hidastamalla kirjoitusnopeutta tahallisesti. Tämän vuoksi kannattaa harkita DVORAK, ABCDF tai kokonaan omaa näppäimistöasetelmaasi, joka on tehty näppäinpainallustesi mukaan tai räätälöity jostakin valmiista, olemassa olevasta näppäimistöasettelusta. Näppäimistöasettelun vaihto parantaa suorituskykyä ja estää sinua rikkomasta sormiasi. Nykyään näppäimistöt kestävät vaikka minkälaisia temppuja, miksi rikkoa sormiasi vaikka ne korjautuvatkin automaattisesti?

Mnemoonit[muokkaa | muokkaa wikitekstiä]

Hyvä muisti on erinomainen asia jos haluaa oppia jotakin uutta, tämän vuoksi suosittelen tutkimaan erilaisia muistamismenetelmiä. Voit muistaa ihmeellisiä asioita jos vain kokeilet niitä. Henkilökohtaisesti todettu erinomaisiksi työkaluiksi! Kirjoittamalla "mnemonics" -googleen, saa varsin hyviä ohjeita.

Esittelen tässä yhden mnemoonin jota käytän soveltavasti vieraiden sanojen ja outojen sarjojen oppimiseen, se perustuu sanan rikkomiseen muistettavampaan muotoon ja satunnaisten assosiaatioiden lisäämiseen. Olen todennut tämän toimivaksi. Haluat vaikka oppia limbisen järjestelmän perusosat; hippokampus, hypotalamus ja mantelitumake. Voit kuvitella miltä seuraava näyttää:

Hippo, hypnomies ja manteli limboavat järjestelmää.

Pureskele ajatusta mielessäsi ja liitä siihen tärkeitä asioita kuten mm. miten nämä asiat liittyvät hippokampukseen, hypotalamukseen ja mantelitumakkeeseen. Kun et tarvitse muistisääntöä enää asian muistamiseen, anna sen unohtua. Tärkeämpi tieto jää tallelle silti koska olet siihen mennessä tehnyt niin monta oikeata assosiaatiota tietoon että et tarvitse muistisääntöä enempää.

Makrot[muokkaa | muokkaa wikitekstiä]

Makrot ovat Lisp-ohjelmoijan parhaita ystäviä. Makroilla voidaan muuttaa Lisp-kieltä erilaiseksi. Silloin sillä voidaan tehdä mm. uusia ehtolausekkeita ja lausekkeita, jotka sulkevat vaikka pistokkeen makron päättyessä. Makrot ovat yksi monista hyödyistä siirryttäessä lausepohjaisesta kielestä listapohjaiseen. Makroja toistaiseksi ei olla pystytty siirtämään toiseen kieleen ilman, että kyseisestä kielestä oltaisiin tehty listapohjainen. Koodissa makrot muistuttavat hyvin paljon funktioita. Niillä on funktioihin verrattuna kuitenkin kaksi huomattavaa eroa: Funktiot evaluoivat parametrinsä ja funktiot suoritetaan ajonaikana. Makrot suoritetaan kääntämisen aikana, eivätkä ne suorita parametrejään, vaan antavat ne suoraan makrolle. Makro taasen palauttaa muokatun version, joka saattaa myös sisältää makroja ja siis laajentua edelleen. Makrot ovat hyvin ongelmallisia väärin käytettynä ja niitä tehtäessä kannattaa siis noudattaa hyvin suurta varovaisuutta. Makrojen testaamiseen on toki olemassa työkaluja. Hyvillä makroilla pystyy säästämään sormiaan tuhansien rivien kirjoittamiselta ja tutkimiselta. Ne ovat siis hyvin hygieenisiä kapistuksia oikein käytettynä.

Ohjelmoitavuus[muokkaa | muokkaa wikitekstiä]

Lispin ohjelmoitavuus tarkoittaa sitä, että itse toteutuksen voi ohjelmoida. Tämä tekee Lisp-toteutuksista erittäin dynaamisia ja miellyttäviä kumppaneita. Itseasiassa, joissakin tilanteissa, joissa muuten joutuisi kuraamaan itsensä C-kieleen, voidaan ongelma ratkaista lyhyellä koodilla, joka toimii laajennuksena kieleen. Toisaalla käsitellään miten Lisp luo tällaisen mahdollisuuden.