i see that "my-list (rest (rest my-list))" is in a let section. That seems like the scope would mean we are talking about a different my- list.
On Jan 11, 1:19 pm, e <evier...@gmail.com> wrote: > that's awesome, and I hope it helps others, too. Thanks for starting > with python. > > This gets to my question perfectly. Why is your code "my-list > (rest (rest my-list)) " legal? > I wouldn't have even thought to try that because, in essence, you are > changing my-list. I mean, I know how persistence works. You are just > reassigning what you think of as the start of my-list, and if no one > else is looking at the old version then it can get gc'd. I guess I > just assumed it would be harder some how. > > how do people feel about the list comprehension thing I did? > > seems like: > [my-list (for [x some-list] [x])] > > is simpler to understand than: > [my-list (vec (map vector some-list))] > > The former is just like math. says, "give me a list of '[x]' for each > element 'x' in some-list" > The second says, "apply the vector operation to each element of some- > list and then make a vector of those." seems lower level, more > rudimentary. > > Thanks for all the help. This is great fun. > > On Jan 11, 12:07 pm, James Reeves <weavejes...@googlemail.com> wrote: > > > Thinking functionally is hard when you're used to programming > > imperatively. So instead of leaping straight into Clojure, lets stick > > with Python for the time being. > > > So let's take your Python code: > > > def msort(someList): > > myList = [[x] for x in someList] > > while len(myList) > 1: > > l1 = myList.pop(0) > > l2 = myList.pop(0) > > listmerge = some_merge_function(l1, l2) > > myList.append(listmerge) > > return myList[0] > > > (I'm assuming you meant msort(someList) and not msort(myList)) > > > Remove all functions and methods that change their arguments, and > > replace them with equivalent assignments: > > > def msort(someList): > > myList = [[x] for x in someList] > > while len(myList) > 1: > > l1 = myList[0] > > l2 = myList[1] > > myList = myList[2:] > > listmerge = some_merge_function(l1, l2) > > myList = myList + [listmerge] > > return myList[0] > > > Next we need to turn the while loop into a recursive function. We can > > do this by identifying what the while loop changes (myList), and then > > using that as the function's input and output: > > > def msort(someList): > > myList = [[x] for x in someList] > > def recursive_loop(myList) > > if len(myList) > 1: > > l1 = myList[0] > > l2 = myList[1] > > myList = myList[2:] > > listmerge = some_merge_function(l1, l2) > > myList = myList + [listmerge] > > myList = recursive_loop(myList) > > return myList > > else: > > return myList > > return recursive_loop(myList)[0] > > > Once you've replaced mutable functions and methods with assignments, > > and replaced loops with recursive functions, you can convert your code > > into Clojure: > > > (defn msort [some-list] > > (let > > [my-list (vec (map vector some-list)) > > recursive-loop > > (fn [my-list] > > (if (> (count my-list) 1) > > (let [l1 (my-list 0) > > l2 (my-list 1) > > my-list (rest (rest my-list)) > > list-merge (some-merge-function l1 l2) > > my-list (conj my-list listmerge) > > my-list (recursive-loop my-list)] > > my-list) > > my-list))] > > ((recursive-loop my-list) 0))) > > > Now we have a functional program, it's time to start taking advantage > > of all the nice Clojure functions and macros. Let's start with the > > loop/recur form, which we can use to replace the recursive-loop > > function: > > > (defn msort [some-list] > > (loop [my-list (vec (map vector some-list))] > > (if (> (count my-list) 1) > > (let [l1 (my-list 0) > > l2 (my-list 1) > > my-list (rest (rest my-list)) > > list-merge (some-merge-function l1 l2) > > my-list (conj my-list listmerge)] > > (recur my-list)) > > (my-list 0)))) > > > Clojure also supports destructuring binding in let forms, so lets use > > that: > > > (defn msort [some-list] > > (loop [my-list (vec (map vector some-list))] > > (if (> (count my-list) 1) > > (let [[l1 l2 & my-list] my-list > > list-merge (some-merge-function l1 l2) > > my-list (conj my-list list-merge)] > > (recur my-list)) > > (my-list 0)))) > > > And we can use rest to check if the list has more than one attribute: > > > (defn msort [some-list] > > (loop [my-list (vec (map vector some-list))] > > (if (rest my-list) > > (let [[l1 l2 & my-list] my-list > > list-merge (some-merge-function l1 l2) > > my-list (conj my-list list-merge)] > > (recur my-list)) > > (first my-list)))) > > > This could be neatened up a bit, but that's basically a functional > > version of your algorithm. > > > - James --~--~---------~--~----~------------~-------~--~----~ 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 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 -~----------~----~----~----~------~----~------~--~---