reduce
y apply
son por supuesto, sólo equivalente (en términos del resultado final devuelto) para las funciones asociativas que tienen que ver todos sus argumentos en el caso-aridad variable. Cuando son equivalentes a los resultados, diría que apply
es siempre perfectamente idiomático, mientras que reduce
es equivalente, y podría reducir una fracción de un abrir y cerrar de ojos, en la mayoría de los casos comunes. Lo que sigue es mi razonamiento para creer esto.
+
se implementa en sí mismo en términos de reduce
para el caso de aria variable (más de 2 argumentos). De hecho, esto parece una forma "predeterminada" muy sensible para cualquier función asociativa de aria variable: reduce
tiene el potencial de realizar algunas optimizaciones para acelerar las cosas, quizás a través de algo como internal-reduce
, una novedad 1.2 deshabilitada recientemente en el maestro , pero ojalá sea reintroducido en el futuro, lo cual sería una tontería repetir en cada función que podría beneficiarse de ellos en el caso vararg. En casos comunes, apply
solo agregará un poco de sobrecarga. (Tenga en cuenta que no hay nada de qué preocuparse realmente).
Por otro lado, una función compleja puede aprovechar algunas oportunidades de optimización que no son lo suficientemente generales para integrarse en reduce
; entonces apply
le permitiría tomar ventaja de esos mientras que reduce
en realidad podría hacerlo más lento. Un buen ejemplo del último escenario que ocurre en la práctica lo proporciona str
: utiliza un StringBuilder
internamente y se beneficiará significativamente del uso de apply
en lugar de reduce
.
Entonces, yo diría que use apply
en caso de duda; y si usted sabe que no le está comprando nada más de reduce
(y que es poco probable que esto cambie muy pronto), siéntase libre de usar reduce
para reducir esa diminuta sobrecarga innecesaria si así lo desea.
Gran respuesta. En una nota lateral, ¿por qué no incluir una función de suma incorporada como en Haskell? Parece una operación bastante común. – dbyrne
¡Gracias, feliz de escuchar eso! Re: 'sum', yo diría que Clojure tiene esta función, se llama' + 'y puedes usarla con' apply'. :-) Hablando en serio, creo que en Lisp, en general, si se proporciona una función variadica, generalmente no va acompañada de un contenedor que opere en las colecciones, eso es lo que usas 'apply' para (o' reduce', si sabes eso tiene más sentido). –
Es curioso, mi consejo es el opuesto: 'reduce' en caso de duda, 'aplica' cuando estés seguro de que hay una optimización. El contrato de 'reduce' es más preciso y, por lo tanto, más propenso a la optimización general. 'apply' es más vago y, por lo tanto, solo se puede optimizar caso por caso. 'str' y' concat' son las dos excepciones predominantes. – cgrand