Hi all,
I wrote a bubble-sort program in clojure:

(defn bubble-sort
  [col]
  (letfn [(outter-loop
            [cc i]
            (if (< i 1)
              cc
              (letfn [(inner-loop
                        [c j]
                        (if (> j (- i 2))
                          c
                          (let [_1st (first c)
                                _2nd (second c)
                                others (rest (rest c))]
                            (if (> _1st _2nd)
                              (cons _2nd (inner-loop (cons _1st others)
(inc j)))
                              (cons _1st (inner-loop (cons _2nd others)
(inc j)))))))]
                (recur (inner-loop cc 0) (dec i)))))]
    (outter-loop col (count col))))

It works quite well, it could sort 1000 elements in no time.

and I also rewrite it to a tail-recursive version:

(defn bubble-sort-tail
  [col]
  ((fn
     [cc i]
     (if (< i 1)
       cc
       (let [inner-loop (fn
                          [c j rst]
                          (if (> j (- i 2))
                            (concat rst c)
                            (let [_1st (first c)
                                  _2nd (second c)
                                  others (rest (rest c))]
                              (if (> _1st _2nd)
                                (recur (cons _1st others) (inc j) (concat
rst [_2nd]))
                                (recur (cons _2nd others) (inc j) (concat
rst [_1st]))))))]
         (recur (inner-loop cc 0 []) (dec i)))))
    col (count col)))

But this tail-recursive version is very very slow, much slower than the
former one. And it also stack-overflows when the input is fairly large... I
don't understand why.

I also printed out a stack trace when it's running slowly, using 'jstack'
command, and the strange stack trace is here:

"nREPL-worker-0" daemon prio=10 tid=0x0000000001dc1000 nid=0x7b1b runnable
[0x00007f77de15a000]
   java.lang.Thread.State: RUNNABLE
at clojure.lang.RT.seqFrom(RT.java:482)
at clojure.lang.RT.seq(RT.java:477)
at clojure.core$seq.invoke(core.clj:133)
at clojure.core$concat$fn__3941.invoke(core.clj:678)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
- eliminated <0x00000000f5deac28> (a clojure.lang.LazySeq)
at clojure.lang.LazySeq.seq(LazySeq.java:60)
- locked <0x00000000f5deac28> (a clojure.lang.LazySeq)
at clojure.lang.RT.seq(RT.java:475)
at clojure.core$seq.invoke(core.clj:133)
at clojure.core$concat$fn__3941.invoke(core.clj:678)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
- eliminated <0x00000000f5deac80> (a clojure.lang.LazySeq)
at clojure.lang.LazySeq.seq(LazySeq.java:60)
- locked <0x00000000f5deac80> (a clojure.lang.LazySeq)
at clojure.lang.RT.seq(RT.java:475)
at clojure.core$seq.invoke(core.clj:133)
at clojure.core$concat$fn__3941.invoke(core.clj:678)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
- eliminated <0x00000000f5deacd8> (a clojure.lang.LazySeq)
at clojure.lang.LazySeq.seq(LazySeq.java:60)
- locked <0x00000000f5deacd8> (a clojure.lang.LazySeq)
at clojure.lang.RT.seq(RT.java:475)
at clojure.core$seq.invoke(core.clj:133)
at clojure.core$concat$fn__3941.invoke(core.clj:678)
......
......
......
many many more stack frames ignored....
        ......
......
......
at clojure.core$concat$fn__3941.invoke(core.clj:678)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
- eliminated <0x00000000f5def0e8> (a clojure.lang.LazySeq)
at clojure.lang.LazySeq.seq(LazySeq.java:60)
- locked <0x00000000f5def0e8> (a clojure.lang.LazySeq)
at clojure.lang.RT.seq(RT.java:475)
at clojure.core$seq.invoke(core.clj:133)
at clojure.core$concat$fn__3941.invoke(core.clj:678)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
- eliminated <0x00000000f5def140> (a clojure.lang.LazySeq)
at clojure.lang.LazySeq.seq(LazySeq.java:60)
- locked <0x00000000f5def140> (a clojure.lang.LazySeq)
at clojure.lang.RT.seq(RT.java:475)
at clojure.core$seq.invoke(core.clj:133)
at clojure.core$concat$fn__3941.invoke(core.clj:678)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
- eliminated <0x00000000f5def198> (a clojure.lang.LazySeq)
at clojure.lang.LazySeq.seq(LazySeq.java:60)
- locked <0x00000000f5def198> (a clojure.lang.LazySeq)
at clojure.lang.RT.seq(RT.java:475)
at clojure.core$seq.invoke(core.clj:133)
at clojure.core$concat$fn__3941.invoke(core.clj:678)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
- eliminated <0x00000000f5def1f0> (a clojure.lang.LazySeq)
at clojure.lang.LazySeq.seq(LazySeq.java:60)
- locked <0x00000000f5def1f0> (a clojure.lang.LazySeq)
at clojure.lang.RT.seq(RT.java:475)
at clojure.core$seq.invoke(core.clj:133)
at clojure.core$concat$fn__3941.invoke(core.clj:678)

It seems that the tail-recursive version also resulted in a very deep
recursion.
I think my program is nothing wrong in the algorithm itself. But why would
this happen? Any ideas?

Thanks!

-- 
Regards.
Yue . Wen

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to