Top Banner
Multimethods Itay Maman Demo
43

Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

Dec 20, 2015

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

Multimethods

Itay Maman

Demo

Page 2: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

2

Multimethods (1/2)

A dynamic-dispatch mechanism The executed method is selected by

the dynamic type of one (or more) argument(s)

virtual methods in Java/C++ are all “SingleMethods”

Related terms: Multi-dispatch Binary-dispatch

Page 3: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

3

Multimethods (2/2)

Single-method dispatching as a mapping: (t, mid) -> mp

t - The dynamic type of the receiver mid – Method id mp – Pointer to selected method

Multimethod dispatching: (t1, t2, … tn, mid) -> mp

Page 4: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

4

The many faces of Multimethods

Design decision (responsibilities of classes)

Aspects Compilation techniques + runtime

system Programming language

Expected to be highly popular

Page 5: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

5

Motivation

The bouncing ball simulation: A 2d plain with walls Two kinds of walls: Blue, Yellow Two kinds of balls: Red, Green Collision rules

Red ball hits a Blue wall – changes direction Red ball hits a Yellow wall – Stops moving Green ball hits a Blue wall – changes

direction + looses speed Green ball hits a Yellow wall – wall

disappears

Page 6: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

6

Motivation

The OO model: Vector of Balls, Walls Abstract class Wall

Maintains location, color Has an active/not active flag Two direct sub-classes: WallX, WallY StickyWallX is a sub-class of WallX

Class Ball Maintains location, color Maintains vx, vy (velocity in each axis) One sub-class: PowerBall

Page 7: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

7

Motivation – Wall

// file: Wall.javapublic abstract class Wall { private Rectangle rect_; private Color color_; public boolean active_ = true;

public Wall(int x, int y, int w, int h, Color color) { color_ = color; rect_ = new Rectangle(x, y, w, h); } public void draw(Graphics g) { if(!active_) return; g.setColor(color_); g.fillRect(rect_.x, rect_.y, rect_.width, rect_.height); } public boolean contains(double x, double y) { return active_ && rect_.contains((int) x, (int) y); }}

Page 8: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

8

Motivation – Ball

// file: Ball.javapublic class Ball { private static double chooseVelocity() { .. } public double vx_ = chooseVelocity(); public double vy_ = chooseVelocity(); public double x_ = 50; public double y_ = 50; public Color color_ = Color.RED;

public void draw(Graphics g) { g.setColor(color_); g.fillArc((int) x_ - 5, (int) y_ - 5, 10, 10, 0, 360); }

public void move() { x_ += vx_; y_ += vy_; }}

Page 9: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

9

Motivation – The catch (1/2)

// Precondition: // w.contains(b.x_, b.y_) == true//// Postcondition:// The state of b, w has changed according// to the simulation’s collision rules//void collision(Wall w, Ball b) { // ? ? ? ? // ? ? ? ?}

This function/method should implement the “collision rules”

A plain virtual method will not do

Page 10: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

10

Motivation – The catch (2/2)

The collision rules depend on the dynamic type of TWO objects: Formal argument w (static type: Wall) Formal argument b (static type: Ball)

At least two relevant classes: Wall, Ball No obvious class to place the code at

Solution 1: Use instanceof Solution 2: Use the “visitor” hack

Page 11: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

11

Motivation – solution 1

void collision(Wall w, Ball ball) { if(w instanceof WallX) { if(ball instanceof Ball) b.vy_ *= -1; else if(ball instanceof PowerBall) b.vy_ *= -0.9; } if(w instanceof WallY) { if(ball instanceof Ball) b.vx_ *= -1; else if(ball instanceof PowerBall) b.vx_ *= -0.9; } if(w instanceof StickyWallX) { if(ball instance of Ball) b.vy_ = b.vx_ = 0; else if(ball instnaceof PowerBall) w.active_ = false; } }

Pros: Code is located in one place

Cons: A Complex chain of if-else

No alert if a case was not handled

No alert if we change the hierarchy

Order is significant

Page 12: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

12

Motivation – solution 2

// file: WallX.javavoid hit(Ball b) { b.vy_ *= -1; }void hit(PowerBall b) { b.vy_ *= -0.9; }

// file: StickyWallX.javavoid hit(Ball b) { b.vx_ = b.vy_ = 0; }void hit(PowerBall b) { active_ = false; }

// file: BouncingBallDemo.javavoid collision(Wall w, Ball b) { b.collide(w); }

// file: Wall.javaclass Wall { .. abstract void hit(Ball b); abstract void hit(PowerBall pb);}

// file: Wall.javaclass Wall { .. abstract void hit(Ball b); abstract void hit(PowerBall pb);}

// file: Ball.javavoid collide(Wall w) { w.hit(this); }

// file: PowerBall.javavoid collide(Wall w) { w.hit(this); }

Page 13: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

13

Motivation – solution 2 (cont’d)

Pros:Order is less significantSome compiler alerts

Cons:Code is highly scatteredReduced cohesion, increased couplingMany methods must be implemented

Page 14: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

14

Motivation – A Nicer solution

// file: BouncingBallDemo.nicevoid collision(Wall w, Ball b);

collision(WallX w, Ball b) { b.vy_ *= -1; }collision(WallY w, Ball b) { b.vx_ *= -1; }collision(StickyWallX w, Ball b) { b.vx_ = b.vy_ = 0; }collision(WallX w, PowerBall b) { b.vy_ *= -0.9; }collision(WallY w, PowerBall b) { b.vx_ *= -0.9; }collision(StickyWallX w, PowerBall b) { w.active_ = false; }

Page 15: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

15

Questions

Where (in the source code) can a multimethod be defined? Just like a virtual method? File scope? Within a dedicated class?

Does a multimethod have a “this” reference? Policy for selecting the “best” match Implementation

Much more complicated than a virtual method dispatch

Page 16: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

16

MultiJava (1/2)

Clifton, Leavens, Chambers, Millstein First presented at OOPSLA 2000

Available at: http://multijava.sourceforge.net

Currently working on various enhancements

Page 17: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

17

MultiJava (2/2)

An extension to Java A legal Java program is also a MultiJava

program Compilation/execution

The MultiJava compiler replaces javac Produces standard .class files No linking phase Any standard JVM can run the program

Excluding J2SE 5.0

Page 18: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

18

MultiJava – example 1

public class Shape { public String both(Shape s) { return "s-s"; } public String both(Shape@Rect r) { return "s-r"; }} public class Rect extends Shape { public String both(Shape s) { return "r-s"; } public String both(Shape@Rect r) { return "r-r"; }} public static void main(String args[]) { Shape s = new Shape(); Shape r = new Rect(); System.out.println(s.both(s)); System.out.println(s.both(r)); System.out.println(r.both(s)); System.out.println(r.both(r)); }

“s-s”“s-r”“r-s”“r-r”

Page 19: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

19

MultiJava – example 2

public static class Shape { } // file: Shape.javapublic static class Rect extends Shape { } // file: Rect.java

// file: something.java public static String both(Shape s1, Shape s2) { return "s-s"; }public static String both(Shape s, Shape@Rect r) { return "s-r"; } public static String both(Shape@Rect r, Shape s) { return "r-s"; }public static String both(Shape@Rect r1, Shape@Rect r2) { return "r-r"; } public static void main(String args[]) { Shape s = new Shape(); Shape r = new Rect(); System.out.println(both(s,s)); System.out.println(both(s,r)); System.out.println(both(r,s)); System.out.println(both(r,r)); }

“s-s”“s-r”“r-s”“r-r”

Page 20: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

20

Nice (1/2)

Bonniot, Keller, Barber Not an academic work Mentioned in several articles (Scala) Available at: http://nice.sourceforge.net

A java-like programming language Not an extension of Java Paradigms: OO, Functional

Page 21: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

21

Nice (2/2)

Besides multimethods, offers additional features: Functions are 1st class values, anonymous functions Tuples Generics Named parameters Limited inference

Compilation/Execution The compiler (nicec) produces executables (jar

files) Any standard JVM can run the program

Has a linking phase Compilation unit: package

Page 22: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

22

Nice – example 1

public class Shape { }public class Rect extends Shape { }

String both(Shape a1, Shape a2) { return "s-s"; }both(Shape a1, Rect a2) { return "s-r"; }both(Rect a1, Shape a2) { return "r-s"; }both(Rect a1, Rect a2) { return "r-r"; }

public void main(String[] args) { Shape s = new Shape(); Shape r = new Rect(); System.out.println(both(r,s));}

“r-s”

Page 23: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

23

Nice – example 2

No need to implement both(Shape, Shape) Q: How is it possible? A: Linking

Dispatching is checked at link-time

public abstract class Shape { } public class Rect extends Shape { }

String both(Shape a1, Shape a2);both(Shape a1, Rect a2) { return "s-r"; }

public void main(String[] args) { Shape r1 = new Rect(); Shape r2 = new Rect(); System.out.println(both(r1,r2));}

“s-r”

Page 24: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

24

Nice – example 3

This code will not compile !! Pattern matching is incomplete:

E.g.: both(Circle,Circle) is not handled

public abstract class Shape { } public class Rect extends Shape { }public class Circle extends Shape { }

String both(Shape a1, Shape a2);both(Shape a1, Rect a2) { return "s-r"; }

Let’s add a circle class to the last program..

Page 25: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

25

Nice – Methods vs. Functions

Two equivalent forms for method/function invocation x.f(y,z) f(x,y,z)

Every file-scope function is also a method But, there is no “this” in file-scope functions

public class Rect { int w = 0; int h = 0; public int area() { return w * h; }}public void set(Rect r, int w, int h) { r.h = h; r.w = w; }

public void main(String[] args) { Rect r = new Rect(); r.set(10,10); System.out.println(r.area()); set(r,10,20); System.out.println(area(r));}

Page 26: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

26

Consequences

(We will use Nice for most code samples)

Page 27: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

27

Open classes

=> Full support for “Open classes” Any class can be expanded

public void show(Object o) { System.out.println(‘<‘ + o.getClass() + ":" + o + ‘>‘);}

public void main(String[] args) { String s = "abc"; s.show(); }

Let’s define a function with an Object argument

“<class java.lang.String:abc>”

Page 28: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

28

Playing with two arguments

public class Printer { void show(Object o) { // *1* System.out.println("Hashcode=" + o.hashCode()); }}

public class StringPrinter extends Printer { void show(String s) { // *2* System.out.println("Len=" + s.length()); }}

Printer.show() displays the hash-code of an Object StringPrinter.show()displays the length of a String

public void main(String[] args) { Printer p = new StringPrinter();

p.show(new java.util.Date()); // Invokes *1* p.show("abc"); // Nice: Invokes *2*. Java: Invokes *1*}

Page 29: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

29

“Best match” policy

String both(Shape a1, Shape a2) = "s-s"; // *1*both(Rect a1, Shape a2) = "r-s"; // *2*both(Shape a1, Circle a2) = "s-c"; // *3*

both(new Rect(), new Circle()); // Invokes ???

Which implementation is invoked? Asymmetric multimethods: *2*

Order of parameters is significant Not intuitive

Symmetric multimethods: None (compiler error) Order is insignificant May yield ambiguity (see the above sample) Used by MultiJava, Nice

Page 30: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

30

Implementation

The magic behind multimethods..

Page 31: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

31

Reminder: Java’s single-dispatch

Each class has a dispatch table with N entries Created by the compiler N – Number of “messages” the class can receive Each entry specifies the “address” of the relevant

method When the .class file is generated, N is known

In multimethods: N is not known

Page 32: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

32

MultiJava – Implementation (1/2)

// file: something.java public static String both(Shape s1, Shape s2) { return "s-s"; }public static String both(Shape s, Shape@Rect r) { return "s-r"; } public static String both(Shape@Rect r, Shape s) { return "r-s"; }public static String both(Shape@Rect r1, Shape@Rect r2) { return "r-r"; }

public class both$20 { public static void apply(Shape s1, Shape s2) { if(s1 instanceof Rect && s2 instanceof Rect)

return "r-r"; if(s1 instanceof Rect && s2 instanceof Shape)

return "r-s"; if(s1 instanceof Shape && s2 instanceof Rect)

return "s-r"; if(s1 instanceof Shape && s2 instanceof Shape)

return "s-s"; }}

Page 33: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

33

MultiJava – Implementation (2/2)

both$20 is a “Generic Function class” Provides the multi-dispatching functionality

Generated automatically by the compiler In the previous example, both$20 is generated for both(Shape, Shape)

Is used for all versions of both() which are a specialization of both(Shape, Shape)

Call site translation by the compiler: Translates multimethod calls to invocations of apply()

on the proper generic function class both(..) is converted to: both$20.apply(..)

Q: Drawbacks?

Page 34: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

34

MultiJava – the flaw Splitting the definition

Let’s define both() in two compilation units: Something.java, SomethingElse.java

public static class Shape { } // file: Shape.javapublic static class Rect extends Shape { } // file: Rect.java

// file: Something.java public static String both(Shape s1, Shape s2) { return "s-s"; }public static String both(Shape s, Shape@Rect r) { return "s-r"; }

// file: SomethingElse.javapublic static String both(Shape@Rect r, Shape s) { return "r-s"; }public static String both(Shape@Rect r1, Shape@Rect r2) { return "r-r"; }

This code will NOT compile The compiler will not regenerate the generic function class Separate compilation principle

Page 35: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

35

Nice – the flaw Implementation of multimethods in Nice:

Multimethod dispatching code is created during linking

All declared types are known at link-time Thus, Pattern-matching can make sure all cases are

handled Q: Where is the flaw?

public abstract class Shape { }public class Rect extends Shape { }

public toString(Shape s) { return "Shape/" + s.getClass(); }

String both(Shape l, Shape r);both(Rect l, Rect r) { return "r-r"; }

public void main(String[] args) { Object o = Class.forName("s14.Circle").newInstance(); System.out.println("Object=" + o.toString());

if(o instanceof Shape) both(o, o);}

Run s14

Page 36: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

36

Overview of features

Basic features/properties Methods functions Open classes Decoupling of state and behavior Covariance Symmetry

Additional features Value dispatch Exact matching Static dispatching of multimethods (“super”)

Not all features are supported by every implementation

Page 37: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

37

Summary

MultiJava Simpler compilation model Restrictions on the definitions of multimethods The less-specialized method must be

implemented

Nice Complex compilation Uses pattern matching => Compile-time safety Dynamic loading of classes yields dispatch

errors at run-time

Page 38: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

38

Multimethods in ML (1/3)

Definition of Multimethods: Dispatching mechanism where the executed method is selected by the dynamic type of one (or more) argument(s)

Q:Is it possible to create a similar mechanism in ML?

First approach: “A language without virtual methods cannot offer multimethods”

Second approach: Let’s change the definition (!) Multimethods: Dispatching mechanism where the

executed function is selected by the concrete type of one (or more) polymorphic values

Page 39: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

39

Multimethods in ML (2/3)

ML support polymorphism: A single variable can hold values of different types

Datatype (AKA: Variant record)

-datatype Shape = Circle of real | Rect of real*real;

-fun area(Circle(r)) = r*r*3.14 | area(Rect(w,h)) = w*h;val area = fn : Shape -> real

The area() function is analogous to an area() method defined by class Shape

Page 40: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

40

Multimethods in ML (3/3)

Now, let’s define our both() function.. both() accepts a tuple of Shape*Shape Uses Pattern-matching to select correct

implementation

-datatype Shape = Circle of real | Rect of real*real;

-fun both(Circle(_), Circle(_)) = "c-c" | both(Circle(_), Rect(_,_)) = "c-r" | both(Rect(_,_), Circle(_)) = "r-c" | both(Rect(_,_), Rect(_,_)) = "r-r";val both = fn : Shape * Shape -> string

Page 41: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

41

ML style multimethods in C++

struct Circle { };struct Rect { };

typedef Variant<Circle,Rect> Shape;

struct Both {

void action(Circle a1, Circle a2) const { cout << "c-c"; } void action(Circle a1, Rect a2) const { cout << "c-r"; } void action(Rect a1, Circle a2) const { cout << "r-c"; } void action(Rect a1, Rect a2) const { cout << "r-r"; }};

int main() { Shape c = Circle(); Shape r = Rect();

dispatch(c,r,Both());

reutrn 0;}

Page 42: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

42

References

Curtis, Leavens, Chambers and Todd, MultiJava: Modular open classes and symmetric Multiple Dispatch for Java, OOPSLA 2000

Baker and Hsie, Maya: Multiple-Dispatch Syntax Extension in Java, PLDI 2002

Dutchyn, Szafron, Bromling and Holst, Multi-Dispatch in the Java virtual machine: design and implementation, COOTS 2001

Bonniot, Keller and Barber, The Nice user’s manual

Page 43: Multimethods Itay Maman Demo. 2 Multimethods (1/2) A dynamic-dispatch mechanism The executed method is selected by the dynamic type of one (or more) argument(s)

43

-The End-