TWiki . Doc . FunctionalApproachExample

/* Please try the NoviceExamples before the MultiMethodExamples
To compile:
   nicec --sourcepath .. -a functional.jar functional
To run:
   java -jar functional.jar
*/


// Functional Approach: Types
//---------------------------

abstract class Shape {}
class Square extends Shape { double side; }
class Circle extends Shape { double radius; }
class Translated extends Shape { Point d; Shape shape; }

class Point { double x; double y; }



// Functional Approach: Operations
//--------------------------------

boolean containsPoint(Shape s, Point p);

containsPoint(Square s, p){
   let d = s.side/2;

   return 
      (p.x >= -d && p.x < d) && 
      (p.y >= -d && p.y < d);
}

containsPoint(Circle s, p) = 
   // just test the bounding box     
   (p.x >= -s.radius && p.x < s.radius) && 
   (p.y >= -s.radius && p.y < s.radius);


containsPoint(Translated s, p){
   let p' = 
      new Point(
         x: p.x - s.d.x,
         y: p.y - s.d.y );
 
   return s.shape.containsPoint(p');
}



/*
   =================================================
   Can we add a type and operation without modifying 
   the original code?
   ================================================= 
*/


// Functional Approach: Adding Type Variants
//------------------------------------------

/* 
   Generally, in a functional approach we would
   need to modify the original source code.
*/ 


// Functional Approach: Adding Operations
//---------------------------------------

Shape shrink(Shape s, double toPercent);

shrink(Square s, toPercent) = 
   new Square(side: (s.side*toPercent)/100 );

shrink(Circle s, toPercent) = 
   new Circle(radius: (s.radius*toPercent)/100 );

shrink(Translated s, toPercent) = 
   new Translated(d: s.d, shape: s.shape.shrink(toPercent) );



// Functional Approach: Testing
//-----------------------------

void main(String[] args){
   let s = new Square(side: 4);
   let c = new Circle(radius: 2);

   let t = 
      new Translated(
         d: new Point(x: 1.5, y: 0),  
         shape: c 
         );

   let p = new Point(x: 3, y: 0);
   println("square contains point " + s.containsPoint(p));
   println("circle contains point " + c.containsPoint(p));
   println("translated contains point " + t.containsPoint(p));

   let t' = t.shrink(toPercent: 50); 
   println("shrunk translated contains point " + t'.containsPoint(p));
}


/* Notes 
See the detailed discussion in
"Synthesizing Object-Oriented and Functional Design to Promote Re-use"
Section 2.1 figures 1, 2, 3
http://citeseer.nj.nec.com/krishnamurthi98synthesizing.html


square contains point false
circle contains point false
translated contains point true
shrunk translated contains point false

*/
-- IsaacGouy - 06 Feb 2004

----- Revision r1.7 - 28 Apr 2005 - 11:50 GMT - TWikiGuest
Copyright © 1999-2003 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback.