Was macht "Symbolwert"?

13

Die Dokumentation hat mich nicht weiser gemacht:

Diese Funktion gibt den in der Wertezelle des Symbols gespeicherten Wert zurück. Hier wird der aktuelle (dynamische) Wert der Variablen gespeichert. Wenn die Variable keine lokale Bindung hat, ist dies einfach ihr globaler Wert. Wenn die Variable ungültig ist, wird ein ungültiger Variablenfehler gemeldet.

Was ist der Sinn des Symbolwertes? Wo und wann muss ich es benutzen?

Die unfun Katze
quelle
3
Vielen Dank, dass Sie versuchen, die Antwort zu finden, indem Sie Emacs fragen. Das ist der richtige Ansatz: Fragen Sie zuerst Emacs und dann hier, was noch nicht klar ist. Lassen Sie uns in Ihrer Frage wissen, was Sie bereits versucht haben. Ein dickes Lob!
Drew

Antworten:

13

Sie benötigen es, wenn Sie im Elisp-Code den Wert eines Symbols erhalten möchten, d. H. Den Wert, wenn Sie es als Variable betrachten.

Beachten Sie, dass ein Elisp-Symbol mehrere Merkmale aufweist:

  • Es hat einen Namen (welche Funktion symbol-namegibt)
  • Es könnte einen Wert haben, wenn es als Variable betrachtet wird (was symbol-valuegibt)
  • Es könnte eine Funktion benennen, wenn es als eine Funktion betrachtet wird (die symbol-functiongibt)
  • Es hat eine Eigenschaftsliste (die symbol-plistgibt)

Stellen Sie sich ein Symbol als Objekt mit verschiedenen Attributen vor.

Drew
quelle
1
Beachten Sie auch, dass (wie in der Dokumentation angegeben) symbol-valueimmer die dynamische Bindung für das Symbol zurückgegeben wird. Auf diese Weise können Sie keine lexikalischen Werte erhalten.
Phils
2
Siehe auch C-h i g (elisp) Symbol Components RETDokumentation zu diesen verschiedenen Symbolzellen / -komponenten.
Phils
@phils: Hm, ich frage mich: (setq lexical-binding t) (let ((v 42)) (message "lex: %S, val: %S" lexical-binding (symbol-value 'v))). Aber ja, das ist , was es sagt auf (elisp) Lexical Binding: „ Funktionen wie symbol-value, boundp'und set'nur abrufen oder einer Variablen dynamisch ändern Bindung (dh der Inhalt seines Symbols Wert Zelle) “. Es wird jedoch nichts darüber gesagt Symbol Components.
Drew
10

(Doh, @Drew hat bereits einige der folgenden Punkte angesprochen. Hier sind jedoch einige zusätzliche Details.)

Wie in der Handbuchseite zu Symbolkomponenten erläutert, enthält jedes Symbol vier Komponenten (Zellen): seine Drucknamenszelle, seine Wertezelle, seine Funktionsdefinition und seine Eigenschaftsliste. Entweder die Wertzelle oder die Funktionszelle ist ungültig, und die Eigenschaftsliste ist möglicherweise null.

Wie das Handbuch auch betont:

Da jedes Symbol separate Wert- und Funktionszellen hat, treten keine Konflikte zwischen Variablennamen und Funktionsnamen auf.

Deshalb können Sie zum Beispiel haben:

(setq test "kittens")
(defun test ()
  (message "puppies"))
(symbol-value 'test)    ; => "kittens"
(symbol-function 'test) ; => (lambda nil (message "puppies"))
Dan
quelle
1
Ah, dass es Wert ist, im Gegensatz zu Funktion, hat es viel leichter verständlich gemacht. Vielen Dank.
The Unfun Cat
8

Hier ist ein historischer Hinweis (ich bin noch nicht geboren, als die beschriebenen Ereignisse stattfanden, also korrigiert mich vielleicht jemand, der mehr über mich weiß. All dies ist auf das Lesen alter Artikel und einiger Bücher zurückzuführen).

Nachdem auf den Haftungsausschluss verzichtet wurde, scheint es, als sei "symbolisch" in den Tagen von Fortran vs Lisp eine Art Modewort gewesen, wie es "objektorientiert" heute ist. Das heißt, Programme wurden in der Regel nur als riesige mathematische Formeln betrachtet, bei denen die Zahlen irgendwann eingefügt werden und die Platzhalter für Zahlen unerheblich sind. Alle in einem Programm enthaltenen symbolischen Informationen würden verschwinden, sobald dieses Programm entweder ausgeführt, kompiliert oder interpretiert wird. Die Neuheit von Lisp war, dass Symbole in einem Programm bestehen bleiben konnten, selbst nachdem es ausgeführt, kompiliert oder interpretiert wurde. Dies inspirierte eine Terminologie wie "symbolische Algebra" (wie bei der Manipulation algebraischer Formeln auf Papier / Tafel anstatt durch direkte Berechnung). Um dies (und andere symbolische Dinge) zu unterstützen, sollten Symbole mit einem Namen und einigen Eigenschaften versehen werden. Aus nicht-symbolischer Sicht könnte man sagen, dass "Symbole nur benannte Zeiger" sind, und obwohl dies nicht der Fall ist, sind sie eher Zeiger auf Strukturen, aber aus praktischen Gründen sind Symbole Bezeichner der Linken Seite eines Variablen-Wert-Paares. Dies macht es auch möglich zu sehensymbol-value Funktion als Zeiger-Dereferenzierung in nicht-symbolischen Sprachen.

Moderne Lisps unterscheiden sich darin, wie viele Werte einem Symbol zugeordnet werden können. (Angenommen, Sie hatten eine nicht-symbolische Sprache mit mehreren Speicherstapeln / -haufen. Sie könnten sich eine Situation vorstellen, in der der gleiche Zeiger eine Bedeutung hat, wenn er im Kontext verschiedener Stapel interpretiert wird.) Haufen). So haben Lisp2-Sprachen (Emacs Lisp ist eine solche Sprache) einen separaten Speicher für Funktionen und Variablen. Deshalb gibt es auch einen symbol-function, der "einen Zeiger dereferenziert, der auf einen Funktionsspeicher verweist". Schema hat diesen speziellen Speicher nicht und Clojure AFAIK hat weder das noch symbol-plist.

wvxvw
quelle
7

Kleine Demo:

(setq v1 10)
;;10
v1
;;10
(setq v2 'v1)
;;v1
v2
;;v1
(symbol-value v2)
;;10 
abo-abo
quelle