Jetzt wird gelispelt.
Erste Schritte mit (X)Emacs (Teil 2)
Aufgelistet
Den gleichen Effekt können wir auch mit folgender, etwas ausführlicherer Darstellung erreichen:
(global-set-key [(control x) (control c)] nil)
Der Ausdruck in der Mitte ist wieder unsere Tastenkombination. Allerdings steht das Ganze jetzt in eckigen Klammern und darin die einzelnen Umschreibungen für die Tasten in runden Klammern.
Fangen wir mit den Ausdrücken in den runden Klammern an. Diesmal ist der erste Ausdruck beispielsweise in (control x) kein Befehl. Vielmehr handelt es sich um einen besonderen Datentyp, der einzelne Werte oder Variablen zusammenfasst. Dieser Datentyp heißt list, das heißt Liste. Hier ein paar Beispiele für Listen: * Liste mit Zahlen: ( 1 2 3) * Liste mit einer Zahl und einer Zeichenkette: ( 1 "abcd") * Liste mit Variable und einer Liste mit Variablen: (a (b c)) * leere Liste: ()
Um auf die einzelnen Elemente einer Liste zugreifen zu können, bietet XEmacs einige nützliche Befehle: * Der Befehl car liefert das erste Element einer Liste: (car '(a b c )) gibt als Ergebnis a zurück. * cdr liefert alles außer dem ersten Element zurück: (cdr '(a b c)) gibt als Ergebnis (b c) zurück. * Mit list können Sie eine neue Liste aus dem ihm übergebenen Werten oder Variablen erzeugen: (list 'a "abc" 7) gibt als Ergebnis eine neue Liste (a "abc" 7) zurück, (list '(a b c) d) dagegen ((a b c) d). * cons fügt ein Argument in einer schon existierenden Liste vorne an: (cons 'a (b c)) hat (a b c) als Ergebnis, (cons '( a b) '(c d)) gibt (( a b) c d) zurück. * append fügt Listen so zusammen: (append '(a b c) '(d e f)) wird zu (a b c d e f). * Der Befehl reverse kehrt die Reihenfolge der Elemente um: (reverse '(1 2 3)) führt zu (3 2 1), (reverse '( ( 1 2) 3 4) aber zu (4 3 (1 2)). * Mit dem schon bekannten Befehl setq können wir einer Variablen auch eine Liste zuweisen: (setq a '(c d)).
Die Liste (control x) enthält also zwei Variablen, die für die [Strg]- und die [x]-Taste stehen. Für die gewünschte Tastenkombination brauchen wir aber noch die andere Verknüpfung mit der Kombination (control c). Man könnte daran denken, dem Befehl global-set-key die Liste ((control x) (control c)) zu übergeben. Dieser verlangt jedoch einen anderen Datentyp, Vektor genannt. Die Elemente eines Vektors werden in eckigen Klammern geschrieben. Elemente können eines beliebigen Datentyps sein. Vorteil eines Vektors gegenüber einer Liste ist, dass die einzelnen Elemente des Vektors direkt angesprochen werden können, anstatt sie mühsam mit car und cdr zu ermitteln.Mit (aref v i) erhalten Sie das i-te Element des Vektors v, wobei die Zählung der Elemente bei 0 beginnt. Beispiel: (aref [a b c] 0) gibt a als Ergebnis zurück. (aset v i Element) setzt das i-te Element des Vektors v auf Element. Beispiel:
(setq v '(vector 1 2 3)) (aset v 0 0)
In der ersten Zeile erzeugen wir mit dem Befehl vector erst einen neuen Vektor und weisen ihn der Variablen v zu. Danach ersetzen wir das erste Element von v (die "1") durch die Zahl "0". Mit (vectorp v) können wir überprüfen, ob es sich bei v wirklich um einen Vektor handelt: Wenn dies zutrifft, wird t zurückgeliefert.
Mit (length v) erhalten Sie schließlich die Länge des Vektors v. length gibt die Länge von Listen oder Zeichenketten zurück.
Alles fließt
Um den Ablauf eines Programms zu steuern, können in Lisp zwei Befehle verwendet werden. Den ersten, if, kennt man aus anderen Programmiersprachen:
(if (>= Alter 16) (setq Zigaretten t) ; ja, Alter >= 16 (setq Zigaretten nil) ; nein, Alter < 16 )
Die erste Klammer nach dem Befehl if erhält die zu überprüfende Bedingung. Ist diese wahr, das heißt nicht nil, wird der zweite Ausdruck ausgewertet, sonst der letzte. In unserem Beispiel wird die Variable Zigarette auf t gesetzt, wenn die Variable Alter größer als oder gleich 16 ist, sonst wird sie auf nil gesetzt.
Nach der zu prüfenden Bedingung darf für die Anweisungen jeweils nur ein Ausdruck verwendet werden. Damit Sie auch komplexere Ausdrücke verwenden können, können Sie solche mit dem Befehl progn vorher auswerten lassen. (Der Befehl message im Beispiel gibt eine Zeichenkette aus.)
(if (>= Alter 16)
(progn
(setq Zigaretten t)
(setq Bier t)
(message "Du darfst Bier und Zigaretten kaufen.")
)
(progn
(setq Zigaretten nil)
(setq Bier nil)
(message "Du darfst weder Bier noch Zigaretten kaufen.")
)
)
Wenn Sie viele Bedingungen überprüfen müssen, wird Ihr Programm durch den Befehl cond übersichtlicher als mit if:
(cond
((< Alter 7) (setq geschaeftsfaehig nil)
(and (>= Alter 7) (< Alter 18)) (setq geschaeftsfaehig beschraenkt)
(>= Alter 18) (setq geschaeftsfaehig t)
))
Am Anfang jeder Zeile nach dem Befehl cond steht die Bedingung, die geprüft werden soll. Ist diese wahr, so werden die danach stehenden beliebig vielen Ausdrücke ausgeführt. Ist eine Bedingung unwahr, geht cond direkt zur nächsten Bedingung über und überprüft diese. Sind alle Bedingungen unwahr, liefert cond nil zurück. In der zweiten Bedingung sehen Sie übrigens ein Anwendungsbeispiel für den logischen Operator and.



