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

Reply via email to