Pregunta

Por lo que entiendo sobre Aplicar, desempaqueta una lista y convierte los elementos en argumentos para una función.

Veo que (aplicar + [1 2 3]) funciona como se esperaba, es decir: es equivalente a ( + 1 2 3).

¿Por qué entonces (aplicar o [verdadero falso]) no es válido? ¿No es equivalente a (o verdadero falso)?

¿Fue útil?

Solución

Porque or es una macro, no una función normal. Puedes obtener el mismo efecto con (some identity [true false]).

Otros consejos

Como alternativa a o puedes usar (alguno predicado coll).

clojure.core/Some ([pred coll])
Devuelve el primer valor verdadero lógico de (pred x) para cualquier x en coll, else nil. Un lenguaje común es usar un conjunto como Pred, por ejemplo, esto volverá: Fred If: Fred está en la secuencia, de lo contrario nil: (algunos #{: Fred} coll)

¿Puedes probar algunos con verdadero? y falso? predicados,


user=> (some true? [true false false])
true
user=> (not (some true? [true false false]))
false
user=> (some false? [true false false])
true
user=> (not (some false? [true false false]))
false

o es una macro, que no puede usar como valor.

Crear una función anónima, expandirse o a tiempo de ejecución Vía eval:

(apply #(eval (list* 'or %&)) [true false])

Sin embargo, una de las cosas importantes a tener en cuenta es el modelo de evaluación. or cortocircuitos, por lo tanto: (or true :some random expression that never gets evaluated:) Nunca evalúa el último. or Se usa tradicionalmente tanto como una estructura de control como 'lógica o'.

En el modelo tradicional de (f x y z), X, Y y Z se evalúan, y se aplica F.

En el uso de (apply f vec) Los contenidos del vector son no evaluados, se toman como está. Esto es más claramente visible con un vector de símbolos, no evalúan en este contexto a sus enlaces. Sin embargo, esto se ofusca por el hecho de que el modelo de Clojure para la creación vectorial es algo diferente que otras LISP, [a b c d] produce un vector que contiene las evaluaciones de los símbolos a, b, c, y d. Contrastando la mayoría de los piss, en donde #(a b c d) no evalúa los símbolos, y simplemente es idéntico a la evaluación (vector 'a 'b 'c 'd) (o de hecho (apply vector '(a b c d))).

Entonces, incluso si fuera posible aplicar formas sintácticas especiales, su resultado tendría una semántica opaca. or Primero evalúa su primer argumento, si es cierto, se detiene y devuelve eso, de lo contrario, va al segundo y se repite hasta al final. En el caso de aplicar, los argumentos ya están evaluados, ¿debería evaluar algunas por segunda vez? ¿Lo más probable es que resulte en un error de tiempo de ejecución en el camino?

Desde una perspectiva de implementación, sería muy mejorado si la sintaxis fuera también 'objetos' y requeriría un modelo de evaluación mucho más complejo. Por lo tanto, no se resuelven en tiempo de ejecución, sino que se reescriben a las primitivas compiladoras en el momento de la compilación.

Pero, por esta misma razón, cuando or se usa lógicamente en lugar de como una estructura de control, me resulta útil tener funciones or/f, and/f, if/f, etc. disponible que son procedimientos verdaderos y evalúan todos sus argumentos y, por lo tanto, se pueden aplicar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top