On 20/03/2011, at 8:25 PM, Christian wrote: > Hello Andreas! > > Thanks for your swift reply. I'll try to explain the reasoning behind > my code. > > In the Clojure Reference I found the function into, which is described > like so: > > Usage: (into to from) > "Returns a new coll consisting of to-coll with all of the items of > from-coll conjoined." This is exactly what's happening: (def v [1 2 3]) (into v (pop v)) => [1 2 3 1 2]
However, v => [1 2 3] It does not mutate the original vector. The same applies for conj. > I'm currently reading the book "Programming Clojure". In it, the > author has a chapter on binding which states that vectors are indeed > immutable. I'm not sure if this is a problem of scope, but I thought > that I could coerce fib-vec into receiving a new vec and throwing the > old one away (making the old one available for deletion from the GC). > That is why I used 'into fib-vec'. I thought it would re-bind fib-vec > to itself, but with one element less. I used the same idea with > ansVec. See above. into doesn't rebind it's arguments. Rather it returns a sequence which contain the second argument added to the elements of the first. It doesn't physically alter the first argument. > > Could you perhaps tell me why it cannot do that? Rather, is this > behavior possible in Clojure? > > PS: Thanks for the book-tipp! I'll be sure to check it out. > All this is intrinsic Clojure behaviour. Clojure is unique in this way. You will find that other flavours of Lisp allow mutable data (e.g. setf in common lisp). Thassilo provided a more idiomatic solution to your problem. Andreas > On Mar 20, 10:48 am, Andreas Kostler > <andreas.koestler.le...@gmail.com> wrote: >> Hi Christian, >> What you're trying to do is to build up a vector with the last element of >> the vector being the answer to your problem: >> (last answer) >> => 4613732 >> You're trying to use cons (conj) to build up that list. >> >> Now, your function below never terminates because you're: >> a) Not actually building up the ans-vec >> b) Not actually changing fib-vec to be closer to termination >> >> Clojure datastructures are immutable. conj returns a new seq with the second >> argument conj(s)ed onto the old sequence without changing the old seq e.g.: >> >> (def v [1 2 3]) >> (conj v 4) >> => [1 2 3 4] >> >> but: >> v >> => [1 2 3] >> >> The same applies to into. >> The closest I can think of you're trying to achieve is: >> >> (defn answer [] >> (loop [ans-vec [0] fib-v fib-vec] >> (if (empty? fib-v) >> ans-vec >> (recur (conj ans-vec (+ (last ans-vec) (last fib-v))) (pop >> fib-v))))) >> >> Now you're actually building up ans-vec in a tail-recursive fashion while >> changing fib-v to be closer to termination. >> >> Having said that, what you really want is (reduce + fib-vec) ;) >> >> Andreas >> P.S. To get your head around basic recursion dig into "The little Schemer" >> by Friedman and Felleisen >> >> On 20/03/2011, at 7:22 PM, Christian wrote: >> >> >> >> >> >> >> >> >> >>> I've tried Project Euler 2 now. >> >>> For those unfamiliar, Project Euler Problem 2 states: find the sum of >>> all even-valued fibonacci terms that are less than four million. >> >>> Let's assume that I have the code to fill the vector: >> >>> (def fib-seq >>> ((fn rfib [a b] >>> (lazy-seq (cons a (rfib b (+ a b))))) >>> 0 1)) >> >>> (def fib-vec >>> (into [] (filter even? (take 35 fib-seq)))) >> >>> Many people reading the Clojure Samples will be familiar with the >>> first sample. My own implementation did not want the 'take' function >>> to work. However, that is a question for another day. Assume that the >>> magic number 35 in the second function does indeed give me all even- >>> valued fibonacci terms under four million. (I did not know how to >>> specify a predicate depending on the value of (fib-seq) to check if >>> the value is under 4 million.) >> >>> With the function '(reduce + (fib-vec))' I effortlessly summed up all >>> values in the vector. This is peculiar, because I first wanted to >>> write a function that does this for me, but to no avail. >> >>> (defn answer [] >>> (let [ansVec [0]] >>> (while (not-empty fib-vec) >>> (conj ansVec (+ (last ansVec) (last fib-vec))) >>> (into fib-vec (pop fib-vec))))) >> >>> This function never terminates. Why not? Where am I thinking wrong? >> >>> -- >>> 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 >> >> ************www.leica-geosystems.com************* >> >> when it has to be right, Leica Geosystems >> >> Please consider the environment before printing this email. > > -- > 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 -- "Test-driven Dentistry (TDD!) - Not everything should be test driven" - Michael Fogus -- ********************************************************** Andreas Koestler, Software Engineer Leica Geosystems Pty Ltd 270 Gladstone Road, Dutton Park QLD 4102 Main: +61 7 3891 9772 Direct: +61 7 3117 8808 Fax: +61 7 3891 9336 Email: andreas.koest...@leica-geosystems.com ************www.leica-geosystems.com************* when it has to be right, Leica Geosystems Please consider the environment before printing this email. -- 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