Double Dispatch Stphane Ducasse stephane ducasseinria fr http
Double Dispatch? Stéphane Ducasse stephane. ducasse@inria. fr http: //www. iam. unibe. ch/~ducasse/ Stéphane Ducasse 1
How to invoke a method Depending on **both** the receiver and an argument… Type check are evil Overloading is plain bad Remember Java lookup? Use Double Dispatch S. Ducasse 2
Type Checking for Dispatching How to invoke a method depending on the receiver and an argument? A not so good solution: PSPrinter>>print: a. Document ^ a. Document is. PS if. True: [self print. From. PS: a. Document] if. False: [self print. From. PS: a. Document as. PS] PSPrinter>>print. Form. PS: a. PSDoc <primitive> Pdf. Printer>>print: a. Document ^ a. Document is. PS if. True: [self print. From. PDF: a. Document as. PDF] if. False: [self print. From. PDF: a. Document] Pdf. Printer>>print. Form. PS: a. Pdf. Doc <primitive> S. Ducasse 3
Drawbacks of Typecheck • • • S. Ducasse Adding new kinds of documents requires changes everywhere Adding new documents requires changes everywhere No dynamic (without recompilation) possibilities 4
Double Dispatch Solution: use the information given by the single dispatch and redispatch with the argument (send a message back to the argument passing the receiver as an argument) S. Ducasse 5
Double Dispatch (a) PSPrinter>>print: a. Doc print. On. PSPrinter: self (b) Pdf. Printer>>print: a. Doc print. On. Pdf. Printer: self (c) PSDoc>>print. On. PSPrinter: a. PSPrinter <primitive> (d) Pdf. Doc>>print. On. Pdf. Printer: a. PSPrinter a. PSprinter print: self as. PS (e) PSDoc>>print. On. PSPrinter: a. Pdf. Printer print: self as. Pdf (f) Pdf. Doc>>print. On. Pdf. Printer: a. Pdf. Printer <primitive> Some Tests: psprinter print: psdoc =>(a->c) pdfprinter print: pdfdoc => (b->f) psprinter print: pdfdoc => (a->d->b->f) pdfprinter print: psdoc => (b->e->b->f) S. Ducasse 6
Let’s Step Back Example: Coercion between Float and Integer Not a really good solution: Integer>>+ a. Number (a. Number is. Kind. Of: Float) if. True: [ a. Number as. Float + self] if. False: [ self int. Add. Primitive: a. Number] Float>>+ a. Number (a. Number is. Kind. Of: Integer) if. True: [a. Number as. Float + self] if. False: [self float. Add. Primitive: a. Number] S. Ducasse 7
Double Dispatch on Numbers (a) Integer>>+ a. Number ^ a. Number sum. From. Integer: self (b) Float>>+ a. Number ^ a. Number sum. From. Float: self (c) Integer>>sum. From. Integer: an. Integer <primitive: 40> (d) Float>>sum. From. Integer: an. Integer ^ an. Integer as. Float + self (e) Integer>>sum. From. Float: a. Float ^a. Float + self as. Float (f) Float>>sum. From. Float: a. Float <primitive: 41> Some Tests: S. Ducasse 1 + 1: (a->c) 1. 0 + 1. 0: (b->f) 1 + 1. 0: (a->d->b->f) 1. 08 + 1: (b->e->b->f 1 + 2. 0
Double Dispatching • Three Kinds of Messages – – – S. Ducasse Primary operations Double dispatching methods Forwarding operations 9
- Slides: 9