Nice TWiki > Doc > CodeExamples > VisitorPatternMultiMethodExample > FunctionalApproachExample (r1.4) TWiki webs:
Dev | Doc | Main | TWiki | Sandbox
Doc . { Changes | Index | Search | Go }
/* 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

Topic FunctionalApproachExample . { Edit | Attach | Ref-By | Printable | Diffs | r1.7 | > | r1.6 | > | r1.5 | More }
Revision r1.4 - 14 Feb 2004 - 21:04 GMT - IsaacGouy
Parents: WebHome > CodeExamples > VisitorPatternMultiMethodExample
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.

Doc.FunctionalApproachExample moved from Doc.FunctionalReuseExample on 06 Feb 2004 - 15:57 by IsaacGouy - put it back