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 -~----------~----~----~----~------~----~------~--~---