# [plt-scheme] Do no evil

 From: Robby Findler (robby at eecs.northwestern.edu) Date: Mon Mar 8 10:53:44 EST 2010 Previous message: [plt-scheme] Do no evil Next message: [plt-scheme] Do no evil Messages sorted by: [date] [thread] [subject] [author]

```I tried to find that quote, but didn't find anything better than what
it says in the "in practice" section of Wikipedia.

(And, of course, we are in a loop here, but this is a new piece of
information related to the loop-- I don't mean for us to cover any old

Robby

On Mon, Mar 8, 2010 at 9:47 AM, Matthias Felleisen <matthias at ccs.neu.edu> wrote:
>
> Knuth wrote this up in the 1960s. Anyone who teaches bubble sort
> in the 20xy is teaching 1970s computer science. But I think I am
> now in some kind of loop with wooks.
>
>
>
>
> On Mar 8, 2010, at 10:44 AM, Robby Findler wrote:
>
>> Continuing my contrarianocity: When I was taught the bubble sort, I
>> wish that my teacher had taken the time to explain bubble sort's place
>> in the pantheon of sorting algorithms (there is essentially no metric
>> under which it better than some other sort, with the possible
>> exception of ease of implementation in Fortran 70).
>>
>> Robby
>>
>> On Mon, Mar 8, 2010 at 9:39 AM, Matthias Felleisen <matthias at ccs.neu.edu>
>> wrote:
>>>
>>> I have taken Veer's understanding to derive a relatively short
>>> form of bubble sort in the plain Scheme language:
>>>
>>> (define (bsort v)
>>>  (define (sweep v i clean?)
>>>   (cond
>>>     [(= i (- n 1)) (if clean? v (sweep v 0 true))]
>>>     [else (if (<= (vector-ref v i) (vector-ref v (+ i 1)))
>>>               (sweep v (+ i 1) clean?)
>>>               (sweep (swap v i) (+ i 1) false))]))
>>>  (define n (vector-length v))
>>>  ;; IN
>>>  (sweep v 0 true))
>>>
>>> ;; swap: factored out as suggested by Noel,
>>> ;; do it with build-vector and weep! bubble
>>> ;; demos how bad FP's performance can be :-)
>>>
>>> But I have done so in ASL just to demonstrate that it is feasible.
>>>
>>> the array until there are no more out of place items left. Then
>>> you're done. Then you 'edit' the program with two observation.
>>> If you were in #lang scheme, you'd come up with the above
>>>
>>> The derivation is appended below. -- Matthias
>>>
>>>
>>>
>>> ;; [Vec Number] -> [Vec Number]
>>> ;; create a sorted version of v
>>> ;; effect: modify v
>>> (define (bsort.v0 v)
>>>  (local (;; Result = (list [Vec Number] Boolean)
>>>
>>>         ;; [Vec Number] -> [Vec Number]
>>>         ;; (effect) create a sorted version of v
>>>         ;; generative recursion: swap-all until nothing to swap anymore
>>>         ;; termination: there are only a finite number of swaps
>>>         (define (generative-driver v)
>>>           (local ((define v+flag (sweep v))
>>>                   (define newv   (first v+flag))
>>>                   (define clean? (second v+flag)))
>>>             (if clean? v (generative-driver v))))
>>>
>>>         ;; [Vec Number] -> Result
>>>         ;; (effect) swap all out of place neighbors throughout vector
>>>         (define (sweep v)
>>>           (local (;; [Vec Number] N Boolean -> Result
>>>                   ;; accumulators: [0,i) is bubbled -- clean? no swaps so
>>> far
>>>                   (define (sweep v i clean?)
>>>                     (cond
>>>                       [(= i (- (vector-length v) 1)) (list v clean?)]
>>>                       [else (if (<= (vector-ref v i) (vector-ref v (+ i
>>> 1)))
>>>                                 (sweep v (+ i 1) clean?)
>>>                                 (sweep (swap v i) (+ i 1) false))])))
>>>             (sweep v 0 true))))
>>>   ;; IN
>>>   (generative-driver v)))
>>>
>>> ;; fold the geneative-driver into the sweep function
>>> ;; observation: the base case packages up the result,
>>> ;; which is immediately unfolded and used for another call
>>>
>>> (define (bsort.v1 v)
>>>  (local (;; [Vec Number] -> [Vec Number]
>>>         ;; (effect) swap all out of place neighbors throughout vector
>>>         (define (sweep v)
>>>           (local (;; [Vec Number] N Boolean -> Result
>>>                   ;; accumulators: [0,i) is bubbled -- clean? no swaps so
>>> far
>>>                   (define (sweep v i clean?)
>>>                     (cond
>>>                       [(= i (- (vector-length v) 1))
>>>                        (if clean? v (sweep v 0 true))]
>>>                       [else (if (<= (vector-ref v i) (vector-ref v (+ i
>>> 1)))
>>>                                 (sweep v (+ i 1) clean?)
>>>                                 (sweep (swap v i) (+ i 1) false))])))
>>>             (sweep v 0 true))))
>>>   ;; IN
>>>   (sweep v)))
>>>
>>> ;; eliminate the indirection from 1-ary sweep through 1-ary sweep
>>> ;; lift the vector-length computation
>>>
>>> (define (bsort v)
>>>  (local (;; [Vec Number] N Boolean -> Result
>>>         ;; accumulators: [0,i) is bubbled -- clean? no swaps so far
>>>         (define (sweep v i clean?)
>>>           (cond
>>>             [(= i (- n 1)) (if clean? v (sweep v 0 true))]
>>>             [else (if (<= (vector-ref v i) (vector-ref v (+ i 1)))
>>>                       (sweep v (+ i 1) clean?)
>>>                       (sweep (swap v i) (+ i 1) false))]))
>>>         ;; where
>>>         (define n (vector-length v)))
>>>   ;; IN
>>>   (sweep v 0 true)))
>>>
>>> ;;
>>>
>>> -----------------------------------------------------------------------------
>>> ;; auxiliaries
>>>
>>> ;; [Vec Number] N -> [Vec Number]
>>> ;; swap items i and i+1 in v
>>> (define (swap v i)
>>>  (local ((define v at i (vector-ref v i)))
>>>   (begin
>>>     (vector-set! v i (vector-ref v (+ i 1)))
>>>     (vector-set! v (+ i 1) v at i)
>>>     v)))
>>>
>>> ;;
>>>
>>> -----------------------------------------------------------------------------
>>> ;; tests
>>>
>>> (define (generate-test) (vector 3 1 9 8 5 6 7 0 4 2))
>>> (define swapped0 (vector 1 3 9 8 5 6 7 0 4 2))
>>> (define swapped2 (vector 3 1 8 9 5 6 7 0 4 2))
>>> (define sorted (vector 0 1 2 3 4 5 6 7 8 9))
>>>
>>> (check-expect (swap (generate-test) 0) swapped0)
>>> (check-expect (swap (generate-test) 2) swapped2)
>>>
>>> (check-expect (bsort (generate-test)) sorted)
>>>
>>> _________________________________________________