Estoy tratando de ver si todos los valores de una lista son verdaderos. Por alguna razón, (apply #'and lst)
errores con:
Función inválida: y
Esto también sucede cuando lo intento (cl-reduce #'and lst)
.
Sin embargo, (apply #'max lst)
parece funcionar bien.
En este momento, estoy usando (eval `(and ,@lst))
, pero eso se siente feo.
and
es una forma especial en lugar de una función.(cl-every 'identity lst)
o(-all? 'identity lst)
.Respuestas:
Esto realmente es solo una respuesta parcial (ya que no puedo decir por qué o realmente proporcionar una solución alternativa más allá de lo que ya tiene).
Según
C-h f and
Entonces, aunque se comporta como una función, no lo es. Se genera el mismo error al usar un
macro
en lugar deand
.fuente
(and nil (drop 'bomb))
es seguro mientrasand
no sea una función.Para agregar y resumir lo que otros han dicho:
Fin de la historia.
Del manual de Elisp, nodo Qué es una función :
(Hombre, odio las nuevas citas rizadas en los manuales. Hace que reemplace cada uno de ellos
`
después de pegar el manual aquí. El doble de esfuerzo que cuando el manual (de manera sensata) se usa en`...'
lugar de‘...’
).fuente
¿Qué es una función?
Para entender por qué sucede esto, necesitamos saber qué es una función. Al evaluar el formulario lisp
(myfunc arg1 arg2 ...)
, emacs primero verifica quémyfunc
es. Si se trata de una función, Emacs evalúa todas las formas Lisparg1
,arg2
, etc, entonces llama a la funciónmyfunc
con los objetos Lisp resultantes como argumentos.Como se señaló,
and
no es una función, es una forma especial, por lo que puede evaluar sus argumentos según sea necesario. Como di en un comentario anterior, el formulario(and nil (drop 'bomb))
es seguro porque(drop 'bomb)
nunca se evalúa.Por otro lado,
(apply #'and (list nil (drop 'bomb)))
no es seguro, porqueapply
es una función, por lo que emacs primero evalúa#'and
(el resultado es un símbolo), luego evalúa(list nil (drop 'bomb))
, que nuevamente es una llamada a función, por lo que adivina lo que sucede a continuación:nil
se evalúa, luego(drop 'bomb)
se evalúa.¿Por qué se
apply
queja?Intentar usarlo
apply
en una forma especial (o una macro) no tiene sentido, porque la forma especial no puede tener su comportamiento especial, por lo que arroja un error.fuente