# 'e é uma função inválida?

7

Estou tentando ver se todos os valores em uma lista são verdadeiros. Por alguma razão, (apply #'and lst)erros com:

Função inválida: e

Isso também acontece quando tento (cl-reduce #'and lst).

No entanto, (apply #'max lst)parece funcionar bem.

No momento, estou usando (eval `(and ,@lst)), mas isso parece feio.

PythonNut
fonte
11
andé uma forma especial e não uma função.
Dan
2
Você deve usar uma função com o comportamento desejado, como (cl-every 'identity lst)ou (-all? 'identity lst).
Wasamasa
@wasama obrigado. Eu vou fazer isso em seu lugar.
precisa saber é o seguinte

Respostas:

5

Esta é realmente apenas uma resposta parcial (já que não sei dizer por que ou realmente fornecer uma solução alternativa para isso além do que você já tem).

Conforme C-h f and

e é uma forma especial no `código fonte C '.

(e CONDIÇÕES ...)

Avalie os argumentos até que um deles dê zero, depois retorne zero. Os argumentos restantes não são avaliados. Se nenhum argumento for nulo, retorne o valor do último argumento.

[de volta]

Portanto, mesmo que se comporte como uma função, não é uma. O mesmo erro é gerado usando a macrono lugar de and.

Jonathan Leech-Pepin
fonte
7
Ele não se comporta como uma função: que para de avaliar argumentos quando um deles é nulo. (and nil (drop 'bomb))é seguro desde que andnão seja uma função.
YoungFrog
3

Para adicionar e resumir o que outros disseram:

(functionp 'and) ; ===> nil

Fim da história.

No manual Elisp, nó O que é uma função :

Você pode usar a função functionppara testar se um objeto é uma função:

- Função: functionp object Esta função retorna tse OBJECT for qualquer tipo de função, ou seja, puder ser passada para funcall. Observe que functionpretorna tpara símbolos que são nomes de funções e retorna 'nil' para formulários especiais.


(Cara, eu odeio a nova citação ondulada nos manuais. Faz-me substituir cada uma delas `depois de colar o manual aqui. Duas vezes mais esforço do que quando o manual (com prudência) usou em `...'vez de ‘...’).

Desenhou
fonte
1

O que é uma função?

Para entender por que isso acontece, precisamos saber o que é uma função. Ao avaliar o formulário lisp (myfunc arg1 arg2 ...), o emacs primeiro verifica o que myfuncé. Se for uma função, emacs avalia todas as formas Lisp arg1, arg2etc., em seguida, chama a função myfunccom os objetos Lisp resultantes como argumentos.

Como foi observado, andnão é uma função, é uma forma especial, portanto, ele pode avaliar seus argumentos conforme necessário. Como eu disse em um comentário anterior, o formulário (and nil (drop 'bomb))é seguro porque (drop 'bomb)nunca é avaliado.

Por outro lado, (apply #'and (list nil (drop 'bomb)))não é seguro, porque apply é uma função, então o emacs avalia primeiro #'and(o resultado é um símbolo), depois avalia (list nil (drop 'bomb)), que é novamente uma chamada de função, para que você adivinhe o que acontece a seguir: nilé avaliado e, em seguida, (drop 'bomb)avaliado.

Por que applyreclama?

Tentar usar applyem um formulário especial (ou macro) não faz sentido, porque o formulário especial não pode ter seu comportamento especial; portanto, gera um erro.

YoungFrog
fonte