Eu tenho algumas perguntas básicas sobre o elisp.
Costumo ver algo como
(search-forward "something" nil 'noerror)
E às vezes vejo algo como
(search-forward "something" nil :noerror)
Qual é a diferença e devo preferir um formulário ao outro?
Tanto quanto eu entendo tudo, mas a lista vazia é avaliada como verdadeira em um contexto booleano. Mas como vem o seguinte:
Quando o termo de pesquisa "alguma coisa" não existe no buffer, o ponto salta para o final do buffer quando 'noerror
é usado em vez de t
. Quando t
é usado, o ponto permanece onde está.
Primeiro caso:
(search-forward "something" nil 'noerror);; 1.Evaluate this
;; end of buffer 2.point jumps here
Segundo caso:
(search-forward "something" nil t);; 1.Evaluate this, 2. Point stays here
;; end of buffer
nil
valores são tratados da mesma forma pela função especificada, passo no meu código um símbolo com o mesmo nome ou semelhante ao nome do parâmetro usado na descrição da função e normalmente em maiúsculas. Isso serve como um lembrete para mim, quando leio o código. Por exemplo(search-forward "abc" nil 'NOERROR)
. É mais útil para argumentos opcionais que raramente são usados.Respostas:
Os valores booleanos no elisp funcionam da seguinte maneira:
nil
e()
(que, como você observou, são a mesma coisa) são falsasO
t
símbolo existe como um valor 'puro' de true (quando não há benefício em usar outro valor), mas a maioria das funções tentará retornar algo que poderia ser útil, sempre que possível.Veja também C-hig
(elisp) nil and t
RETQuando se trata de usar argumentos de palavra-chave ou outros símbolos como um não-
nil
valor quando o código única se preocupanil
ou nãonil
, é realmente apenas uma questão de preferência pessoal. Não há diferença em termos de execução.Uma vez perguntei a mesma coisa e fui informado de que a abordagem de argumento de palavra-chave é um método Lisp-ish mais comum.
(Eu mesmo decidi usar argumentos de palavra-chave, em parte para destacar a sintaxe e em parte porque os diferencia melhor dos símbolos de variável e função).
Quanto à sua exemplo específico, a função faz diferenciar entre vários não-
nil
valores, e que o comportamento é coberto pela sua docstring:Em geral, você notará que as doutrinas tendem a se referir a "não nulo" em vez de "verdadeiro" ou "t". Se você vir "t", é bem provável que seja um caso especial.
fonte
nil
é). Por "puro", apenas quero dizer que existe especificamente para ser um valor que significa "verdadeiro", porque às vezes é isso que você deseja. Outros não-nil
valores ainda são tão "verdadeiros" quantot
são.Alguma referência histórica é devido.
O Emacs Lisp empresta muitas coisas do Common Lisp, mas a semelhança é apenas superficial. O símbolo de dois pontos no Common Lisp é um qualificador de espaço para nome. Os nomes de símbolos canônicos têm duas partes: o nome do pacote e o nome do símbolo nesse pacote; portanto, por exemplo,
cl-user:apropos
é um símbolo definido no pacotecl-user
. Há também um pacote de palavras-chave especial importado automaticamente pelo Common Lisp quando é iniciado. Este pacote é usado para se comunicar entre outros pacotes (para que, se os pacotes precisem enviar informações simbólicas entre si, eles não discutirão sobre quem deve declará-las). Como você deve ter adivinhado, os símbolos desse pacote são escritos com os dois pontos principais.O Emacs Lisp não tem um conceito de pacotes, mas o cólon ainda é especial, pois instrui o leitor a interpretar a expressão como símbolo de autoavaliação (ou seja, é uma variável cujo valor é essa variável). Existem vários desses símbolos de autoavaliação incorporados:
t
enil
são exemplos que vou escrever mais adiante.O apóstrofo também é emprestado do Common Lisp, onde é uma macro de leitor padrão (ou seja, é um código que o interpretador Lisp executa durante a leitura na fonte do programa). Ele se expande da seguinte forma:,
'x -> (quote x)
onde(quote ...)
é uma forma especial que impede o intérprete Lisp de avaliar o conteúdo da expressão interna. Emacs Lisp tem três built-in macros leitor:'
,`
e#
, mas você não pode adicionar seu próprio. Os dois primeiros se expandem para(quote ...)
, no entanto, o segundo permite uma sintaxe especial para criar a expressão não avaliada.#
expande para o(function ...)
formulário, o que instrui o intérprete que o valor deve ser procurado no espaço de nomes da função.Os símbolos no Emacs Lisp devem ser avaliados com algum valor (semelhante a variáveis em outros idiomas), caso contrário, é um erro. No entanto, você pode impedir a avaliação usando o formulário de cotação.
Finalmente, a diferença entre:
e
É que, no primeiro caso, você chamou
search-forward
com um símbolo sem valor, para o qual apenas o nome é conhecido, e no segundo caso, você chamou essa função com um símbolo cujo valor é esse próprio símbolo. Acontece que essa função não se importa com qual deles você usa.Os tipos são uma importante ferramenta de programação para verificação automática de programas. O sistema de tipos Emacs Lisp é semelhante ao Common Lisp, pois seu tipo universal (escrito como
t
) é o tipo do qual todos os outros tipos são derivados. Por outro lado,nil
é o tipo do qual nenhum tipo é derivado (o complemento det
). Isso é diferente de muitas linguagens de programação populares, que podem não ter um conceito de tipo universal ou ter um tipo booleano distinto.Mais uma vez, infelizmente, o Emacs Lisp não copiou esta parte precisamente do Common Lisp, e a
type-of
função fornece resultados confusos parat
enil
.Emacs Lisp:
Lisp comum
Extensão comum do Emacs Lisp Lisp tem uma função
cl-typep
que pode, no entanto, ajudar a entender o relacionamento. Então, por exemploou seja, seja o que
'noerror
for, é do tipot
.fonte