rwaldhoff    2003/03/31 10:21:52

  Modified:    functor/xdocs examples.xml
               functor/src/test/org/apache/commons/functor/example
                        QuicksortExample.java
  Log:
  minor changes to examples
  
  Revision  Changes    Path
  1.3       +6 -4      jakarta-commons-sandbox/functor/xdocs/examples.xml
  
  Index: examples.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/functor/xdocs/examples.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- examples.xml      12 Mar 2003 21:08:16 -0000      1.2
  +++ examples.xml      31 Mar 2003 18:21:52 -0000      1.3
  @@ -80,15 +80,17 @@
            </p>
            <p>
               The 
  -            <a 
href="xref-test/org/apache/commons/functor/example/FlexiMapExample.html#88">FlexiMap</a>
 
  -            example applies this design to <code>java.util.Map</code>, 
demonstrating how 
  +            <a 
href="xref-test/org/apache/commons/functor/example/FlexiMapExample.html#88">FlexiMap 
example</a> 
  +            applies this design to <code>java.util.Map</code>, demonstrating how 
               "pluggable" functors can be applied to a generic <code>Map</code> 
structure in order
               to introduce new behaviors.           
            </p>
         </subsection>      
  -      <subsection name="A Functional Quicksort Implementation">
  +      <subsection name="A Quicksort Implementation">        
           <p>
  -          See the <a 
href="xref-test/org/apache/commons/functor/example/QuicksortExample.html#79">Quicksort</a>
 example.
  +          The <a 
href="xref-test/org/apache/commons/functor/example/QuicksortExample.html#79">Quicksort 
example</a>
  +          presents an implementation of the Quicksort sorting algorithm written in 
a functional programming
  +          style using Commons Functor.
           </p>
         </subsection>      
       </section>
  
  
  
  1.3       +160 -51   
jakarta-commons-sandbox/functor/src/test/org/apache/commons/functor/example/QuicksortExample.java
  
  Index: QuicksortExample.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/functor/src/test/org/apache/commons/functor/example/QuicksortExample.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- QuicksortExample.java     12 Mar 2003 21:08:16 -0000      1.2
  +++ QuicksortExample.java     31 Mar 2003 18:21:52 -0000      1.3
  @@ -342,13 +342,92 @@
           System.out.println();
       }
   
  +
   /*
  - * BUILDING BLOCKS:
  + * THE QUICKSORT ALGORITHM:
    * ----------------------------------------------------------------------------
  + */
  +
  +/*
  + * Our quicksort method will invoke a UnaryFunction named
  + * quicksort:
  + */
  + 
  +    public List quicksort(List list) {
  +        return (List)(quicksort.evaluate(list));
  +    }
  +
  +/*
  + * The quicksort sorting algorithm can be summarized as follows:
  + * 
  + * Given a list of elements to be sorted:
  + * 
  + * A) If the list is empty, consider it already sorted.
  + * 
  + * B) If the list is non-empty, we can sort it by first splitting it into 
  + *   three lists:
  + *     1) one list containing only the first element in the list (the "head")
  + *     2) one (possibly empty) list containing every element in the remaining
  + *        list that is less than the head
  + *     3) one (possibly empty) list containing every element in the remaining
  + *        list that is greater than or equal to the head
  + *    applying the quicksort algorithm recursively to the second and third lists,
  + *    and joining the results back together as (2) + (1) + (3).
  + */
  +
  +/*
  + * Using a functional style (or at least a semi-functional style), it's easy
  + * to transalate this description directly into code:
  + */
  +
  +    private UnaryFunction quicksort = new ConditionalUnaryFunction(
  +        /* if the list is empty... */
  +        IsEmpty.getIsEmpty(),
  +        /* ...then return an empty list... */     
  +        new ConstantFunction(Collections.EMPTY_LIST), 
  +        /* ...else, apply the following function... */
  +        new ListFunction() {                                   
  +            public Object evaluate(List list) {
  +                /* Create a list to contain the results. */
  +                List result = new ArrayList(list.size());
  +                /* 
  +                 * Recursively apply quicksort the the elements in the
  +                 * tail less than the head, adding the result to the
  +                 * sorted list we're generating.
  +                 */
  +                result.addAll(
  +                    (List)quicksort.evaluate(
  +                        lesserTail.evaluate(
  +                            head.evaluate(list), 
  +                            tail.evaluate(list))));
  +                /* 
  +                 * Add the head to the sorted list we're generating.
  +                 */
  +                result.add(head.evaluate(list));
  +                /* 
  +                 * Recursively apply quicksort the the elements in the
  +                 * tail greater than the head, adding the result to the
  +                 * sorted list we're generating.
  +                 */
  +                result.addAll(
  +                    (List)quicksort.evaluate(
  +                        greaterTail.evaluate(
  +                            head.evaluate(list), 
  +                            tail.evaluate(list))));
  +                /* 
  +                 * And return the generated list.
  +                 */
  +                return result;
  +            }
  +    });
  +
  +/*
  + * Now let's look at the building blocks we need to flesh out that 
  + * function.
  + * 
  + * First, let's save ourselves some casting and error handling by
  + * definining some functor sub-types.
    * 
  - * Let's save ourselves some casting and error checking by defining
  - * functor subclasses that deal with java.util.List.
  - *
    * Let ListFunction be a UnaryFunction that operates on Lists:
    */
   
  @@ -372,7 +451,7 @@
    * Let ObjectListFunction be a BinaryFunction that operates on 
    * an Object, List pair:
    */
  -
  + 
       public abstract class ObjectListFunction implements BinaryFunction {
           public abstract Object evaluate(Object head, List tail);
   
  @@ -391,30 +470,8 @@
           }
       }
   
  -/*
  - * THE QUICKSORT ALGORITHM:
  - * ----------------------------------------------------------------------------
  - * 
  - * The quicksort sorting algorithm can be summarized as follows:
  - * 
  - * Given a list of elements to be sorted:
  - * 
  - * A) If the list is empty, consider it already sorted.
  - * 
  - * B) If the list is non-empty, we can sort it by first splitting it into 
  - *   three lists:
  - *     1) one list containing only the first element in the list (the "head")
  - *     2) one (possibly empty) list containing every element in the remaining
  - *        list that is less than the head
  - *     3) one (possibly empty) list containing every element in the remaining
  - *        list that is greater than or equal to the head
  - *    applying the quicksort algorithm recursively to the second and third lists,
  - *    and joining the results back together as (2) + (1) + (3).
  - * 
  - */
  -
   /* 
  - * Let's define functors for the operations we'll need.
  + * Now for the implementations.
    * 
    * Given a List, we need to be able to break it into its head:
    */
  @@ -467,29 +524,81 @@
           }
       };
   
  -/* 
  - * With these building blocks, our quicksort function is a 
  - * straightfoward application of the description above.
  +/*
  + * Note that each of these smaller functors is readily testable
  + * in isolation:
    */
  -    private UnaryFunction quicksort = new ConditionalUnaryFunction(
  -        IsEmpty.getIsEmpty(),                         /* If the list is empty, */
  -        new ConstantFunction(Collections.EMPTY_LIST), /*  then return an empty 
list, */
  -        new ListFunction() {                          /*  else, split and recurse */
  -        public Object evaluate(List list) {
  -            List result = new ArrayList(list.size());
  -            Object h = head.evaluate(list);
  -            Object t = tail.evaluate(list);
  -            result.addAll((List)quicksort.evaluate(lesserTail.evaluate(h, t)));
  -            result.add(h);
  -            result.addAll((List)quicksort.evaluate(greaterTail.evaluate(h, t)));
  -            return result;
  + 
  +    public void testHeadFunction() {
  +        List list = new ArrayList();
  +        try {
  +            head.evaluate(list);
  +            fail("Expected IndexOutOfBoundsException when evaluating head of an 
empty list");
  +        } catch(IndexOutOfBoundsException e) {
  +            // expected
           }
  -    });
  +        
  +        list.add("First");
  +        assertEquals("First",head.evaluate(list));
  +
  +        list.add("Second");
  +        assertEquals("First",head.evaluate(list));
  +        
  +    }
  +    
  +    public void testTailFunction() {
  +        List list = new ArrayList();
  +        {
  +            List result = (List)(tail.evaluate(list));
  +            assertTrue("Tail of an empty list is empty.",result.isEmpty()); 
  +        }
  +        list.add("First");
  +        {
  +            List result = (List)(tail.evaluate(list));
  +            assertTrue("Tail of a one element list is empty.",result.isEmpty()); 
  +        }
  +        list.add("Second");
  +        {
  +            List result = (List)(tail.evaluate(list));
  +            assertEquals("Tail of a two element list has one 
element.",1,result.size());
  +            assertEquals("Second",result.get(0)); 
  +        }
  +        list.add("Third");
  +        {
  +            List result = (List)(tail.evaluate(list));
  +            assertEquals("Tail of a three element list has two 
elements.",2,result.size());
  +            assertEquals("Second",result.get(0)); 
  +            assertEquals("Third",result.get(1)); 
  +        }
  +    }
   
  -/*
  - * Finally, our quicksort method simply invokes the UnaryFunction:
  - */
  -    public List quicksort(List list) {
  -        return (List)(quicksort.evaluate(list));
  +    public void testLesserTail() {
  +        List list = new ArrayList();
  +        for(int i=0;i<10;i++) {
  +            list.add(new Integer(i));
  +        }
  +        for(int i=0;i<10;i++) {
  +            Integer val = new Integer(i);
  +            List lesser = (List)lesserTail.evaluate(val,list);
  +            assertEquals(i,lesser.size());
  +            for(int j=0;j<i;j++) {
  +                assertEquals(new Integer(j),lesser.get(j));
  +            }
  +        }
  +    }
  +
  +    public void testGreaterTail() {
  +        List list = new ArrayList();
  +        for(int i=0;i<10;i++) {
  +            list.add(new Integer(i));
  +        }
  +        for(int i=0;i<10;i++) {
  +            Integer val = new Integer(i);
  +            List greater = (List)greaterTail.evaluate(val,list);
  +            assertEquals(10-i,greater.size());
  +            for(int j=i;j<10;j++) {
  +                assertEquals(new Integer(j),greater.get(j-i));
  +            }
  +        }
       }
   }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to