[ << Scheme-Tutorium ] | [Top][Contents][Index] | [ Schnittstellen für Programmierer >> ] |
[ < Einfache Scheme-Datentypen ] | [ Up : Einleitung in Scheme ] | [ Berechnungen in Scheme > ] |
1.1.4 Zusammengesetzte Scheme-Datentypen
Es gibt auch zusammengesetzte Datentypen in Scheme. Die Datentypen, die in LilyPond häufig benutzt werden, beinhalten Paare, Listen, assoziative Listen und Hash-Tabellen.
Paare (pair)
Der wichtigste zusammengesetzte Datentyp in Scheme ist ein Paar (pair
).
Wie aus dem Namen schon hervorgeht, besteht ein Paar aus zwei zusammengeschweißten
Werten. Die Prozedur um ein Paar zu erstellen ist cons
.
guile> (cons 4 5) (4 . 5) guile>
Das Paar wird dargestellt als zwei Elemente, von Klammern umgeben
und durch Leerzeichen und einen Punkt (.
) getrennt. Der Punkt ist
kein Dezimalpunkt, sondern markiert die Gruppe als Paar.
Paare können auch wörtlich eingegeben werden, indem man ihnen voraus ein
einfaches Anführungszeichen ('
setzt.
guile> '(4 . 5) (4 . 5) guile>
Beide Elemente eines Paares können beliebige gültige Scheme-Werte sein:
guile> (cons #t #f) (#t . #f) guile> '("blah-blah" . 3.1415926535) ("blah-blah" . 3.1415926535) guile>
Das erste Element eines Paares kann mit der Prozedur car
,
das zweite mit der Prozedur cdr
angesprochen werden.
guile> (define mypair (cons 123 "hello there") ... ) guile> (car mypair) 123 guile> (cdr mypair) "hello there" guile>
Achtung: cdr
wird ausgesprochen wie "kudd-err", nach Sussman und
Abelson, siehe
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-14.html#footnote_Temp_133
Listen (list)
Ein sehr häufiger Datentyp in Scheme ist die Liste (list). Formal
gesehen wird eine Liste entweder als leere Liste definiert
(repräsentiert als '()
), oder als ein Paar, dessen cdr
eine Liste ist.
Es gibt viele Arten, Listen zu erstellen. Die vielleicht häufigste Methode
ist die list
-Prozedur:
guile> (list 1 2 3 "abc" 17.5) (1 2 3 "abc" 17.5)
Wie man sehen kann, wird eine Liste dargestellt in Form der einzelnen Elemente, getrennt durch ein Leerzeichen und als Gruppe in Klammern eingeschlossen. Anders als bei einem Paar, befindet sich kein Punkt zwischen den Elementen.
Eine Liste kann auch als wörtliche Liste notiert werden, indem man die enthaltenen Elemente in Klammern einschließt und ein einfaches Anführungszeichen voranschreibt:
guile> '(17 23 "foo" "bar" "bazzle") (17 23 "foo" "bar" "bazzle")
Listen haben eine zentrale Stellung in Scheme. Scheme wird als Dialekt von Lisp angesehen, und das Wort „lisp“ steht für „List Processing“. Scheme-Ausdrücke sind immer Listen.
Assoziative Listen (alist)
Eine besonderer Listentyp ist die assoziative Liste oder alist. Eine Alist wird benutzt, um Daten zum einfachen Abrufen zu speichern.
Alisten sind Listen, deren Elemente als Paare kommen. Der car
-Teil
jedes Elements wird als Schlüssel (key) bezeichnet, der
cdr
-Teil jedes Elements wird Wert (value) genannt.
Die Scheme-Prozedur assoc
wird benutzt, um einen Eintrag aus einer
Aliste aufzurufen, und mit cdr
wird sein Wert abgefragt:
guile> (define my-alist '((1 . "A") (2 . "B") (3 . "C"))) guile> my-alist ((1 . "A") (2 . "B") (3 . "C")) guile> (assoc 2 my-alist) (2 . "B") guile> (cdr (assoc 2 my-alist)) "B" guile>
Alisten werden sehr viel in LilyPond genutzt, um Eigenschaften und andere Daten zu speichern.
Hash-Tabellen (hash table)
Eine Datenstruktur, die ab und zu in LilyPond eingesetzt wird. Eine Hash-Tabelle ähnelt einem Array, aber die Indexe des Arrays können beliebige Scheme-Werte sein, nicht nur Integre.
Hash-Tabellen sind effizienter als Alisten, wenn man viele Daten speichern will und die Daten sich oft ändern.
Die Syntax, mit der Hash-Tabellen erstellt werden, ist etwas komplex, aber man kann Beispiele hierzu im LilyPond-Quellcode finden.
guile> (define h (make-hash-table 10)) guile> h #<hash-table 0/31> guile> (hashq-set! h 'key1 "val1") "val1" guile> (hashq-set! h 'key2 "val2") "val2" guile> (hashq-set! h 3 "val3") "val3"
Werte werden aus den Hash-Tabellen mit hashq-ref
ausgelesen.
guile> (hashq-ref h 3) "val3" guile> (hashq-ref h 'key2) "val2" guile>
Schlüssel und Werte werden als Paar mit hashq-get-handle
ausgelesen.
Das ist die beste Art, weil hier #f
ausgegeben wird, wenn ein
Schlüssel nicht gefunden werden kann.
guile> (hashq-get-handle h 'key1) (key1 . "val1") guile> (hashq-get-handle h 'frob) #f guile>
[ << Scheme-Tutorium ] | [Top][Contents][Index] | [ Schnittstellen für Programmierer >> ] |
[ < Einfache Scheme-Datentypen ] | [ Up : Einleitung in Scheme ] | [ Berechnungen in Scheme > ] |