Que fait «valeur-symbole»?


13

Les docs ne m'ont pas rendu plus sage:

Cette fonction renvoie la valeur stockée dans la cellule de valeur du symbole. C'est là que la valeur actuelle (dynamique) de la variable est stockée. Si la variable n'a pas de liaison locale, il s'agit simplement de sa valeur globale. Si la variable est nulle, une erreur de variable vide est signalée.

À quoi sert la valeur du symbole? Où et quand dois-je l'utiliser?


3
Merci d'avoir essayé de trouver la réponse en demandant à Emacs. C'est la bonne approche: demandez d'abord à Emacs, puis demandez ici ce qui n'est pas encore clair, en nous faisant savoir dans votre question ce que vous avez déjà essayé. Gloire!
Drew

Réponses:


13

Vous en avez besoin lorsque, dans le code Elisp, vous souhaitez obtenir la valeur d'un symbole, c'est-à-dire sa valeur lorsqu'elle est considérée comme une variable.

Gardez à l'esprit qu'un symbole Elisp a plusieurs caractéristiques / fonctionnalités:

  • Il a un nom (quelle fonction symbol-namedonne)
  • Il peut avoir une valeur, lorsqu'il est considéré comme une variable (ce qui symbol-valuedonne)
  • Il pourrait nommer une fonction, lorsqu'elle est considérée comme une fonction (ce qui symbol-functiondonne)
  • Il a une liste de propriétés (qui symbol-plistdonne)

Considérez un symbole comme un objet, avec différents attributs.


1
Notez également que (comme l'indique la documentation) symbol-valuerenvoie toujours la liaison dynamique pour le symbole. Vous ne pouvez pas obtenir des valeurs lexicales de cette façon.
phils

2
Voir également la C-h i g (elisp) Symbol Components RETdocumentation sur ces différentes cellules / composants de symboles.
phils

@phils: Hm, je me demande: (setq lexical-binding t) (let ((v 42)) (message "lex: %S, val: %S" lexical-binding (symbol-value 'v))). Mais oui, c'est ce qu'il dit dans (elisp) Lexical Binding: " fonctionne comme symbol-value, boundp'et set'ne récupère ou modifie que la liaison dynamique d'une variable (c'est-à-dire le contenu de la cellule de valeur de son symbole) ". Cependant, rien n'est dit à ce sujet sur Symbol Components.
Drew

10

(Doh, @Drew a déjà mis en place certains des éléments suivants. Quoi qu'il en soit, voici quelques détails supplémentaires.)

Comme l'explique la page de manuel sur les composants des symboles , chaque symbole comprend quatre composants (cellules): sa cellule de nom d'impression, sa cellule de valeur, sa définition de fonction et sa liste de propriétés. La cellule de valeur ou la cellule de fonction peut être nulle et la liste des propriétés peut être nulle.

Comme le souligne également le manuel:

Étant donné que chaque symbole a des cellules de valeur et de fonction distinctes, les noms de variables et les noms de fonctions n'entrent pas en conflit.

C'est pourquoi vous pouvez avoir, par exemple:

(setq test "kittens")
(defun test ()
  (message "puppies"))
(symbol-value 'test)    ; => "kittens"
(symbol-function 'test) ; => (lambda nil (message "puppies"))

1
Ah, que c'est la valeur par opposition à la fonction qui le rendait beaucoup plus facile à comprendre. Merci.
The Unfun Cat

8

Voici un peu de référence historique (je ne suis pas encore né lorsque les événements décrits ont eu lieu, alors peut-être que quelqu'un de plus compétent me corrigera. Tout cela vient de la lecture de vieux articles et de certains livres).

Ayant renoncé à la clause de non-responsabilité, il semble qu'à l'époque de Fortran vs Lisp, «symbolique» était une sorte de mot à la mode comme «orienté objet» l'est aujourd'hui. C'est-à-dire que les programmes étaient généralement considérés comme de simples formules mathématiques énormes où les nombres seront éventuellement connectés et les espaces réservés pour les nombres étaient sans importance. Toutes les informations symboliques contenues dans un programme disparaîtraient dès que ce programme serait exécuté, compilé ou interprété. La nouveauté de Lisp était qu'elle permettait aux symboles de persister dans un programme même après son exécution, sa compilation ou son interprétation. Cela a inspiré une terminologie comme «algèbre symbolique» (comme dans la manipulation des formules algébriques comme sur papier / tableau noir plutôt que par calcul direct). Afin de soutenir cela (et d'autres choses symboliques), les symboles devaient être dotés d'un nom et de certaines propriétés. D'un point de vue non symbolique, on pourrait dire que "les symboles ne sont que des pointeurs nommés", et bien que ce ne soit pas vrai, ils sont plutôt des pointeurs vers des structures, mais à des fins pratiques, les symboles sont des désignateurs de gauche côté d'une paire à valeur variable. Cela permet également de voirsymbol-value fonctionnent comme un déréférencement de pointeur dans des langages non symboliques.

Les lisps modernes varient en ce que les valeurs peuvent être associées à un symbole (supposons que vous ayez un langage non symbolique avec plusieurs piles / tas de mémoire, vous pouvez imaginer une situation où le même pointeur a un sens lorsqu'il est interprété dans le contexte de différentes piles / tas). Ainsi, les langages Lisp2 (Emacs Lisp étant l'un de ces langages) ont un stockage séparé pour les fonctions et les variables, c'est pourquoi il y a aussi un symbol-function, qui "déréférence un pointeur pointant vers un stockage de fonction". Scheme n'a pas ce stockage spécial et Clojure AFAIK, n'a ni ça ni ça symbol-plist.


7

Petite démo:

(setq v1 10)
;;10
v1
;;10
(setq v2 'v1)
;;v1
v2
;;v1
(symbol-value v2)
;;10 
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.