Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.
Referenzen und Listen
Eine Frage, deren Antwort vielleicht nicht auf den ersten Blick ersichtlich ist (auch nicht aus dem Scheme Report), ist, ob bestimmte Listenfunktionen nun Kopien der Werte oder Referenzen auf die Listenelemente zurückliefern. Ich hab es einfach mal ausprobiert und falls es jemanden interessiert, hier die Ergebnisse:
list-tail liefert eine Referenz auf die Teilliste zurück, und nicht eine neue Liste mit den selben Werten. Man betrachte folgendes Beispiel:
(define L '(1 2 3 4 5))
(define A (list-tail L 2))
(set-car! A 6)
L
Ausgabe: (1 2 6 4 5)
Ebenso verhalten sich die Funktionen memq, memv, member, assq, assv, assoc.
list-ref liefert allerdings eine Kopie des Wertes zurück:
(define L '(1 2 3 4 5))
(define a (list-ref L 2))
(set! a 6)
L
Ausgabe: (1 2 3 4 5)
Offenbar werden also Paare (d.h. also auch Listen) per Referenz gespeichert, alles andere als Wert.
Noch ein Beispiel:
(define A (cons 1 2))
(define B A)
(set-cdr! B 3)
A
Ausgabe: (1 . 3)
Hier wird deutlich, dass B eine Referenz auf das selbe Paar wie A enthält und nicht eine Kopie davon erhält.
Für Vektoren gilt das gleiche:
(define U (make-vector 3 0))
(define V U)
(vector-set! V 1 1)
U
Ausgabe: #3(0 1 0)
listref liefert ebenfalls eine referenz!
das beispiel ist leider unglücklich gewählt. darin ist L einfach eine liste von nummern. list-ref liefert nun das (n-1)te element aus dieser liste, oder hier die 3. im endeffekt steht also da:
(define a 3)
, dieses steht dann in keiner beziehung mehr zur liste.
nimm einfach mal eine liste, die ihrerseits wieder aus listen besteht:
(define LOL (map list '(1 2 3 4 5)))
dann hole wieder das dritte element raus
(define b (list-ref LOL 2))
so, und nu weisen wir dem ding mal was zu
(set-cdr! b '(666))
ergebnis des aufrufes “LOL”:
((1) (2) (3 666) (4) (5))
Ja, es hat wohl nichts mit den Funktionen zu tun, sondern anscheinend werden Paare, Listen und Vektoren als Referenz und alles andere direkt gespeichert.
Is ja klar, sieh ein pair einfach als eine Art Doppel-Pointer an… Dann wird’s vielleicht verständlicher, was ein Wert und was eine Referenz ist…
Aber hat schonmal jemand versucht, aus einer leeren Liste ein pair zu machen? Ich hab’s net geschafft! Ich hab also die leere Liste, die scheinbar als Wert übergeben wird (schon zu spät!!), und jetzt soll da ne Liste draus werden… Hier mein Versuch:
[code](define (makex x val)
(begin
(set! x (cons val '()))
x))
(define l '())
l
(makex l 1)
l[/code]
Aus logistischen und anderen Gründen kann diese set!-Zuweisung nicht außerhalb der makex-Funktion erfolgen. Nur falls mir jemand sowas anbieten wollte…
Ich hätte es also gerne so, dass ich dem Teil ne leere Liste übergeb, da hängt er dann ein Teil dran und das, was mal DIE leere Liste war, soll jetzt ein Element sein! Is aber net, es bleibt leer. Ergo: was einmal zu einer leeren Liste verkümmert ist, muss es für immer bleiben! Kann sowas sein?
Ich brauche eine Lösung dafür!!!