4
\$\begingroup\$

I wrote the following Forth code for sorting a string with the Bubble Sort method.

It looks nice to my eyes, but I'd like your experienced opinion and any comments about the code you might have.

  1. In the compare-and-swap-next word, is using the return stack to save base address of string ok?
  2. the bubblesort word uses 2 pick which is not so bad? A previous version had 5 pick (!), anyway ... is 2 pick fine: don't overthink about that or maybe try some more refactoring?
  3. How would I go about adding a check for any swaps in each round and terminate the sort early? A variable? A stack cell (on TOS)? Rethink all of the implementation?
: compare-and-swap-next ( string i -- )
   2dup + dup >r c@ rot rot 1 + + c@ 2dup >
   if     r@ c! r> 1 + c!
   else   r> drop 2drop
   then ;

: bubblesort ( string len -- string len )
   dup 1 -
   begin  dup 0>
   while  dup 0
          do   2 pick i compare-and-swap-next
          loop
          1 -
   repeat
   drop ;

\ s" abracadabra" bubblesort \ cr type
\ s" The quick brown fox" bubblesort \ cr type
\ s" a quick brown fox jumps over the lazy dog." bubblesort \ cr type

Code available on github

Nitpicks welcome! Pedantism welcome!
Thank you!

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

To address your immediate concerns,

  1. Using the return stack for storing your temporaries is a perfectly valid technique.

  2. pick is always frown upon (as well as tuck, roll, and friends). It seems that the len parameter to bubblesort does not participate in computation - except the very beginning - and mostly just stays in the way. Consider

     : bubblesort
         dup >r 1-
         ....
    

and use over instead of 2 pick (don't forget to r> the length at the end).


I prefer a slightly different formatting of conditional. Consider

2dup > if     
    r@ c! r> 1 + c!  else   
    r> drop 2drop then ;

Same for the loops. Consider

: bubblesort ( string len -- string len )
    dup 1 - begin 
    dup 0> while
        dup 0 do                                      
            2 pick i compare-and-swap-next               
        loop
        1 -                                     
    repeat
drop ;

Keeping control words together with their respective conditions/actions looks more Forthy for me.


r> drop is also known as rdrop.

rot rot is also known as -rot.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.