<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule">
<channel>
    <title>SIGKILL - Lisp</title>
    <link>http://sigkill.dk/blog/</link>
    <description>Hello, World!</description>
    <dc:language>en</dc:language>
    <generator>Serendipity 1.5.2 - http://www.s9y.org/</generator>
    <managingEditor>athas@sigkill.dk</managingEditor>
<webMaster>athas@sigkill.dk</webMaster>

    <image>
        <url>http://sigkill.dk/blog/templates/default/img/s9y_banner_small.png</url>
        <title>RSS: SIGKILL - Lisp - Hello, World!</title>
        <link>http://sigkill.dk/blog/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>Eksempel på CLIM</title>
    <link>http://sigkill.dk/blog/archives/196-Eksempel-pa-CLIM.html</link>
            <category>Lisp</category>
    
    <comments>http://sigkill.dk/blog/archives/196-Eksempel-pa-CLIM.html#comments</comments>
    <wfw:comment>http://sigkill.dk/blog/wfwcomment.php?cid=196</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://sigkill.dk/blog/rss.php?version=2.0&amp;type=comments&amp;cid=196</wfw:commentRss>
    

    <author>nospam@example.com (Troels Henriksen)</author>
    <content:encoded>
    &lt;p&gt;
For et stykke tid siden &lt;a href=&quot;http://www.sigkill.dk/blog/archives/137-Common-Lisp-Interface-Manager.html&quot;&gt;skrev jeg om CLIM&lt;/a&gt; og var især begejstret for &lt;em&gt;presentation types&lt;/em&gt;. Det er jeg stadigvæk, og for at konkretisere hvorfor jeg synes de er så geniale, vil jeg nu komme med et eksempel på hvorledes jeg har brugt dem i løbet af de sidste uger.
&lt;/p&gt;

&lt;p&gt;
Jeg arbejder i min fritid på &lt;a href=&quot;http://common-lisp.net/project/climacs/&quot;&gt;Climacs&lt;/a&gt; - en næstegenerations Emacs skrevet i Common Lisp. Derudover arbejder jeg også på &lt;a href=&quot;http://common-lisp.net/project/clim-desktop/&quot;&gt;CLIM-desktop&lt;/a&gt; - integration mellem en række forskellige CLIM-programmer. I CLIM-desktop har jeg skrevet kode der udnytter presentation types på en ret interessant måde - en standard presentation type er &lt;em&gt;symbol&lt;/em&gt;, som bliver brugt når et program ønsker at vise brugeren et almindeligt Lisp-symbol. Ved at definere en &lt;em&gt;presentation command translator&lt;/em&gt; har jeg kædet alle presentations af denne typer sammen med en kommando, der får Climacs til at redigere definitionen af symbolet. Resultatet af dette er at når et program producerer output, kan det blot sige at et givent stykke output repræsenterer et givent symbol, hvorefter brugeren til hver en tid kan holde ALT inde, klikke på symbolet, og blive taget til den fil, og position i filen, hvor symbolets funktion, klasse, type, osv., bliver defineret. Dette sker fuldstændigt uden at applikationsprogrammøren skal tænke nærmere over det, han kan blot gå ud fra at miljøet giver brugeren nogle relevante interaktionsmuligheder for en given presentation type (selvom programmet selvfølgelig også kan definere sine egne).
&lt;/p&gt;

&lt;p&gt;
På samme måde er andre presentation types også kædet til kommandoer - filnavne giver mulighed for at åbne filen, klassenavne mulighed for at redigere i filen, og kommandoer og kommandonavne mulighed for at redigere kommandoens definition. Det er ret komfortabelt at bruge et miljø hvor man, hvis man pludselig opdager en bug i en kommando, som regel bare kan holde ALT inde og trykke på kommandoen, og fikse den. Og denne funktionalitet kommer fuldstændigt gratis for applikationsprogrammøren, hvor det i de fleste toolkits ville være ganske besværligt at implementere.
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Fri, 16 Jun 2006 11:58:00 +0200</pubDate>
    <guid isPermaLink="false">http://sigkill.dk/blog/archives/196-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license>
</item>
<item>
    <title>Climacs pr0n og jubilæum</title>
    <link>http://sigkill.dk/blog/archives/183-Climacs-pr0n-og-jubilum.html</link>
            <category>Lisp</category>
    
    <comments>http://sigkill.dk/blog/archives/183-Climacs-pr0n-og-jubilum.html#comments</comments>
    <wfw:comment>http://sigkill.dk/blog/wfwcomment.php?cid=183</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://sigkill.dk/blog/rss.php?version=2.0&amp;type=comments&amp;cid=183</wfw:commentRss>
    

    <author>nospam@example.com (Troels Henriksen)</author>
    <content:encoded>
    &lt;p&gt;
For præcist et år siden gik jeg i gang med at lære Common Lisp, det sprog, der sidenhed er blevet mit absolutte favoritsprog (og som tilmed var med til at introducere mig til rigtig datalogi).
&lt;/p&gt;

&lt;p&gt;
Jeg har i løbet af året arbejdet på en række mindre ting - mindre, fordi jeg ikke har været tilstrækkeligt familiær med sproget og dets redskaber til at overkomme større opgaver, men i løbet af de seneste måneder har jeg alligevel været involveret i et større projekt: &lt;a href=&quot;http://common-lisp.net/project/climacs/&quot;&gt;Climacs&lt;/a&gt; - en moderne implementation af en Emacs-editor i Common Lisp. Kombineret med &lt;a href=&quot;http://common-lisp.net/project/clim-desktop/&quot;&gt;CLIM-Desktop&lt;/a&gt; er Climacs allerede et udemærket udviklingsmiljø til Common Lisp - og det er allerede begyndt at se ganske fancy ud (&lt;a href=&quot;http://sigkill.dk/athas/climacs-pr0n.png&quot;&gt;Climacs pr0n!&lt;/a&gt;).
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sun, 30 Apr 2006 22:34:59 +0200</pubDate>
    <guid isPermaLink="false">http://sigkill.dk/blog/archives/183-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license>
</item>
<item>
    <title>Derfor Common Lisp</title>
    <link>http://sigkill.dk/blog/archives/178-Derfor-Common-Lisp.html</link>
            <category>Lisp</category>
    
    <comments>http://sigkill.dk/blog/archives/178-Derfor-Common-Lisp.html#comments</comments>
    <wfw:comment>http://sigkill.dk/blog/wfwcomment.php?cid=178</wfw:comment>

    <slash:comments>8</slash:comments>
    <wfw:commentRss>http://sigkill.dk/blog/rss.php?version=2.0&amp;type=comments&amp;cid=178</wfw:commentRss>
    

    <author>nospam@example.com (Troels Henriksen)</author>
    <content:encoded>
    &lt;p&gt;
  For snart et år siden begyndte jeg at lære mig
  selv &lt;a
  href=&quot;http://sigkill.dk/blog/archives/64-Practical-Common-Lisp.html&quot;&gt;Common
  Lisp&lt;/a&gt;. Jeg havde tidligere arbejdet med Emacs Lisp i forbindelse
  med udvidelse af GNU Emacs-editoren, men det var ikke det helt
  store. Jeg var i stand til at læse Lisp-kode, men jeg havde ikke
  forståelse for Common Lisp&#039;s kultur, teknologi, features og
  idiomer. Common Lisp blev meget hurtigt mit
  yndlings-programmeringssprog til næsten alle opgaver og har markant
  ændret hvordan jeg tænker på programmering, programmer, datalogi og
  computere i det hele taget. I dette indlæg vil jeg forsøge at
  beskrive hvorfor Lisp er vigtigt, hvorfor Lisp er sejt, hvorfor
  netop &lt;em&gt;du&lt;/em&gt; bør lære Lisp og hvor man skal starte.
&lt;/p&gt;

&lt;p&gt;
  Overordnet set findes der ikke noget sprog ved navn Lisp. Lisp er en
  betegnelse for en familie af højniveausprog, der alle arver features
  og designidéer fra det oprindelige Lisp-sprog, &lt;em&gt;LISP&lt;/em&gt;, der
  blev skabt omkring 1960. I dag er der tre større Lisp-sprog
  (&lt;em&gt;dialekter&lt;/em&gt;):
&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;strong&gt;Emacs Lisp&lt;/strong&gt;, den Lisp-dialekt som den kendte
    Emacs-editor er delvist skrevet i. Det er en gammel dialekt, der
    ikke har så mange features og som ikke er så avanceret som nyere
    dialekter, men til gengæld har det en masse funktioner relateret
    til tekstredigering. Det bruges kun i
    (&lt;a href=&quot;http://www.xemacs.org&quot;&gt;X&lt;/a&gt;)Emacs, og er der det (stort
    set) eneste sprog man kan bruge til at udvide og konfigurere
    editoren. Emacs Lisp er alt i alt ikke nogen synderligt god
    Lisp-dialekt, og bør så vidt muligt undgås.
  &lt;/li&gt;

  &lt;li&gt;
    &lt;strong&gt;Scheme&lt;/strong&gt; er en minimalistisk, moderne Lisp-dialekt,
    der er designet til brug i teoretisk datalogi i forbindelse med
    forskning i programmeringssprog og compilerdesign. Det blev ikke
    designet til brug i real-world programmer og har derfor ikke så
    meget bagudkompatibilitets-relateret urenhed, men heller ikke
    noget særligt stort standardbibliotek af funktioner.
  &lt;/li&gt;

  &lt;li&gt;
    &lt;strong&gt;Common Lisp&lt;/strong&gt; er den suverænt mest udbredte og
    velunderstøttede general-purpose Lisp-dialekt. Common Lisp er et
    moderne, &lt;a
    href=&quot;http://www.lispworks.com/documentation/HyperSpec/&quot;&gt;ANSI-standardiseret
    sprog&lt;/a&gt; (X3J13) designet til at være brugbart i store systemer
    og tager hensyn til bagudkompatibilitet med ældre, nu uddøde,
    Lisp-dialekter (Maclisp, ZetaLisp), hvilket medfører en noget mere
    rodet standard end Scheme. Common Lisp har en relativt stor mængde
    højkvalitets-miljøer og compilere, både frie og ufrie, samt flere
    libraries end sandsynligvis alle andre Lisp-dialekter tilsammen
    (muligvis med undtagelse af Emacs Lisp).
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
  Jeg foretrækker selv Common Lisp, men har også respekt for Scheme,
  og bruger det nu og da til mindre programmer, hvor simplicitet er i
  højsædet. Common Lisp er måske ikke lige så elegant som Scheme, men
  der er langt mere support og, i mine øjne, nogle mere kraftfulde
  standard-features, der gør Common Lisp stort set ubegrænset
  kraftfuldt - det kan praktisk taget emulere ethvert andet sprog uden
  større problemer og uden at blive til
  en &lt;a
  href=&quot;http://www.catb.org/jargon/html/T/Turing-tar-pit.html&quot;&gt;Turing
  tar-pit&lt;/a&gt; (mere om det senere).
&lt;/p&gt;

&lt;p&gt;
  Hvad gør Lisp-det-almene-koncept så fantastisk? En del af det er at
  Lisp er gearet imod funktionsorienteret programmering - en
  programmeringsstilart, hvor man, i modsætning til imperativ
  programmering, ikke siger &lt;em&gt;hvordan&lt;/em&gt; noget skal udregnes,
  men &lt;em&gt;hvad&lt;/em&gt; der skal udregnes. En del af dette er at undgå
  side-effekter, altså at variable skifter værdi. En af grundstenene
  indenfor funktionsorienteret programmering er at en funktion altid
  skal returnere samme værdi hver gang den kaldes med et unikt sæt
  elementer. Det betyder at udregningen af funktionens returværdi ikke
  må afhænge af &quot;globale variabler&quot; eller lignende, da disse kan ændre
  sig fra kald til kald. Det er naturligvis langt fra alle funktioner
  der kan skrives således, og det kræver tid at vænne sig til det, men
  når først man begynder at tænke funktionsorienteret bliver ens kode
  ofte lettere at forstå og med en &lt;em&gt;markant&lt;/em&gt; nedsat mængde
  bugs. Jo mindre data ændrer sig, desto mere forudsigelig er
  programkørslen, desto mindre potentiale er der for
  fejl. Funktionsorienteret programmering er ikke unikt for Lisp, og
  der
  findes &lt;a
  href=&quot;http://www.haskell.org&quot;&gt;andre&lt;/a&gt; &lt;a
  href=&quot;http://www.smlnj.org/&quot;&gt;sprog&lt;/a&gt; der tager konceptet langt
  længere end Lisp. En af Lisp&#039;s andre features er dog mere eller
  mindre unik for sproget - at kode og data er så tæt forbundet. Det
  første indtryk ikke-Lisp-programmøren får, når vedkommende ser et
  Lisp-program, er den massive mængde parenteser - programmet ser
  fuldstændigt ulæseligt ud, og læseren får den idé at
  Lisp-programmører bruger halvdelen af deres tid på at tælle
  parenteser (dette passer ikke). Parenteserne er ofte blevet fremført
  som en brist i Lisp&#039;s design, men de er måske den absolut vigtigste
  features - parenteserne beskriver nemlig enkelt-lænkede lister,
  Lisp&#039;s grundlæggende datastruktur. Det betyder at kode kan indlæses
  som enhver liste, at kode kan ændres og analyseres som enhver liste,
  af &lt;em&gt;enhver&lt;/em&gt; Lisp-programmør. Ethvert gyldigt Lisp-program kan
  indlæses som en datastruktur eller et objekt af en af Lisp&#039;s
  almindelige I/O-funktioner. I andre sprog ville dette involvere
  konstruktionen af en kompliceret parser, til at fortolke den måske
  tvetydige og ofte meget komplekse syntaks, og derefter uhyre
  forsigtighed fra programmørens side, for at bevare den syntaktiske
  korrekthed. Betyder dette noget i praksis, giver det nogle reelle
  fordele? Ja, det betyder at Lisp-programmører har lige så meget
  kontrol over sproget, som kun compiler-konstruktører har over andre
  sprog. Og det gør det naturligvis også afsindigt let at skrive
  værktøjer der foretager analyse af Lisp-kode. Med et enkelt kald til
  funktionen &lt;var&gt;read&lt;/var&gt; kan man læse et komplet parse-træ af et
  Lisp-program ind i hukommelsen - det vil jeg gerne se gjort for C i
  under 5000 linjer. I princippet kan man sige, at hvor andre sprog
  har en kompliceret syntaks, der så af compileren konverteres til et
  abstrakt syntaks-træ, så skriver man Lisp-kode direkte i det
  abstrakte syntakstræk, og kan derfor lettere se, og ændre, hvad
  compileren bliver fodret med. Lisp&#039;s simple syntaks betyder
  naturligvis også at det er let at parse i andre sprog, f.eks. vist
  i &lt;a href=&quot;http://www.modeemi.fi/~chery/lisp500/&quot;&gt;Lisp500&lt;/a&gt;, en
  implementation af Lisp i 500 linjer ANSI C. Den nemhed, hvormed man
  kan manipulere Lisp-kode, udnyttes primært til at lave
  runtime-generering af kode (&quot;programmer, der skriver programmer&quot;
  eller &quot;programmer, der omskriver sig selv, mens de kører&quot;) eller til
  at implementere makroer. Den simple syntaks muliggør også
  teksteditorer, som f.eks. Emacs, der er i stand til at manipulere
  med programmets logiske struktur, i stedet for dets tegn. En tredje
  af Lisp&#039;s fordele er at det er garbage-collected, men det er nok et
  mindre vindende argument i dag, end det var for 30 år siden.
&lt;/p&gt;

&lt;p&gt;
  Når Common Lisp skal promoveres er en af de oftest nævnte
  fordele &lt;em&gt;makroer&lt;/em&gt;, så hvorfor bryde traditionen? Desuden er
  det suverænt en af de sejeste features i noget programmeringssprog
  jeg endnu har set. Nogle kender måske makroer fra C, og forstår ikke
  hvorfor Common Lisp-programmører er så begejstrede for dem. Det er
  forståeligt - C&#039;s preprocessor-baserede makroer er primitive og
  forårsager let fejl. Common Lisp&#039;s er i en helt anden klasse, og
  drager nytte af at Lisp-kode bare er lister. Et Lisp-makro kan
  forstås som en funktion, der kaldes ved compile-time, i stedet for
  ved runtime. Når Lisp-compileren gennemgår et stykke
  kode, &lt;em&gt;ekspanderer&lt;/em&gt; den først alle makroer - det sker ved at
  makrofunktionen kaldes med de makro-parametre programmøren har
  angivet i sin kode, hvorefter makrofunktionens returværdi indsættes
  som kode i stedet for makroen. Makroer giver derved mulighed for at
  manipulere og ændre koden efter den er blevet læst af parseren og
  før den bliver omdannet til maskinkode af
  compileren. Makrofunktionen får sine parametre som Lisp-objekter
  (f.eks. lister) og kan ligeså returnere kode som en ganske
  almindelig liste, så at skrive en makro er næsten lige så let som at
  skrive en funktion - der er nogle få detaljer vedrørende det faktum
  at makroekspansion foregår ved compile-time, som man bør være
  opmærksom på, men grundlæggende er det at skrive en makro og en
  funktion to ret ens processer i Lisp. Makroer giver enhver
  programmør mulighed for at ændre sproget præcist som vedkommende
  lyster, næsten uden grænse. Det er muligt at skrive en makro, der
  som parameter tager {C++, C#, VB, Haskell, SML, Brainfuck,
  FORTRAN}-kode og genererer Lisp-kode til compileren, hvis man skulle
  have lyster i den retning. Common Lisp-programmører bruger ofte
  makroer til at udvide sproget, lave syntaktisk sukker og
  implementere domæne-specifikke sprog. Nu og da kan en del af et
  Lisp-program udtrykkes klarere i et sprog designet til opgaven, og
  via makroer kan man implementere et sådan under-sprog direkte i
  Lisp. Makroer bruges ofte til mindre syntaktisk detaljer, der
  isoleret set virker lidt banale, men som sammenlagt kan øge
  fornøjelsen ved at skrive programmer. Tag f.eks. den klassiske
  design pattern &lt;em&gt;singleton&lt;/em&gt; - hvis man ønsker at lave en sådan
  i C++ involverer det som regel enten at skrive en pæn bid kode og
  nedarve fra en anden klasse. Hvis C++ havde makroer som Lisp, ville
  man blot kunne udvide sproget til at tillade en syntaks
  som &lt;code&gt;singleton MySingleton { /* stuff */ };&lt;/code&gt;,
  hvor &lt;var&gt;singleton&lt;/var&gt;-makroen ville ekspandere til den kode der
  er nødvendig, for at implementere en singleton. Et andet
  traditionelt eksempel er Common Lisp&#039;s &lt;var&gt;loop&lt;/var&gt;-makro, der
  implementerer et totalt u-Lisp-agtigt og domænespecifikt sprog til
  at udtrykke looping:
&lt;/p&gt;

&lt;pre&gt;
  (loop for odd in (list 1 3 5 7 9)
        for even in (list 2 4 6 7 8)
      collecting odd
      collecting even
      maximizing odd into max
      maximizing even into max)
&lt;/pre&gt;

&lt;p&gt;
  Dette simple loop itererer over to lister (samtidigt), samler den
  til en fælles liste og indsætter den største værdi i
  variablen &lt;var&gt;max&lt;/var&gt;. Alt hvad makroer kræver er at deres
  parametre opfylder grundlæggende Lisp-syntaks-regler, f.eks. et
  balanceret antal parenteser, pga. parseren. Man kan dog godt omgå
  dette, hvis man er virkelig ivrig, ved at definere
  en &lt;em&gt;reader-makro&lt;/em&gt;, der ændrer på parserens opførsel, og
  tillader en at tage total kontrol over den stream som parsingen
  foregår fra. Dette bruges typisk til at implementere nye literal
  types, f.eks. kan man få parseren til at omdanne enhver instans af
  &lt;code&gt;$10&lt;/code&gt; i kildekoden til et kald til at oprette et objekt
  der repræsenterer 10 dollar (mere specifikt $N til N dollar). Denne
  fleksibilitet er helt fantastisk når først man er vant til den, men
  man må dog altid forsøge at beherske sig - det er kraftige
  værktøjer, men de gør det meget let at lave grumme, grumme fuckups,
  hvis man skulle være uforsigtig.
&lt;/p&gt;

&lt;p&gt;
  Lisp-miljøer/runtimes er programmer ganske ulig hvad man normalt ser
  i dag, og vil være fremmede for de fleste nye Lisp-programmører,
  ganske som de var det for mig engang (Emacs-brugere vil dog kunne
  genkende en del af dem). På sin vis minder Lisp-runtimes meget om
  .NET-runtimes og JRE&#039;s - et runtime-miljø kører forskellige
  programmer og man kan via diverse protokoller snakke med miljøet. I
  Lisp tager dette som regel form af en REPL - et
  Read-Eval-Print-Loop. Det er en simpel kommandoprompt, hvor man kan
  indtaste et Lisp-udtryk, få det evalueret og få udskrevet
  returværdierne. Ved denne prompt har man som bruger fuld adgang til
  Lisp-miljøet, inklusive compileren, på samme måde som alle
  programmer har det ved runtime. På ethvert tidspunkt kan
  Lisp-miljøet blive bedt om at kompilere et udtryk, en funktion eller
  ændre værdien af data forskellige steder i systemet. Det er en
  interaktivitet man hurtigt lærer at værdsætte, hvis man, f.eks. som
  C-programmør, er vant til at ens miljø sætter store grænser op
  mellem write-time, compile-time og run-time for ens program. I Lisp
  er miljøet altid til rådighed og kan altid evaluere ethvert
  Lisp-udtryk man måtte ønske. Miljøet compiler alle
  funktionsdefinitioner, man som programmør eller program indlæser,
  til maskinkode, og der er således ikke et større performancetab end
  i .NET og Java, og da Lisp er let at optimere, og compilerne desuden
  har mere end 20 års optimeringsteknologi bag sig, er Lisp nu og da
  overraskende hurtigt.
&lt;/p&gt;

&lt;p&gt;
  Dette super-interaktive miljø har været en stor fordel for mig i de
  seneste par dage, hvor jeg har arbejdet på
  tekst-editoren &lt;a
  href=&quot;http://common-lisp.net/project/climacs/&quot;&gt;Climacs&lt;/a&gt;. Mit pt.
  foretrukne udviklingsmiljø til Common Lisp er GNU Emacs
  med &lt;a href=&quot;http://common-lisp.net/project/slime/&quot;&gt;SLIME&lt;/a&gt;, der
  holder en åben socket-baseret forbindelse til Lisp-miljøet, og
  derved, med et enkelt tastetryk, kan sende en opdateret
  funktionsdefinition til Lisp-miljøet, der så vil kompilere og
  installere funktionen i systemet. Dette udnyttede jeg, da jeg
  debuggede en række Lisp-funktioner i Climacs - jeg ændrede
  funktionen i Emacs, skiftede over til Climacs-vinduet, testede den,
  og vendte tilbage til Emacs for at arbejde videre. At skifte over
  til Climacs og teste min funktion tog mig vel i gennemsnit under 3
  sekunder, da jeg jo ikke behøvede at genstarte programmet - Lisp har
  ingen problemer med at ændre programmer, der allerede er indlæst -
  og jeg behøvede heller ikke genindtaste den test-data jeg brugte til
  at afprøve min kode. I andre sprog ville jeg have været nødt til at
  genstarte det program jeg testede hver gang jeg ændrede en smule på
  en funktion, men ikke i Lisp - der kan jeg omskrive mine programmer
  mens de kører. Den eneste begrænsning er at en ændring af en
  eksisterende funktion kun vil have effekt på nye funktionskald, hvis
  programmets control-flow allerede befinder sig &lt;em&gt;i&lt;/em&gt;
  funktionen, vil det ikke blive påvirket før næste gang det træder
  ind i funktionen. Dette påvirker naturligvis ens udviklingsrytme i
  massiv grad, og man bliver langt mere villig til at eksperimentere,
  fordi det går så hurtigt med at få feedback på ens forsøg.
&lt;/p&gt;

&lt;p&gt;
  Der er naturligvis ingen rose uden torne, og Common Lisp har også
  sine fejl, hvor den primære er manglen på libraries. Hvis man er
  vant til den massive mængde libraries der findes i forbindelse med
  Java, .NET, C eller C++, så kan man let blive skuffet over det noget
  mere magre udvalg indenfor Common Lisp. De libraries der findes er
  dog ofte ret gode, og da der igennem årtier konsistent er blevet
  produceret store programmer i Common Lisp, må det jo være muligt at
  klare sig. Common Lisp er et sprog i vækst, og selv i det lille år
  hvor jeg har observeret sproget, er der sket store landvindinger i
  library-udbuddet og implementations-kvaliteten, så det er så absolut
  ikke et døende sprog man i givet fald tilslutter sig. Selvom Common
  Lisp nok aldrig bliver rigtigt mainstream, så har det altid været,
  og vil nok altid være, et særdeles velegnet sprog til at løse svære
  opgaver og give ansvarlige programmører ekstremt kraftfulde
  værktøjer til det.
&lt;/p&gt;

&lt;p&gt;
  Alt i alt kan jeg kun anbefale nysgerrige programmører at lære
  Common Lisp - det er en for det første en øjenåbner og for det andet
  et praktisk værktøj. I disse tider er det rimeligt nemt at
  installere et frit Common Lisp-miljø og finde den nødvendige
  dokumentation til at komme i gang, men det skal dog siges med det
  samme at den optimale oplevelse får man på et GNU/Linux-system
  (muligvis også OS X). Den letteste måde at komme i gang på, og den
  jeg også selv fulgte for omkring et år siden, er at læse den gratis
  tilgængelige bog &lt;a href=&quot;http://gigamonkeys.com/book/&quot;&gt;Practical
  Common Lisp&lt;/a&gt;, der også indeholder anvisninger på at opsætte et
  udviklingsmiljø (også under Windows). Derefter kan man gå i gang med
  at læse &lt;a href=&quot;http://planet.lisp.org&quot;&gt;Planet Lisp&lt;/a&gt; og besøge
  #lisp på &lt;a href=&quot;http://freenode.net&quot;&gt;Freenode&lt;/a&gt; i al den fritid
  man naturligvis opnår grundet produktivitetsforøgelsen ved at skifte
  til Lisp. Læs evt. også
  min &lt;a href=&quot;http://sigkill.dk/code/commonlisp.html&quot;&gt;Common
  Lisp-side&lt;/a&gt;.
&lt;/p&gt;

&lt;!--  LocalWords:  Common Emacs-editoren Scheme compilerdesign. real-world read
 --&gt;
&lt;!--  LocalWords:  Maclisp ZetaLisp compilere ufrie libraries Turing tar-pit
 --&gt;
&lt;!--  LocalWords:  O-funktioner. compiler-konstruktører compileren parse
 --&gt;
 
    </content:encoded>

    <pubDate>Tue, 11 Apr 2006 01:25:00 +0200</pubDate>
    <guid isPermaLink="false">http://sigkill.dk/blog/archives/178-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license>
</item>
<item>
    <title>Interaktiv programmering</title>
    <link>http://sigkill.dk/blog/archives/175-Interaktiv-programmering.html</link>
            <category>Lisp</category>
    
    <comments>http://sigkill.dk/blog/archives/175-Interaktiv-programmering.html#comments</comments>
    <wfw:comment>http://sigkill.dk/blog/wfwcomment.php?cid=175</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://sigkill.dk/blog/rss.php?version=2.0&amp;type=comments&amp;cid=175</wfw:commentRss>
    

    <author>nospam@example.com (Troels Henriksen)</author>
    <content:encoded>
    &lt;p&gt;
  Jeg har efterhånden gjort det i et godt stykke tid, men nu og da
  stopper jeg alligevel op og tænker - &lt;em&gt;hvor er interaktiv
  programmering bare fedt!&lt;/em&gt; Konceptet med at kunne omskrive et
  program &lt;em&gt;mens det kører&lt;/em&gt;, og evaluere ethvert programudtryk
  interaktivt, ved en prompt, uden rekompilering eller andet skidt, er
  en helt fantastisk oplevelse sammenlignet med traditionelle
  edit-compile-run-loops. Hvor man normalt ændrer nogle ting,
  rekompilerer, tester og fikser det, der ikke virker, føler man sig
  når man udfører interaktiv programmering mere som en kunstner, der
  former en klat ler eller en klump marmor. Man får utroligt hurtigt
  svar på sine formodninger og man kan på ekstremt kort tid nå at
  gennemgå mange forskellige iterationer af en given implementation af
  noget funktionalitet. Det lynhurtige feedback-loop inviterer en til
  at udføre eksperimenter, og min erfaring er derfor at man har
  lettere ved at opdage både optimale løsninger på problemer, samt
  uforudsete konsekvenser af ens ændringer. Interaktiv programmering
  fjerner mange af de kedelige elementer, og lader en koncentrere sig
  om det essentielle og det underholdende - at få skrevet noget kode.
&lt;/p&gt;

&lt;p&gt;
  Og da jeg samtidigt arbejder på en editor/IDE er fornøjelsen
  naturligvis endnu større - at hacke på et program i selve programmet
  er så sejt at det næsten er surrealistisk.
&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Tue, 04 Apr 2006 23:16:48 +0200</pubDate>
    <guid isPermaLink="false">http://sigkill.dk/blog/archives/175-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license>
</item>
<item>
    <title>CLIM-desktop</title>
    <link>http://sigkill.dk/blog/archives/146-CLIM-desktop.html</link>
            <category>Lisp</category>
    
    <comments>http://sigkill.dk/blog/archives/146-CLIM-desktop.html#comments</comments>
    <wfw:comment>http://sigkill.dk/blog/wfwcomment.php?cid=146</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://sigkill.dk/blog/rss.php?version=2.0&amp;type=comments&amp;cid=146</wfw:commentRss>
    

    <author>nospam@example.com (Troels Henriksen)</author>
    <content:encoded>
    &lt;p&gt;
Jeg har
 &lt;a
 href=&quot;http://www.sigkill.dk/blog/archives/137-Common-Lisp-Interface-Manager.html&quot;&gt;tidligere&lt;/a&gt;
 skrevet om &lt;a href=&quot;http://www.cliki.net/CLIM&quot;&gt;CLIM&lt;/a&gt;, &lt;em&gt;Common
 Lisp Interface Manager&lt;/em&gt;. Her i dag har jeg
 undersøgt &lt;a
 href=&quot;http://www.cliki.net/clim-desktop&quot;&gt;CLIM-desktop&lt;/a&gt;, en pakke
 af programmer, der danner et mere eller mindre integreret
 CLIM-baseret udviklingsmiljø til Common Lisp. Lad mig sige det med
 det samme: CLIM-desktop og dets komponenter er som hovedregel
 ekstremt buggy
 (især &lt;a href=&quot;http://common-lisp.net/project/climacs/&quot;&gt;Climacs&lt;/a&gt;,
 teksteditoren er slem), ikke udpræget finpudsede og ganske besværlige
 at sætte op og bruge. Det er dog ret tydeligt at der er stort
 potentiale bag et miljø, der er helt og holdent implementeret i
 CLIM. At stort set alle grafiske elementer er kontekst-sensitive i
 den rigtige sammenhæng er en fantastisk feature, som virkelig gør
 interfacet dynamisk og effektivt at arbejde med. CLIM-desktops ideal
 er hvad Emacs er en primitiv efterligning af. CLIM-desktop gør det
 meget let at udnytte Lisp&#039;s
 indbyggede &lt;a
 href=&quot;http://en.wikipedia.org/wiki/Reflection_%28computer_science%29&quot;&gt;&lt;em&gt;introspection&lt;/em&gt;&lt;/a&gt;-faciliteter,
 da det pludselig er ganske trivielt at klikke sig rundt i slots,
 generiske funktioner, subklasser og superklasser i et klassehieraki,
 samt konstant, selv når man er nok så langt nede i debuggeren, at
 kunne pille ethvert objekt fra hinanden.
&lt;/p&gt;

&lt;p&gt;
  Denne gang har jeg
  screenshots. På &lt;a
  href=&quot;http://sigkill.dk/athas/clim-desktop1.png&quot;&gt;dette
  screenshot&lt;/a&gt; vises Climacs, CLIM-listeneren og Beirc (en
  IRC-klient). I CLIM-listeneren vises resultatet af lidt klikkeri
  gennem et objekthieraki - derudover er listeren en fuldgyldig REPL,
  hvor man kan indtaste vilkårlig Lisp-kode. Hvis man, eller
  programmerne, dummer sig, ender man i debuggeren
  (&lt;a href=&quot;http://sigkill.dk/athas/clim-desktop2.png&quot;&gt;nederst til
  højre&lt;/a&gt;), hvor man kan gennemgå en stack trace, se på
  funktionsparametre, etc.
&lt;/p&gt;

&lt;p&gt;
  CLIM-desktop har potentiale - nok ikke som desktop til den almene
  bruger, men som udviklingsmiljø til Common Lisp vil det snildt kunne
  overgå &lt;a href=&quot;http://common-lisp.net/project/slime/&quot;&gt;SLIME&lt;/a&gt;,
  hvis der bliver udviklet en smule mere på det.
&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Wed, 11 Jan 2006 22:04:48 +0100</pubDate>
    <guid isPermaLink="false">http://sigkill.dk/blog/archives/146-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license>
</item>
<item>
    <title>Common Lisp Interface Manager</title>
    <link>http://sigkill.dk/blog/archives/137-Common-Lisp-Interface-Manager.html</link>
            <category>Lisp</category>
    
    <comments>http://sigkill.dk/blog/archives/137-Common-Lisp-Interface-Manager.html#comments</comments>
    <wfw:comment>http://sigkill.dk/blog/wfwcomment.php?cid=137</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://sigkill.dk/blog/rss.php?version=2.0&amp;type=comments&amp;cid=137</wfw:commentRss>
    

    <author>nospam@example.com (Troels Henriksen)</author>
    <content:encoded>
    &lt;p&gt;
  De sidste par dage er, for mit vedkommende, gået med at
  eksperimentere med &lt;a href=&quot;http://www.cliki.net/CLIM&quot;&gt;CLIM&lt;/a&gt;
  - &lt;em&gt;Common Lisp Interface Manager&lt;/em&gt; - kort sagt, et
  widget-framework til Common Lisp. Det er bemærkelsesværdigt at CLIM,
  der er næsten 20 år gammelt, har features, der endnu ikke er set i
  nutidens udbredte, grafiske miljøer. Ja, jeg vil nu skrive om
  grafiske interfaces, ja, jeg vil rose dem. Ja, det er muligvis en
  gris, der flyver rundt, uden for dit vindue.
&lt;/p&gt;

&lt;p&gt;
  En af disse features, og måske den mest centrale grundpille i hele
  CLIM&#039;s design, er konceptet omkring &lt;em&gt;presentations&lt;/em&gt;. Ethvert
  grafisk interface præsenterer information til brugeren. Dette sker
  ved at printe tekst, billeder eller andre grafiske repræsentationer,
  men i selve udprintningen mister de deres oprindelige datatype - de
  bliver bare til tekst, et billede, en knap, eller et andet grafisk
  element. Hvis interface-designeren ønsker at de skal have en speciel
  betydning, er han nødt til selv at sætte signaler op til at opfange
  musetryk, drag&#039;n&#039;drop, etc. Sådan er det ikke med CLIM - her
  præsenteres information til brugeren ved at &lt;em&gt;present&lt;/em&gt;&#039;e det,
  og en CLIM &lt;em&gt;presentation&lt;/em&gt; husker sit oprindelige objekt, så
  man fra ethvert grafisk element kan sige præcist hvilket
  Lisp-objekt, der står bag. Naturligvis kan et stykke data stadigvæk
  repræsenteres via tekst eller et grafisk element, men CLIM vil huske
  forbindelsen mellem brugerinterface-elementet og
  Lisp-objektet. Dette giver for det første brugerinterfacet en massiv
  grad
  af &lt;a
  href=&quot;http://en.wikipedia.org/wiki/Reflection_(computer_science)&quot;&gt;reflection&lt;/a&gt;,
  noget der skulle få OOP-tilhængere til at klappe i deres små
  hænder. For det andet skaber det også en alternativ inputmetode til
  diverse programmer. Hvis et program f.eks. beder om et billede som
  input, så vil enhver repræsentation, der er &lt;em&gt;present&lt;/em&gt;&#039;et som
  typen &quot;billede&quot;, kunne bruges som input til programmet, blot ved at
  trykke på det - også repræsentationer fra andre programmer end det,
  der beder om input. Et Lisp-objekts interne type, og hvordan det
  repræsenteres i brugerinterfacet, behøver naturligvis ikke være
  identisk - et billede kan godt vises for brugeren som en
  tekststreng, eller et tal - det er ligegyldigt for CLIM, det vil
  stadigvæk være gyldigt input, når et program beder om et billede.
  Programmøren kan naturligvis altid oprette nye præsentationstyper og
  metoder til at indlæse, og præsentere, objekter som den relevante
  type, og selve systemet, der sørger for at denne mekanisme virker,
  er næsten uendeligt fleksibelt, og kan tweakes på stort set enhver
  mulig måde.
&lt;/p&gt;

&lt;p&gt;
  Men ak, ingen applikation uden en null pointer. Lige så elegant og
  avanceret som CLIM er, rent specifikationsmæssigt, lige så dårlig er
  den eneste frie
  implementation, &lt;a
  href=&quot;http://common-lisp.net/project/mcclim/&quot;&gt;McCLIM&lt;/a&gt;, der ofte
  er plaget af besynderlige bugs. Ydermere stammer CLIM fra en anden
  tid, hvor man ikke havde de samme principper omkring GUI-design som
  man har i dag, derfor kan CLIM-applikationer virke ekstremt arkaiske
  og gammeldags. Det rører dog ikke ved deres effektivitet - CLIM blev
  designet som en højere enhed mellem de muligheder hhv. en
  kommandolinje og en GUI giver, og grundprincipperne er stadigvæk
  ganske solide.
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Fri, 23 Dec 2005 23:52:06 +0100</pubDate>
    <guid isPermaLink="false">http://sigkill.dk/blog/archives/137-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license>
</item>
<item>
    <title>Metaprogrammering</title>
    <link>http://sigkill.dk/blog/archives/136-Metaprogrammering.html</link>
            <category>Lisp</category>
    
    <comments>http://sigkill.dk/blog/archives/136-Metaprogrammering.html#comments</comments>
    <wfw:comment>http://sigkill.dk/blog/wfwcomment.php?cid=136</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://sigkill.dk/blog/rss.php?version=2.0&amp;type=comments&amp;cid=136</wfw:commentRss>
    

    <author>nospam@example.com (Troels Henriksen)</author>
    <content:encoded>
    &lt;p&gt;
Jeg har netop læst &lt;a href=&quot;http://opal.cabochon.com/~stevey/blog-rants/lisp-wins.html&quot;&gt;en rant&lt;/a&gt;, der disser Java (hvilket altid er godt), og meget velartikuleret beskriver hvorfor metaprogrammering er en god ting. Da jeg for tiden &lt;a href=&quot;http://www.amazon.co.uk/exec/obidos/ASIN/0262610744/026-8694348-6593204&quot;&gt;læser om metaprogrammering&lt;/a&gt;, og desuden er enig i hans antagelser, vil jeg anbefale alle at læse hans artikel, og prøve et sprog der understøtter metaprogrammering. Hvorfor skal man kun kunne manipulere data? Hvad er der galt i at manipulere kode?
&lt;/p&gt;

&lt;p&gt;
&lt;strong&gt;Edit:&lt;/strong&gt; Wow, den rant er skrevet af en meget klog mand. En af hans andre artikler er også &lt;a href=&quot;http://opal.cabochon.com/~stevey/blog-rants/the-emacs-problem.html&quot;&gt;obligatorisk læsning&lt;/a&gt;.
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Tue, 20 Dec 2005 19:55:15 +0100</pubDate>
    <guid isPermaLink="false">http://sigkill.dk/blog/archives/136-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license>
</item>
<item>
    <title>SDBL, Darcs, Portable AllegroServe</title>
    <link>http://sigkill.dk/blog/archives/125-SDBL,-Darcs,-Portable-AllegroServe.html</link>
            <category>Lisp</category>
    
    <comments>http://sigkill.dk/blog/archives/125-SDBL,-Darcs,-Portable-AllegroServe.html#comments</comments>
    <wfw:comment>http://sigkill.dk/blog/wfwcomment.php?cid=125</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://sigkill.dk/blog/rss.php?version=2.0&amp;type=comments&amp;cid=125</wfw:commentRss>
    

    <author>nospam@example.com (Troels Henriksen)</author>
    <content:encoded>
    &lt;p&gt;
  Jeg har fået kodet en smule Lisp her i weekenden, helt præcist har
  jeg arbejdet videre på min database-engine, SDBL, så de fleste
  grimme bugs burde være fjernet. Der er stadigvæk ikke alt for meget
  funktionalitet, og visse af de interne datastrukturer (f.eks. brugen
  af flade arrays til at gemme data) har vist sig at være ret
  upraktiske. Jeg overvejer at skifte over til at bruge cirkulære,
  linkede arrays (hvor arrays bestående af måske 10 til 20 celler er
  forbundet i en linked liste), og opbygge indices ind i dem, for at
  sikre hurtig lookup. Det hjalp gevaldigt på mængden af rettede fejl,
  da jeg begyndte at bruge SDBL som backend til nogle trivielle
  test-programmer -
  en &lt;a href=&quot;http://sigkill.dk/code/sdbl/scddb.lisp&quot;&gt;CD-database&lt;/a&gt;,
  og, hvad der nok er mere interessant,
  en &lt;a href=&quot;http://sigkill.dk/code/sdbl/tagwall.lisp&quot;&gt;kollaborativ
  tagwall&lt;/a&gt; (min WikiWikiWall). Tagwallen er et webprogram, der
  bruger &lt;a href=&quot;http://portableaserve.sourceforge.net/&quot;&gt;Portable
  AllegroServe&lt;/a&gt;. Når min computer er tændt, kan tagwallen
  ses &lt;a href=&quot;http://athas.dyndns.dk:1337/tagwall&quot;&gt;her&lt;/a&gt;. Hverken
  CD-databasen eller tagwallen udviser udpræget god kodeskik, men det
  var heller ikke formålet med dem.
&lt;/p&gt;

&lt;p&gt;
  Portable AllegroServe er en rigtig rar webserver at arbejde med. Det
  er en portabel udgave af open-source webserveren AllegroServe, som
  &lt;a href=&quot;http://www.franz.com/&quot;&gt;Franz Inc.&lt;/a&gt; udviklede som
  eksempel på multithreaded udvikling med Allegro Common Lisp. I
  modsætning til f.eks. Apache er AllegroServe ikke filorienteret -
  man sætter ikke en eller anden mappe som rod, hvorefter serveren
  sever ud fra den. I stedet benytter man en &quot;publish&quot;-funktion, så
  man kan tilknytte HTTP-queries til specifikke filer, til enten
  reelle filer, eller Lisp-funktioner, hvis output bliver sendt som
  svar til klienten. På den server der driver min tagwall har jeg
  således tilknyttet queries til filen &quot;/tagwall&quot;, til
  funktionen &lt;em&gt;sdbl-tagwall::tagwall&lt;/em&gt;, hvis returværdi bliver
  brugt som svar til klienten. Det er ret smart.
&lt;/p&gt;

&lt;p&gt;
  Et andet stykke fabelagtig softwareteknologi, som jeg virkelig er
  blevet betaget af i denne weekend, er
  versionskontrol-systemet &lt;a href=&quot;http://darcs.net/&quot;&gt;Darcs&lt;/a&gt;. Et
  versioneringssystem er, groft sagt, et program der holder styr på
  kildekoden til et program, logger alle ændringer til koden, og giver
  mulighed for at gå tilbage i historien, hvis nye ændringer er
  problematiske. &lt;a
  href=&quot;http://en.wikipedia.org/wiki/Version_control_system&quot;&gt;Wikipedia
  kan forklare det bedre end jeg kan&lt;/a&gt;. Det der virkelig fængede mig
  ved Darcs, er at et er utrolig simpelt at bruge - i modsætning til
  CVS, som jeg tidligere har arbejdet med. For det første er Darcs&#039;
  kommandolinjeprogram simpelt at arbejde med, ret selvdokumenterende,
  og med interaktive dialoger til stort set alt. For det andet kræver
  Darcs ikke at man kører et serverprogram - et Darcs-repository er
  bare en mappe, og man må selv om hvorvidt man tilgår den via SSH,
  FTP, SMB, NFS eller lokalt. I forhold til andre
  versionskontrol-systemer er Darcs simpelt at komme i gang med, har
  en masse nyttige features (såsom at ændringer ikke er
  filspecifikke), og i mine øjne ideelt til enkelte programmører, der
  blot ønsker noget simpelt til at holde styr på deres kode. Muligvis
  kan Darcs også bruges af større hold, med mere komplekse behov, men
  det har jeg ikke selv haft mulighed for at afprøve - udviklingen af
  selve Darcs foregår dog via Darcs. Jeg kan kun anbefale
  at &lt;a href=&quot;http://www.darcs.net/DarcsWiki/GettingStarted&quot;&gt;læse
  tutorialen&lt;/a&gt; og komme i gang.
&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Sun, 27 Nov 2005 17:57:28 +0100</pubDate>
    <guid isPermaLink="false">http://sigkill.dk/blog/archives/125-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license>
</item>
<item>
    <title>Hurra for SLIME og Lisp!</title>
    <link>http://sigkill.dk/blog/archives/109-Hurra-for-SLIME-og-Lisp!.html</link>
            <category>Lisp</category>
    
    <comments>http://sigkill.dk/blog/archives/109-Hurra-for-SLIME-og-Lisp!.html#comments</comments>
    <wfw:comment>http://sigkill.dk/blog/wfwcomment.php?cid=109</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://sigkill.dk/blog/rss.php?version=2.0&amp;type=comments&amp;cid=109</wfw:commentRss>
    

    <author>nospam@example.com (Troels Henriksen)</author>
    <content:encoded>
    &lt;p&gt;
Jeg sidder her til aften og prikker lidt
til &lt;a href=&quot;http://common-lisp.net/project/climacs/&quot;&gt;Climacs&lt;/a&gt;, i
håb om at jeg kan få det til at udføre nogle nye kunster. Det er en
relativt stor kodebase, og der er også en større mængde mere eller
mindre buggy libraries, som Climacs gør brug af. At forstå et
kompliceret system er svært nok i forvejen, og det bliver ikke lettere
af at bruge et primitivt udviklingsmiljø, der ikke understøtter så
mange forskellige måder at prikke til koden på, men kun tillader at
man ændrer i nogle filer, recompiler, og ser hvad der sker. Derfor er
jeg glad for at Climacs er skrevet i Common Lisp, for
med &lt;a href=&quot;http://common-lisp.net/project/slime/&quot;&gt;SLIME&lt;/a&gt; i GNU
Emacs har jeg en editor der er rimeligt tæt integreret med Common
Lisp-runtime-programmet, der delvist forstår Common Lisp, og har en
række features, der gør det lettere at forstå en relativt
udokumenteret, fremmed kodebase. Især kan jeg godt
lide &lt;em&gt;slime-edit-definition&lt;/em&gt; (&lt;strong&gt;M-.&lt;/strong&gt;), der gør
det muligt at springe direkte til definitionen for en funktion, en
variabel, en klasse, eller noget som helst andet. At dette overhovedet
kan lade sig gøre, er naturligvis også en bieffekt af fri/åben
kode. For mit vedkommende er det en stor hjælp at jeg kan læse
kildekoden for de værktøjer jeg bruger, og så er jeg sådan set
ligeglad med anti-FOSS horderne, der påstår at det alligevel ikke er
andre end de primære udviklere, der nogensinde ser på et stykke
kildekode, selv hvis det er åbent. En anden rar funktion
er &lt;em&gt;slime-describe-symbol&lt;/em&gt; (&lt;strong&gt;C-c C-d C-d&lt;/strong&gt;), der
viser stort set enhver tilgængelig information om et givent symbol -
hvis det er en funktion, hvilke parametre den tager, eventuel inline
dokumentation, information om hvornår, og hvorfra, den blev compiled,
osv. Hvis det er en klasse vises alle relaterede klasser, det være sig
superclasses eller subclasses. Og sidst, men måske vigtigst, er
muligheden for at have en hel runtime kørende som en kommandoprompt,
hvor man blot kan skrive arbitrære Lisp-udtryk, og få dem evalueret
med det samme, også en virkelig fed feature, der gør det meget
hurtigere at teste funktioner, end andre sprogs edit-compile-test
cyklusser.
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Fri, 28 Oct 2005 23:51:56 +0200</pubDate>
    <guid isPermaLink="false">http://sigkill.dk/blog/archives/109-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license>
</item>
<item>
    <title>Simple DataBase in Lisp</title>
    <link>http://sigkill.dk/blog/archives/97-Simple-DataBase-in-Lisp.html</link>
            <category>Lisp</category>
    
    <comments>http://sigkill.dk/blog/archives/97-Simple-DataBase-in-Lisp.html#comments</comments>
    <wfw:comment>http://sigkill.dk/blog/wfwcomment.php?cid=97</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://sigkill.dk/blog/rss.php?version=2.0&amp;type=comments&amp;cid=97</wfw:commentRss>
    

    <author>nospam@example.com (Troels Henriksen)</author>
    <content:encoded>
    &lt;p&gt;
For tiden arbejder jeg på et program kaldet SDBL, en forkortelse for &lt;em&gt;Simple DataBase in Lisp&lt;/em&gt;. Det er et simpelt relationelt databasesystem, der kan bruges som et library af Common Lisp-programmer. Jeg har ikke arbejdet på det i mere end et par dage (og meget af det har jeg omskrevet en del gange), så det er i sandhed simpelt: Det er ikke threadsafe, det kan kun bruges fra Common Lisp, og ikke på tværs af processer, det understøtter kun meget simple queries (stub-JOIN, INSERT, SELECT, DROP, UPDATE, men med andre navne og syntaks), der er ingen SQL-support, og hele programmet er på omkring 500 linjer. Hvad der derimod er, er en, i mine øjne, ret sej metode til at gemme en database til disk. Normalt gøres den slags ved at definere et binært, XML-baseret, eller på anden måde programspecifikt format. Under alle omstændigheder, noget der baseret på de fleste informationer kan kaldes &lt;em&gt;data&lt;/em&gt;. Dette er ikke den måde SDBL gør tingene på, i stedet bliver der skrevet en Lisp-expression til disk, et lille Lisp-program, der, når det køres, returnerer en database med samme indhold, som den database der blev brugt som parameter, da koden blev genereret. Oprindeligt gjorde jeg det på denne måde fordi det virkede som det mest enkle (under 30 linjer kode), men nu er jeg efterhånden blevet ret begejstret for den fremgangsmåde. At en sådan ting overhovedet kan lade sig gøre viser hvor stor en fordel Lisp&#039;s opfattelse af &quot;data som kode - kode som data&quot; kan være - den fremgangsmåde jeg har brugt i SDBL kan ganske enkelt ikke lade sig gøre i de fleste andre sprog. Og i de sprog hvor den &lt;em&gt;er&lt;/em&gt; en mulighed (f.eks. &lt;a href=&quot;http://www.php.net&quot;&gt;PHP&lt;/a&gt;), gør syntaksen det så besværligt at generere gyldig og korrekt kode, at metoden mister en del af sine fordele. Lisp&#039;s syntaks, der ellers er foragtet af så mange der ikke er vant til den, gør at det ikke er sværere at generere gyldig kode, end det er at skabe en hvilken som helst anden liste. Et Lisp-program er vitterligt ikke andet end én eller flere lister.
&lt;/p&gt;

&lt;p&gt;
Hvis folk har lyst til at se på SDBL smider jeg nu og da kildekoden op &lt;a href=&quot;http://www.sigkill.dk/code/sdbl.lisp&quot;&gt;her&lt;/a&gt; (kun én fil, indtil jeg mener at systemet er så stort, at der er behov for at dele det op).
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Tue, 04 Oct 2005 20:35:51 +0200</pubDate>
    <guid isPermaLink="false">http://sigkill.dk/blog/archives/97-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license>
</item>
<item>
    <title>Procedural closure &lt;3</title>
    <link>http://sigkill.dk/blog/archives/88-Procedural-closure-3.html</link>
            <category>Lisp</category>
    
    <comments>http://sigkill.dk/blog/archives/88-Procedural-closure-3.html#comments</comments>
    <wfw:comment>http://sigkill.dk/blog/wfwcomment.php?cid=88</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://sigkill.dk/blog/rss.php?version=2.0&amp;type=comments&amp;cid=88</wfw:commentRss>
    

    <author>nospam@example.com (Troels Henriksen)</author>
    <content:encoded>
    &lt;p&gt;
Det er frygteligt lang tid siden jeg har skrevet noget om Lisp her på siden. Det må jeg råde bod på. Til en forandring vil dette indlæg ikke omhandle Common Lisp, men derimod &lt;a href=&quot;http://www.swiss.ai.mit.edu/projects/scheme/&quot;&gt;Scheme&lt;/a&gt;, en mere elegant men også mindre featurefuld dialekt af Lisp. I dette indlæg vil jeg forfejle et forsøg på at give udtryk for hvor seje first-order procedures er, og hvor mange interessante ting man kan bruge dem til. Eksemplet i dette indlæg er taget fra den herlige bog &lt;a href=&quot;http://mitpress.mit.edu/sicp/&quot;&gt;Structure and Interpretation of Computer Programs&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Nuvel, først lidt trivia: Normalt siges det at den grundlæggende datastruktur i Lisp er den enkelt-linkede liste (Lisp står som bekendt(?) for LISt Processing). Dette er så ikke helt sandt, den grundlæggende datastruktur er derimod &lt;em&gt;cons-cellen&lt;/em&gt;, der har fået sig navn fra den funktion man bruger til at oprette den (&lt;em&gt;cons&lt;/em&gt;). En cons-celle er grundlæggende bare et par - det er en datastruktur, med to &quot;pladser&quot;, hvor man kan gemme værdier. De to pladser kaldes hhv. for &lt;em&gt;car&lt;/em&gt; og &lt;em&gt;cdr&lt;/em&gt;, igen navngivet efter de funktioner man bruger til at tilgå dem (&lt;em&gt;car&lt;/em&gt; og &lt;em&gt;cdr&lt;/em&gt;, hvis I ikke selv skulle have udledt det - navnene er et levn fra den IBM 704-maskine som Lisp oprindeligt kørte på, og står for hhv. &lt;em&gt;contents of address register&lt;/em&gt; og &lt;em&gt;contents of decrement register&lt;/em&gt; - disse navne har ikke længere nogen relevans). Hvis man vil oprette en Lisp-liste, gemme man en vilkårlig værdi i en cons-celles car, og endnu en cons-celle i cdr. I den næste cons-celle gemmer man så endnu en vilkårlig værdi i car, og endnu en cons-celle i cdr, og sådan fortsætter det, til man afslutter listen ved at placere værdien &lt;em&gt;nil&lt;/em&gt; i en cons-celles cdr (nil er også kendt som () - den tomme liste - og svarer lidt til en null pointer). Resultatet er at man har en liste, der indeholder de værdier som man har gemt i de forskellige cons-cellers car.
&lt;/p&gt;

&lt;p&gt;
Dette system er noget af det mest grundlæggende i Lisp, men det kan alligevel meget simpelt re-implementeres af en programmør, ved at bruge first-order funktioner. Således defineres funktionerne &lt;em&gt;cons&lt;/em&gt;, &lt;em&gt;car&lt;/em&gt; og &lt;em&gt;cdr&lt;/em&gt;:
&lt;/p&gt;

&lt;pre&gt;
(define (cons x y)
  (lambda (z)
    (cond ((= z 0) x)
          ((= z 1) y)
          (else (error &quot;Error in cons cell&quot;)))))

(define (car cell)
  (cell 0))

(define (cdr cell)
  (cell 1))
&lt;/pre&gt;

&lt;p&gt;
Idéen her er at funktionen &lt;em&gt;cons&lt;/em&gt; returnerer en funktion, der når den bliver kaldt med argumentet 0 returnerer car, og når den bliver kaldt med argumentet 1, returnerer cdr. &lt;em&gt;car&lt;/em&gt; og &lt;em&gt;cdr&lt;/em&gt; er så implementeret ved at kalde en funktion af den type som &lt;em&gt;cons&lt;/em&gt; returnerer med det passende parameter. Ved at neste kald af &lt;em&gt;cons&lt;/em&gt; (&lt;em&gt;(cons 1 (cons 2 (cons 3 nil)))&lt;/em&gt;) kan man så oprette lister, der kan tilgås via &lt;em&gt;car&lt;/em&gt; og &lt;em&gt;cdr&lt;/em&gt;.
&lt;/p&gt;

&lt;p&gt;
At implementere en så low-level datastruktur som en cons-celle via funktioner er naturligvis ikke nyttigt, for ydelsen vil blive ret ringe. Men det viser hvor fleksible first-order funktioner er, og hvilken styrke closure (her defineret som datastrukturer der kan indeholde datastrukturer af samme type, for at lave mere komplekse strukturer) er for et sprog.
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Fri, 12 Aug 2005 12:05:53 +0200</pubDate>
    <guid isPermaLink="false">http://sigkill.dk/blog/archives/88-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license>
</item>
<item>
    <title>Stumpwm</title>
    <link>http://sigkill.dk/blog/archives/73-Stumpwm.html</link>
            <category>Lisp</category>
    
    <comments>http://sigkill.dk/blog/archives/73-Stumpwm.html#comments</comments>
    <wfw:comment>http://sigkill.dk/blog/wfwcomment.php?cid=73</wfw:comment>

    <slash:comments>2</slash:comments>
    <wfw:commentRss>http://sigkill.dk/blog/rss.php?version=2.0&amp;type=comments&amp;cid=73</wfw:commentRss>
    

    <author>nospam@example.com (Troels Henriksen)</author>
    <content:encoded>
    &lt;p&gt;
Jeg har i snart et år brugt den fænomenale window manager &lt;a href=&quot;http://www.nongnu.org/ratpoison&quot;&gt;ratpoison&lt;/a&gt; - en keyboardcentrisk window manager, til folk der ikke kan lide &lt;a href=&quot;http://eeshop.unl.edu/rsi.html&quot;&gt;gnaveren&lt;/a&gt;. For et par dage siden faldt jeg over &lt;a href=&quot;http://www.nongnu.org/stumpwm&quot;&gt;Stumpwm&lt;/a&gt;, en window manager bygget på samme principper som ratpoison, men skrevet i &lt;a href=&quot;http://www.lisp.org/alu/home&quot;&gt;Common Lisp&lt;/a&gt;. Jeg ledte i forvejen efter et interessant Lisp-projekt, som jeg kunne få noget erfaring med sproget, så jeg &lt;a href=&quot;http://www.nongnu.org/stumpwm/download.html&quot;&gt;hentede Stumpwm fra CVS&lt;/a&gt;, og prøvede at få det til at køre. Det var... ikke trivielt. Der var også en del bugs i programmet, som jeg så efterhånden har fået fikset. Jeg har uploadet min kildekode &lt;a href=&quot;http://www.sigkill.dk/code/stumpwm-0.0.3-athas.tar.gz&quot;&gt;her&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Med mindre man kender en del til Lisp, er chancen for at man kan få det til at køre på egen hånd yderst minimal. Jeg præsenterer derfor: &lt;em&gt;Athas&#039; ultimative guide til opsætning af Stumpwm under GNU/Linux&lt;/em&gt;:
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Installér en implementation af Common Lisp. Personligt kører jeg Stumpwm under &lt;a href=&quot;http://www.sbcl.org/&quot;&gt;Steel Bank Common Lisp&lt;/a&gt;. Under &lt;a href=&quot;http://www.gentoo.org&quot;&gt;Gentoo&lt;/a&gt; kan det installeres med kommandoen &lt;strong&gt;emerge sbcl&lt;/strong&gt;, under &lt;a href=&quot;http://www.debian.org&quot;&gt;Debian&lt;/a&gt; med &lt;strong&gt;apt-get install sbcl&lt;/strong&gt;.&lt;/li&gt;

&lt;li&gt;Installér &lt;a href=&quot;http://common-lisp.net/project/slime/&quot;&gt;SLIME&lt;/a&gt;. Hvis man er blandt de heldige, kan man skrive &lt;strong&gt;emerge slime&lt;/strong&gt;, mens Debian-brugere kan hente deb-pakker &lt;a href=&quot;http://commonwerx.org/software/contrib/slime/deb/&quot;&gt;her&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Installér &lt;a href=&quot;http://www.cliki.net/CLX&quot;&gt;CLX&lt;/a&gt;. Gentoo-brugere kan skrive &lt;strong&gt;emerge cl-clx&lt;/strong&gt;, mens Debian-brugere må lade sig nøjes med &lt;strong&gt;apt-get install cl-clx-sbcl&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Nu bliver det farligt. &lt;a href=&quot;http://clocc.sourceforge.net/&quot;&gt;CLOCC&lt;/a&gt; skal installeres. Gentoo: &lt;strong&gt;emerge cl-port&lt;/strong&gt;. Ifølge &lt;a href=&quot;http://www.cliki.net/Debian&quot;&gt;denne side&lt;/a&gt; burde Debian-brugere kunne installere pakken &lt;em&gt;clocc-port&lt;/em&gt;, men den var i hvert fald ikke tilgængelig på det Sarge-system jeg har til rådighed.&lt;/li&gt;

&lt;li&gt;Download Stumpwm, og udpak kildekoden et sted du kan huske.&lt;/li&gt;
&lt;li&gt;Opret en fil ved navn &lt;em&gt;.stumpwm&lt;/em&gt; i dit homedir (det er vigtigt at du ikke kalder den &lt;em&gt;.stumpwmrc&lt;/em&gt;, selvom det måske ville være mere logisk), og giv den følgende indhold:
&lt;pre&gt;
(require &#039;swank)
(swank:create-swank-server 4005 :spawn)

(require &#039;clx)
(require &#039;port)

(load &quot;/home/athas/code/stumpwm/package.lisp&quot;)
(load &quot;/home/athas/code/stumpwm/primitives.lisp&quot;)
(load &quot;/home/athas/code/stumpwm/user.lisp&quot;)
(load &quot;/home/athas/code/stumpwm/stumpwm.lisp&quot;)
(load &quot;/home/athas/code/stumpwm/core.lisp&quot;)
(load &quot;/home/athas/code/stumpwm/input.lisp&quot;)

;; start stumpwm
(stumpwm:stumpwm)
&lt;/pre&gt;
Ret i filen, så stierne til Stumpwm-filerne passer til din installation.&lt;/li&gt;
&lt;li&gt;Start nu X med denne kommando: &lt;strong&gt;startx `which xterm` -- :1&lt;/strong&gt; - dette starter X på et sekundært display, der kan tilgås via CTRL-ALT-F8, i modsætning til det normale display, der tilgås via CTRL-ALT-F7. Så kan du køre både Stumpwm og din sædvanlige Window-manager, i hver sin X-session. X vil starte op uden andet end en xterm. Skriv &lt;strong&gt;sbcl --load ~/.stumpwm&lt;/strong&gt; i xterm&#039;en, og vent. Hvis der opstår fejl, så fiks dem. Efter et stykke tid vil Stumpwm starte (det skal lige compiles, hvilket sker automatisk), og kunne betjenes på nogenlunde samme måde som ratpoison.&lt;/li&gt;

&lt;li&gt;Vær lykkelig.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
Jeg har naturligvis kun checket disse trin på et Gentoo-system, så der er ingen garanti for at det virker på Debian.
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Mon, 06 Jun 2005 13:50:41 +0200</pubDate>
    <guid isPermaLink="false">http://sigkill.dk/blog/archives/73-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license>
</item>
<item>
    <title>Emacs styrer</title>
    <link>http://sigkill.dk/blog/archives/68-Emacs-styrer.html</link>
            <category>Lisp</category>
    
    <comments>http://sigkill.dk/blog/archives/68-Emacs-styrer.html#comments</comments>
    <wfw:comment>http://sigkill.dk/blog/wfwcomment.php?cid=68</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://sigkill.dk/blog/rss.php?version=2.0&amp;type=comments&amp;cid=68</wfw:commentRss>
    

    <author>nospam@example.com (Troels Henriksen)</author>
    <content:encoded>
    &lt;p&gt;
I går blev jeg mindet om hvorfor jeg bruger &lt;a href=&quot;http://www.gnu.org/software/emacs&quot;&gt;Emacs&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
For tiden bruger jeg min fritid på at studere Common Lisp, et ret interessant programmeringssprog, og jeg skriver naturligvis koden i det program jeg også bruger til alt andet: GNU Emacs. GNU Emacs er også selv skrevet i Lisp (dog Emacs Lisp, en noget mere primitiv Lisp-dialekt), og har en række funktioner der gør det hurtigt og let at slå op i dokumentationen for en given Emacs Lisp-funktion. Jeg kan naturligvis forsøge at slå Common Lisp-funktionerne op i Emacs Lisp-dokumentationen, nu og da vil jeg få korrekt information (især for grundlæggende funktioner som &lt;em&gt;list&lt;/em&gt;, &lt;em&gt;append&lt;/em&gt; eller &lt;em&gt;cons&lt;/em&gt;), andre gange vil jeg få næsten-korrekt information (hvis funktionen findes i Emacs&#039; Common Lisp-kompatibilitetssystem), men i langt de fleste tilfælde vil jeg ikke få noget ud af det. Common Lisp har et opslagsværk kaldet &lt;a href=&quot;http://www.lisp.org/HyperSpec/FrontMatter/index.html&quot;&gt;HyperSpec&lt;/a&gt;, en slags Lisp-&lt;a href=&quot;http://msdn.microsoft.com&quot;&gt;MSDN&lt;/a&gt;, og jeg opdagede at Emacs havde en funktion til at slå Common Lisp-symboler op på HyperSpec-siden: &lt;em&gt;hyperspec-lookup&lt;/em&gt;. Jeg rebindede så &lt;strong&gt;C-h f&lt;/strong&gt; og &lt;strong&gt;C-h v&lt;/strong&gt; til, når jeg redigerer Common Lisp-kode, at køre funktionen &lt;em&gt;hyperspec-lookup&lt;/em&gt; i stedet for hhv. &lt;em&gt;describe-function&lt;/em&gt; og &lt;em&gt;describe-variable&lt;/em&gt;. Derefter ændrede jeg værdien af variablen &lt;em&gt;browse-url-browser-function&lt;/em&gt; til &lt;em&gt;w3m-browse-url&lt;/em&gt;, så &lt;em&gt;hyperspec-lookup&lt;/em&gt; bruger Emacs&#039; tekstbaserede w3m-browser til at foretage lookups. Så nu har jeg også let tilgængelig dokumentation for Common Lisp-symboler. Senere vil jeg nok erstatte det rene kald til &lt;em&gt;hyperspec-lookup&lt;/em&gt; med en funktion der også checker dokumentationen for de funktioner jeg selv har skrevet, ligesom det virker med Emacs Lisp.
&lt;/p&gt;

&lt;p&gt;
Det er rart at bruge en editor med et indbygget programmeringssprog. Jeg går aldrig tilbage til almindelige statiske programmer. Min .emacs kan hentes &lt;a href=&quot;http://sigkill.dk/athas/conf/dot.emacs&quot;&gt;her&lt;/a&gt;.
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Fri, 13 May 2005 14:42:04 +0200</pubDate>
    <guid isPermaLink="false">http://sigkill.dk/blog/archives/68-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license>
</item>
<item>
    <title>Common Lisp og standarder</title>
    <link>http://sigkill.dk/blog/archives/66-Common-Lisp-og-standarder.html</link>
            <category>Lisp</category>
    
    <comments>http://sigkill.dk/blog/archives/66-Common-Lisp-og-standarder.html#comments</comments>
    <wfw:comment>http://sigkill.dk/blog/wfwcomment.php?cid=66</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://sigkill.dk/blog/rss.php?version=2.0&amp;type=comments&amp;cid=66</wfw:commentRss>
    

    <author>nospam@example.com (Troels Henriksen)</author>
    <content:encoded>
    &lt;p&gt;
Det siges at man først værdsætter noget, når man har mistet det. Det har jeg måttet sande i de seneste par dage, hvor jeg har forsøgt at lære mig Common Lisp. I sprog som C og C++ er jeg vant til at jeg kan tage den kode jeg har skrevet til &lt;a href=&quot;http://gcc.gnu.org&quot;&gt;GNU GCC&lt;/a&gt;, og kompilere den med andre compilere, som f.eks. Borlands eller Microsofts. &lt;em&gt;Hvis&lt;/em&gt; der er problemer, så er det oftest fordi jeg har sjusket, eller fordi jeg udnytter implementations-specifikke detaljer. Jeg kan f.eks. regne med at &lt;strong&gt;scanf&lt;/strong&gt; gør det samme under alle compilerne. Alene tanken om at en implementation skulle kunne implementere &lt;strong&gt;scanf&lt;/strong&gt; forkert virker grotesk. Det siges ofte at C og C++&#039;s standarder er svage, og ikke efterfulgt særligt godt, men graden af inkonsistens i det miljø er det rene vand i forhold til hvordan det er med Common Lisp.
&lt;/p&gt;

&lt;p&gt;
Her er et eksempel: Common Lisp har en funktion ved navn &lt;strong&gt;yes-or-no-p&lt;/strong&gt; (ja, Common Lisp tillader bindestreger i identifiers, det er ret sejt). Det er en funktion der tager ét parameter, en tekststreng, og som returnerer enten &lt;strong&gt;t&lt;/strong&gt; eller &lt;strong&gt;nil&lt;/strong&gt; - Lisp&#039;s udgaver af &lt;strong&gt;true&lt;/strong&gt; og &lt;strong&gt;false&lt;/strong&gt;. Funktionen kunne ikke være meget mere simpel, den skriver paremetret på terminalen, tager som input enten &quot;yes&quot; eller &quot;no,&quot; og returnerer en passende værdi.

&lt;/p&gt;

&lt;p&gt;
Men så simpelt skal det naturligvis ikke være.
&lt;/p&gt;

&lt;p&gt;
For at gøre det klart for brugeren at vedkommende skal skrive enten &quot;yes&quot; eller &quot;no&quot; kan det være hensigtsmæssigt at skrive noget i stil med &quot;(yes/no)&quot; i prompten. Altså:
&lt;/p&gt;

&lt;pre&gt;
(yes-or-no-p &quot;Is this correct: [yes/no] &quot;)
&lt;/pre&gt;

&lt;p&gt;
Under &lt;a href=&quot;http://clisp.cons.org/&quot;&gt;CLISP&lt;/a&gt; (min nuværende Common Lisp-implementation) giver det følgende output:

&lt;/p&gt;

&lt;pre&gt;
Is this correct: [yes/no]  (yes/no)
&lt;/pre&gt;

&lt;p&gt;
&lt;em&gt;What the hell?&lt;/em&gt; Okay, så funktionen sætter altså selv &quot;(yes/no)&quot; på. Det er da meget fint... hvis det ikke var fordi der ingen regel er for hvad der helt præcist skal sættes på - det varierer fra implementation til implementation. Man kan ikke være sikker på hvad der helt præcist bliver udskrevet, eller om der bliver udskrevet noget overhovedet. Hvad ville der ske hvis MSVC++ pludselig begyndte at skrive &quot;input integer&quot; i &lt;strong&gt;scanf&lt;/strong&gt;-kald? Den slags generer mig grusomt.
&lt;/p&gt;

&lt;p&gt;
Dette er dog kun en mindre detalje (okay, flere detaljer, der er også nogle andre problemer jeg er i gang med at undersøge). Jeg er allerede blevet meget fascineret af Common Lisp, og det har så absolut en chance for at slå C++ som mit favoritsprog (muligvis fordi det er det eneste der er mere kryptisk...). Jeg råder alle til at prøve kræfter med Common Lisp, eventuelt gennem &lt;a href=&quot;http://common-lisp.net/project/slime/&quot;&gt;SLIME&lt;/a&gt;, der gør GNU Emacs til et top-notch Common Lisp udviklingsmiljø.

&lt;/p&gt; 
    </content:encoded>

    <pubDate>Thu, 05 May 2005 20:18:44 +0200</pubDate>
    <guid isPermaLink="false">http://sigkill.dk/blog/archives/66-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license>
</item>
<item>
    <title>Practical Common Lisp</title>
    <link>http://sigkill.dk/blog/archives/64-Practical-Common-Lisp.html</link>
            <category>Lisp</category>
    
    <comments>http://sigkill.dk/blog/archives/64-Practical-Common-Lisp.html#comments</comments>
    <wfw:comment>http://sigkill.dk/blog/wfwcomment.php?cid=64</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://sigkill.dk/blog/rss.php?version=2.0&amp;type=comments&amp;cid=64</wfw:commentRss>
    

    <author>nospam@example.com (Troels Henriksen)</author>
    <content:encoded>
    &lt;p&gt;
Håhå, Lisp er hverken almindeligt eller praktisk, håhå. Alligevel har Peter Seibel skrevet bogen Practical Common Lisp, og ikke bare det, han har også gjort den &lt;a href=&quot;http://www.gigamonkeys.com/book/&quot;&gt;frit tilgængelig&lt;/a&gt; online! Derfor er jeg nu gået i gang med at lære Common Lisp... jeg har haft lyst til at lære det i et stykke tid, men jeg har ikke rigtigt haft tid. Bogen er også blevet &lt;a href=&quot;http://developers.slashdot.org/developers/05/04/28/1936206.shtml?tid=156&amp;amp;tid=6&quot;&gt;anmeldt på Slashdot&lt;/a&gt;, og der burde være nok Lisp-jokes for alle.
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sat, 30 Apr 2005 18:31:31 +0200</pubDate>
    <guid isPermaLink="false">http://sigkill.dk/blog/archives/64-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license>
</item>

</channel>
</rss>