Bitte nicht erschrecken: Ich will hier nichts kaputtmachen, und
eine Anleitung zu Virenbasteln in AutoLisp gibt's hier sicherlich
nicht! Mit 'destruktiv' bezeichnet man einfach Funktionen, die
Daten im Speicher verändern - also Funktionen mit Nebeneffekt. Es
geht hier um eine Anleitung, wie man sich zu vorhandenen Funktionen
noch destruktive Parallelversionen schaffen kann. Diese sind dann
zwar nicht sonderlich für Verkettungen geeignet, können einem aber
einfach eine Menge Tipparbeit abnehmen.
Anfänger vergessen ja so ab und zu, dass Funktionen wie
(append ...) reine Effektfunktionen sind (ach ja, wer das Kapitel
über Effekte und Seiteneffekte noch nicht gelesen hat: Das sollte
jetzt erstmal nachgeholt werden!).
(append liste1 liste2) ist nur
dann sinnvoll und nützlich, wenn die Rückgabe aufgefangen und
weiterverarbeitet wird. Meist rettet sich der Anfänger damit, dass
er das Ergebnis mit
(setq ...) einer Variablen zuweist.
Manchmal ist ja eine solche Zuweisung durchaus sinnvoll. Schliesslich
muss ja nicht in einer Funktion, die 23 Mal die Wurzel aus pi Viertel
braucht, auch 23 Mal berechnet werden, wieviel das denn nun ist. Also
fährt man besser, wenn man einmal
(setq wupivi(sqrt(/ pi 4)))
berechnet und dann nur noch die Variable benutzt. Wenn man in einer ähnlichen
Situation nun zwei Listen zusammenfügen und das Ganze dann speichern
will, muss man
(setq liste(append liste andere-liste))
hinschreiben. Und die Zuweisung ist das, was Anfänger eben mal
vergessen. Wie wäre es denn, wenn wir die Sache andersherum angehen:
Eine Funktion, die das in einem Rutsch erledigt? Damit wir sie von dem
normalen
append unterscheiden können, nenne ich sie
append!:
(append! liste andere-liste)
Leider geht das nicht ganz so mit unserem Destruktiv-
append! Da das
Argument
liste ja evaluiert wird, kann unser
append! die Zuweisung nicht
vornehmen - das Symbol
liste kommt dort nicht an. Aber die folgende
Version funktioniert:
(append! 'liste andere-liste)
In der Funktion kann mit
(eval ...) die erste Liste angesprochen werden,
die zweite wird mit
append verbunden, und das Ganze wird an das Symbol
liste gebunden. So sieht die Funktionsdefinition aus:
(defun append!(symbol1 liste2 / )
(set symbol1(append(eval symbol1)liste2))
)