# 'y es una función no válida?

7

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.

PythonNut
fuente
1
andes una forma especial en lugar de una función.
Dan
2
Debe usar una función con el comportamiento deseado, como (cl-every 'identity lst)o (-all? 'identity lst).
wasamasa
@wasama gracias. Lo haré en su lugar.
PythonNut

Respuestas:

5

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

y es una forma especial en el 'código fuente C'.

(Y condiciones...)

Evalúe args hasta que uno de ellos rinda cero, luego devuelva cero. Los argumentos restantes no se evalúan en absoluto. Si ningún argumento produce cero, devuelve el último valor del argumento.

[espalda]

Entonces, aunque se comporta como una función, no lo es. Se genera el mismo error al usar un macroen lugar de and.

Jonathan Leech-Pepin
fuente
77
No se comporta como una función: deja de evaluar argumentos una vez que uno de ellos es nulo. (and nil (drop 'bomb))es seguro mientras andno sea una función.
YoungFrog
3

Para agregar y resumir lo que otros han dicho:

(functionp 'and) ; ===> nil

Fin de la historia.

Del manual de Elisp, nodo Qué es una función :

Puede usar la función functionppara probar si un objeto es una función:

- Función: objeto functionp Esta función se devuelve tsi OBJECT es cualquier tipo de función, es decir, se puede pasar a funcall. Tenga en cuenta que functionpdevuelve los tsímbolos que son nombres de funciones y devuelve 'nulo' para formas especiales.


(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 ‘...’).

Dibujó
fuente
1

¿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é myfunces. Si se trata de una función, Emacs evalúa todas las formas Lisp arg1, arg2, etc, entonces llama a la función myfunccon los objetos Lisp resultantes como argumentos.

Como se señaló, andno 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, porque apply 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: nilse evalúa, luego (drop 'bomb)se evalúa.

¿Por qué se applyqueja?

Intentar usarlo applyen 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.

YoungFrog
fuente