On Nov 8, 2010, at 1:59 PM, Laurent PETIT wrote: > I would invite you to try write your code with predicate-based hofs such as > iterate-while, filter, remove, reduce, map, etc.
I did attempt this, but the algorithm doesn't seem to lend itself nicely to this approach, which is why I was hoping for some functional gurus to help me out. - Greg > 2010/11/8 Greg <[email protected]> > So... I tried, and failed, to use transients properly. > > It's also, somehow, a fail of using clojure datastructures functionally. > I mean, transients must be used as you would used their persistent > counterparts. > Generally, you would first write the code without transients, and when it > works, try to add transient / persistent! calls here and there to see if > there's an interesting performance benefit. > > Your algorithm with calls to doseq feels imperative. You could make it work > by using reference types (presumably atoms or refs), but still this would not > be really clojurish. > > I would invite you to try write your code with predicate-based hofs such as > iterate-while, filter, remove, reduce, map, etc. > > Or, if you have more tricky conditions to start / skip parts of > datastructures, fall back to using loop. > > HTH, > > -- > Laurent > > > The function below, new-gen, takes a sequence of "nodes" and creates a new > generation of nodes out of them using the functions "transform-left" and > "transform-right". > > Each node in the sequence has two children, one is created with > transform-left, the other with tranform-right. > > The desired result is a new sequence containing all the children, > representing the "new generation". > > The catch is that some of the children are aborted at birth according the > following rules: > > 1) If the child has an existing parent with a value equal to its own, it is > left out of the sequence > 2) If the child has an existing sibling with a value equal to its own, it too > is left out of the resultant sequence > > The function is listed below: > > (defn new-gen [a] > (let [t (transient [])] > (doseq [f a] > (doseq [n [(transform-left f) (transform-right f)]] > (when-not (contains? #(= (:val n) %) (map :val > (parents n))) > (conj! t n)))) ;; <-- transient > bashing!! > (distinct #(= (:val %1) (:val %2)) (persistent! t)))) > > I'm also using modified versions of 'distinct' and 'contains?', the full > source for them (and the new-gen function) is available in > syntax-hightlighted goodness here: > > http://paste.pocoo.org/show/288063/ > > > The question is: how do I write new-gen in an elegant way and avoid "bashing > the transient"? > > I must say it would be really nice if this was considered kosher.. as it does > work just fine. It would also be useful to know why transient bashing is > frowned upon. > > Any help is greatly appreciated! > > - Greg > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to [email protected] > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > [email protected] > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to [email protected] > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > [email protected] > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to [email protected] Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/clojure?hl=en
