Fork me on GitHub
#clojure-italy
<
2015-09-14
>
reborg16:09:29

Mi sono riscritto un fnil che accetta un numero indefinito di default. C’e’ qualche scelta migliore che potrei fare a livello di implementazione?

(defn fnil+ [f & opts]
  (fn [& args]
    (letfn [(pad [coll] (take (count args) (concat coll (repeat nil))))]
      (apply f (map #(if (nil? %1) %2 %1) args (pad opts))))))
((fnil+ + 0 0 0 0) 1 nil 2 nil)
;;3

bronsa18:09:48

@reborg: avere le arity piu` usate unrollate manualmente, per quanto orribile da vedere, e` non poco importante performance-wise

reborg20:09:43

ah vedo che non e’ cosa nuova simple_smile

reborg20:09:44

@bronsa: Re: performances, capito, posso provare un benchmark o due. Di che ordine di grandezza stiamo parlando?

reborg20:09:21

poi vedo che posso eliminare quel take, e probabilmente a quel punto anche il letfn

reborg20:09:43

(defn fnil+ [f & opts]
  (fn [& args]
    (apply f (map #(if (nil? %1) %2 %1) args (concat opts (repeat nil))))))

reborg20:09:56

che e’ praticamente quello che hai scritto nella patch simple_smile

bronsa20:09:28

@reborg: ho visto vararag+apply avere da 40% a 100% slowdown rispetto a versioni unrolled

bronsa20:09:21

io letfn lo uso SSE mi servono funzioni mutualmente ricorsive

reborg20:09:01

che va benissimo. io lo uso anche quando il nome che viene dato alla funzione rende piu’ chiaro il motivo per cui e’ scritto il codice. Nel caso precedente (quando ancora non avevo capito che potevo fare a meno del take) chiamarla pad illustrava il right-padding a nil.