The key to writing an algorithm functionally is to break it up into simple components.
You're performing three calculations: (def x (myfunc x)) (def buffer (in_buffer buffer x)) (+ (nth buffer 1) (nth buffer 3)) Let's tackle each in turn. The first is a continually changing value of x, with the new value calculated from the previous. We can represent this as a sequence, e.g. (x, (f x), (f (f x)), (f (f (f x))), ...) We could write a function to do this for us: (defn iterate [f x] (cons x (lazy-seq (iterate f (f x))))) But fortunately the iterate function already exists in the clojure.core namespace. So this solves your first calculation: (def x (myfunc x)) ==> (iterate myfunc 0) Next, we want a sliding buffer of 5 values. Again, we could represent this as a sequence, e.g. ([a b c d e], [b c d e f], [c d e f g], ...) We could write our own function for this (defn sliding-buffer [n xs] (cons (take n xs) (lazy-seq (sliding-buffer n (rest xs))))) But it turns out there's already a function to do this in clojure.core, called partition: (def buffer (in_buffer buffer x)) ==> (partition 5 1 (iterate myfunc 0)) Okay, we're nearly there. Now we just need to add the second and fourth numbers (indexes 1 and 3) together for each value in the sequence. We can do this with a map: (map (fn [b] (+ (nth b 1) (nth b 2))) (partition 5 1 (iterate myfunc 0))) Or, with a bit of syntax sugar: (->> (iterate myfunc 0) (partition 5 1) (map #(+ (nth % 1) (nth % 3)))) In my opinion, one of the key difficulties with programming in a functional style is to realise that a single loop in an imperative program may hide multiple pieces of functionality. The functional style favours splitting this out into sequence operations that do one thing each. - James On 6 October 2013 20:02, vMac <vanmac...@gmail.com> wrote: > Hello, > > I'm new to closure and functional programming and need some adviec/help > with > my oldschool programming style. > I've written the following little program and hope someone could help me > to improve it. > > The programm computes numbers through an iterative function , put the > numbers in a 'shift buffer' and computes some value from the entries > in that buffer. > > I'm sure it's not optimal at all and could be improved a lot. > I've used a vector (and not a list) as buffer because I have to address > and use the elements using nth. Hope thats ok, but not sure of that. > I wish I could enter the new values at the start (left side) but found noe > efficient way to do it. With vector one should use conj to add new values > and > that could only be done from the right side of the buffer , right? > I'm sure there is a much better way to build such a 'shift buffer', any > ideas? > > Another concern I have is the used of def's in the iteration loop. > Overwriting the x and the buffer may not be optimal, but I have no idea of > another (more functional) approch to that. > > > ; defines my function > (defn myfunc [x] > (mod (+ (inc x) (rand-int 10) ) 10)) > > ; creates buffer and sets initial values > (def buffer (vec (take 5 (repeat 0))) ) > > ; creating a 'shift buffer': removes oldest entry and adds a new value at > the end > > (defn in_buffer [buff x] > (conj (subvec buff 1) x)) > > ; sets start value > (def x 0) > > ; iteration loop > (dorun(for [i (range 20)] > > (do > (def x (myfunc x)) ; computes new value using myfunc and sets > new x value > (def buffer (in_buffer buffer x)); writes value into buffer and > sets new buffer > (println buffer) ;print buffer > (println (+ (nth buffer 1) (nth buffer 3)) )))) ; ;compute with > values from bufffer > > > > > Thank you or your help. > > > -- > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > 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 unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/groups/opt_out. > -- -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.