Die hier vorgestellte Funktion
(nothing-happens ...) ist in der praktischen
Arbeit eigentlich zu nichts zu gebrauchen: Sie gibt das Argument unverändert
zurück, und Seiteneffekte hat sie auch nicht. Was macht sie also so interessant,
dass ich sie hier veröffentliche? Nun, sie nimmt (wenn es sich nicht um ein
Atom handelt), ihr Argument vollständig auseinander und setzt es auch wieder
sauber zusammen. Das bedeutet, dass jedes in einer noch so verschachtelten
Liste vorkommende Atom zu einem bestimmten Zeitpunkt einmal direkt greifbar
ist.
nothing-happens ist also ein Prototyp für Funktionen, die Listen
durchsuchen und/oder etwas darin manipulieren sollen.
Wie kann so eine Funktion arbeiten? Für das Argument kommen insgesamt vier Fälle
in Frage:
- Das Argument ist nil
- Das Argument ist ein Atom
- Das Argument ist ein dotted pair
- Das Argument ist eine Liste
Im ersten und zweiten Fall wird das Argument unverändert zurückgegeben, fertig.
Im dritten Fall wird der
car des Paares getrennt vom
cdr verarbeitet
und dann mit
cons wieder zusammengesetzt. Die Verarbeitung erfolgt auf
rekursivem Wege. Bei einem dotted pair können wir aber auf die Anwendung der
Rekursion auf den
cdr verzichten, da es sich ja um ein Atom handeln muss.
Im vierten Fall trennen wir ebenso das erste Element vom Listenrest, es müssen
aber beide Teile in die Rekursion geschickt werden, da wir nichts über die Inhalte
wissen. Mit
(append ...) werden beide Teile wieder zusammengesetzt. Die
Rekursion geht so lange weiter, bis irgendwann Atome vorgefunden werden. Die
Reihenfolge der vier Fälle sollte nicht verändert werden! Würde man z.B. den
ersten und den zweiten Test vertauschen, würden leere Listen (
nil!) als
Atom behandelt. Ein Vertauschen des dritten und vierten Tests würde zu evtl.
auftretenden Abbrüchen durch Fehler führen (s. Kapitel über dotted pairs).
Der Code von
(nothing-happens ...) sieht so aus:
(defun nothing-happens(any-data / )
(cond
( (null any-data)nil)
( (atom any-data)any-data)
( (and
(=(type any-data)'LIST)
(cdr any-data)
(atom(cdr any-data))
)
(cons
(nothing-happens(car any-data))
(cdr any-data)
)
)
('T
(append
(list(nothing-happens(car any-data)))
(nothing-happens(cdr any-data))
)
)
)
)
Der Code kann etwas gekürzt werden, wenn man auf die im Kapitel 'dotted pairs'
vorgestellte Testfunktion
dotted? zurückgreift:
(defun nothing-happens(any-data / )
(cond
( (null any-data)nil)
( (atom any-data)any-data)
( (dotted? any-data)
(cons
(nothing-happens(car any-data))
(cdr any-data)
)
)
('T
(append
(list(nothing-happens(car any-data)))
(nothing-happens(cdr any-data))
)
)
)
)
Da
nothing-happens jedes Argument völlig unverändert zurückgibt, kann auf
Beispiele für die Anwendung verzichtet werden.