In a question über eine Funktion zu beantworten, die mehrere Funktionen mit den gleichen Argumenten Karten über (A: juxt), kam ich mit einer Funktion auf, die im Wesentlichen die gleiche Form wie juxt nahmen, aber Karte verwendet:Irgendwelche Vorteile für eine lazy-ish juxt-Funktion?
(defn could-be-lazy-juxt
[& funs]
(fn [& args]
(map apply funs (repeat args))))
=> ((juxt inc dec str) 1)
[2 0 "1"]
=> ((could-be-lazy-juxt inc dec str) 1)
(2 0 "1")
=> ((juxt */-) 6 2)
[12 3 4]
=> ((could-be-lazy-juxt */-) 6 2)
(12 3 4)
I Ich habe wenig Ahnung von der Faulheit oder der Leistung, aber das Timing in der REPL deutet darauf hin, dass etwas Faules vor sich geht.
=> (time (apply (juxt + -) (range 1 100)))
"Elapsed time: 0.097198 msecs"
[4950 -4948]
=> (time (apply (could-be-lazy-juxt + -) (range 1 100)))
"Elapsed time: 0.074558 msecs"
(4950 -4948)
=> (time (apply (juxt + -) (range 10000000)))
"Elapsed time: 1019.317913 msecs"
[49999995000000 -49999995000000]
=> (time (apply (could-be-lazy-juxt + -) (range 10000000)))
"Elapsed time: 0.070332 msecs"
(49999995000000 -49999995000000)
Ich bin sicher, dass diese Funktion nicht wirklich schnell ist (der Druck des Ergebnisses ‚fühlt‘ etwa so lang in beide). Ein "Take x" auf der Funktion begrenzt nur die Menge der evaluierten Funktionen, was wahrscheinlich in ihrer Anwendbarkeit begrenzt ist, und das Begrenzen der anderen Parameter durch "Take" sollte in normalem juxt genauso faul sein.
Ist das juxt wirklich faul? Würde ein lazy juxt etwas Nützliches an den Tisch bringen, zum Beispiel als einen Kompositionsschritt zwischen anderen faulen Funktionen? Was sind die Auswirkungen auf die Leistung (mem/cpu/Objektanzahl/Kompilierung)? Warum wird der Clojure juxt mit einem Reduzieren implementiert und gibt einen Vektor zurück, der Faulheit bricht?
Beachten Sie, dass '' realisiert '' Funktion, ob ein faules-Seq zu identifizieren hilft (unter? andere) hat einen Wert erzeugt. z.B. '(realisiert? ((könnte sein-lazy-juxt inc dec str) 1)))' '=>' 'false'' – sw1nn
Ich glaube, du könntest auch einfach' apply' für '# ersetzen (bewerbe% 1% 2) 'in Ihrem ersten Beispiel. –
Sie sind völlig richtig, danke! Scheint "Dinge können in Clojure immer einfacher gemacht werden" steht noch;) – NielsK