Folk spør av og til hvordan jeg har tid til å være så aktiv på nettet, og svaret på det er at det har jeg jo ikke. Særlig ikke i det siste, med ny jobb og ny kjæreste og ny leilighet og … vel, dere skjønner. Jeg har skrevet litt nylig om IQ i Dagens Næringsliv og vært på radio etpar ganger og noe greier … men blogging er det ikke blitt mye av.
I skrivende stund jobber jeg med nyeste utgave av Spartacus forlags Swahili-Norsk ordbok. Første opplag kom i 1997, og er utsolgt. Da bruke forfatteren en Filemaker-database som jeg nennsomt plukket dataene ut av og oversatte til LaTeX. Dengang brukte jeg Perl. Det vil jeg ikke lenger. Denne gangen, 2. utgave, er det fortsatt LaTeX (Jeg synes ConTeXt er vakkert, men ikke veldig godt dokumentert og et bevegelig mål uansett).
Men denne gangen bruker jeg et ordentlig programmeringsspråk. Common Lisp, og implementasjonen er Clozure CL for MacOS. (Onde tunger vil ha det til at det er flere Lisp-omgivelser enn programmer skrevet i Lisp. Ikke hør på dem.)
Her er koden så langt. Vakkert. Jeg vet hvordan det ville sett ut i Perl.
(require 'split-sequence)
;(import 'split-sequence:split-sequence :cl-user)
(load "string-replace")
(require 'cl-ppcre)
(import 'cl-ppcre:regex-replace :cl-user)
(defvar *infile* "001.csv")
(import 'csv-parser::do-csv-file 'cl-user)
(setq csv-parser::*field-separator* #\,)
(defun collate (a b)
(let ((split-a (split-sequence:split-sequence (code-char 29) a))
(split-b (split-sequence:split-sequence (code-char 29) b)))
(mapcar
#'(lambda (a b)
(format nil "~A ~A "
(tex-format a)
(tex-format b)))
split-a split-b)))
(defun tex-format (s)
(and
(stringp s)
(> (length s) 2)
(let*
((s
(string-replace s "#I" "\\emph{"))
(s
(string-replace s "#@" "} ")))
s)))
(defun swahili ()
(let ((*swahili* nil))
(princ (format t "~&~A~A~&" "Kjører swahili" "..."))
(with-open-file
(out "swahili.tex"
:direction :output
:if-does-not-exist :create
:if-exists :overwrite)
(do-csv-file
((line num-fields) *infile*)
(let
((keyword (nth 0 line))
(wordclass (nth 1 line))
(explanation (nth 2 line))
(examples (nth 3 line))
(eng-examples (nth 5 line))
(eng-phonetics (nth 4 line))
)
(progn
(format out "~&\\a\{~A\} ~A ~A ~A ~A ~&"
keyword
wordclass
(collate
explanation
examples)
eng-examples
eng-phonetics
)))))))
(swahili)
(quit)
Med destructuring-bind kan du si:
(destructuring-bind (keyword wordclass explanation examples eng-phonetics eng-examples)
line
Den var ikke dum! Vært med i standarden siden 1989 også, ser jeg …
Vil du ha ytterligere uproduktiv nitpicking av koden?
Tar imot alt jeg kan få, jeg,
Princ-kallet i uttrykket (princ (format t "~&~A~A~&" "Kjører swahili" "…"))
gir ikke helt mening. Det er bare når du gjør (format nil … …) at resultatet fra format brukes, ellers kalles format for sideeffekten — det at noe bli skrevet ut.
(format t "~&~A~A~&" "Kjører swahili" "…") returnerer nil, så princ får nil som argument og skriver det ut. Dermed får du som output:
Kjører swahili…
NIL
Progn brukes for å kjede sammen flere uttrykk der det omkringliggende uttrykket forventer bare ett uttrykk. Du trenger ikke noe progn rundt et enkelt kall til format, slik du har i funksjonen swahili:
(progn
(format out "~&\a{~A} ~A ~A ~A ~A ~&"
Jeg vet, det var flere uttrykk der, også fjernet jeg dem men ikke progn …
Braces er ikke magiske om de står alene i format-uttrykk, så du trenger ikke backslash foran dem.