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