O que o `valor do símbolo 'faz?

13

Os documentos não me fizeram mais sábio:

Esta função retorna o valor armazenado na célula de valor do símbolo. É aqui que o valor atual (dinâmico) da variável é armazenado. Se a variável não tiver ligação local, este é simplesmente o seu valor global. Se a variável for anulada, um erro de variável anulada é sinalizado.

Qual é o ponto do valor do símbolo? Onde e quando eu preciso usá-lo?

The Unfun Cat
fonte
3
Obrigado por tentar encontrar a resposta, perguntando ao Emacs. Essa é a abordagem correta: pergunte primeiro ao Emacs e depois pergunte aqui o que ainda não está claro, deixando-nos saber em sua pergunta o que você já tentou. Parabéns!
Tirou

Respostas:

13

É necessário quando, no código Elisp, você deseja obter o valor de um símbolo, ou seja, seu valor quando considerado como variável.

Lembre-se de que um símbolo Elisp possui várias características / recursos:

  • Tem um nome (cuja função symbol-namefornece)
  • Pode ter um valor, quando considerado como uma variável (que symbol-valuefornece)
  • Pode nomear uma função, quando considerada como uma função (que symbol-functionfornece)
  • Possui uma lista de propriedades (que symbol-plistfornece)

Pense em um símbolo como um objeto, com vários atributos.

Desenhou
fonte
1
Observe também que (como a documentação indica) symbol-valuesempre retorna a ligação dinâmica para o símbolo. Você não pode obter valores lexicais dessa maneira.
phils
2
Consulte também C-h i g (elisp) Symbol Components RETa documentação sobre essas várias células / componentes de símbolos.
Phillip #
@phils: Hm, eu me pergunto: (setq lexical-binding t) (let ((v 42)) (message "lex: %S, val: %S" lexical-binding (symbol-value 'v))). Mas sim, é o que diz em (elisp) Lexical Binding: " funções como symbol-value, boundp'e set'única recuperar ou modificar dinâmica de uma variável de ligação (ou seja, o conteúdo da célula valor do seu símbolo) ". No entanto, nada é dito sobre isso em Symbol Components.
Tirou
10

(Doh, o @Drew já colocou alguns dos itens a seguir. De qualquer forma, aqui estão alguns detalhes adicionais.)

Como a página de manual no explica componentes do símbolo , existem quatro componentes (células) para cada símbolo: sua célula de nome de impressão, sua célula de valor, sua definição de função e sua lista de propriedades. A célula de valor ou a célula de função pode ser nula e a lista de propriedades pode ser nula.

Como o manual também aponta:

Como cada símbolo possui células de valor e função separadas, os nomes das variáveis ​​e os nomes das funções não entram em conflito.

É por isso que você pode ter, por exemplo:

(setq test "kittens")
(defun test ()
  (message "puppies"))
(symbol-value 'test)    ; => "kittens"
(symbol-function 'test) ; => (lambda nil (message "puppies"))
Dan
fonte
1
Ah, que é um valor em oposição à função tornou muito mais fácil entender. Obrigado.
The Unfun Cat
8

Aqui está um pouco de referência histórica (eu ainda não nasci quando os eventos descritos ocorreram, talvez alguém com mais conhecimento me corrija. Tudo isso é através da leitura de artigos antigos e de alguns livros).

Tendo dispensado o aviso de isenção, parece que nos dias de Fortran vs Lisp "simbólico" era uma espécie de chavão como o "orientado a objetos" é hoje. Ou seja, os programas costumavam ser vistos apenas como grandes fórmulas matemáticas, onde os números acabariam sendo conectados e os espaços reservados para os números eram irrelevantes. Todas as informações simbólicas contidas em um programa desapareceriam assim que esse programa fosse executado, compilado ou interpretado. A novidade do Lisp era que ele permitia que os símbolos persistissem em um programa mesmo depois de executado, compilado ou interpretado. Isso inspirou uma terminologia como "álgebra simbólica" (como na manipulação de fórmulas algébricas feitas no papel / quadro-negro, e não no cálculo direto). Para apoiar isso (e outras coisas simbólicas), os símbolos deveriam ser equipados com um nome e algumas propriedades. De um ponto de vista não simbólico, pode-se dizer que "os símbolos são apenas nomeados ponteiros" e, embora isso não seja verdade, eles são mais indicadores de estruturas, mas, para fins práticos, os símbolos são designadores da esquerda lado de um par de valor variável. Isso também permite versymbol-value funciona como desreferenciamento de ponteiro em idiomas não simbólicos.

Os Lisps modernos variam na medida em que valores podem ser associados a um símbolo (suponha que você tenha uma linguagem não simbólica com várias pilhas / pilhas de memória, você pode imaginar uma situação em que o mesmo ponteiro tenha significado quando interpretado no contexto de pilhas diferentes / montões). Portanto, as linguagens Lisp2 (o Emacs Lisp é uma dessas linguagens) têm armazenamento separado para funções e variáveis, é por isso que também existe um symbol-function, que "desreferencia um ponteiro apontando para um armazenamento de funções". O esquema não possui esse armazenamento especial e o Clojure AFAIK, não possui nem isso nem symbol-plist.

wvxvw
fonte
7

Pequena demonstração:

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