Efficient Multimethods in a Single Dispatch Language Brian Foote Brian Foote Ralph Johnson Dept. of...
-
date post
22-Dec-2015 -
Category
Documents
-
view
226 -
download
1
Transcript of Efficient Multimethods in a Single Dispatch Language Brian Foote Brian Foote Ralph Johnson Dept. of...
Efficient Multimethods in a Efficient Multimethods in a Single Dispatch LanguageSingle Dispatch Language
Brian FooteBrian Foote
Ralph JohnsonRalph JohnsonDept. of Computer ScienceDept. of Computer Science
University of Illinois at Urbana-ChampaignUniversity of Illinois at Urbana-Champaign
201 N. Goodwin, Urbana, IL 61801, USA201 N. Goodwin, Urbana, IL 61801, USA
[email protected] [email protected] [email protected] [email protected]
James NobleJames NobleSchool of Mathematical and Computing SciencesSchool of Mathematical and Computing Sciences
Victoria University of WellingtonVictoria University of Wellington
P.O. Box 600, Wellington, New ZealandP.O. Box 600, Wellington, New Zealand
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 22
LandmarksLandmarks Motivation for MultimethodsMotivation for Multimethods Syntax MattersSyntax Matters A Tale of Two MOPsA Tale of Two MOPs Two ImplementationsTwo Implementations Enduring SignificanceEnduring Significance
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 33
Let’s Get SeriousLet’s Get SeriousOne day an Englishman, a One day an Englishman, a ScotsmanScotsman, and , and
an Irishman walked into a pub together. an Irishman walked into a pub together. They each called for a dram of whiskey. They each called for a dram of whiskey. As they were about to enjoy their As they were about to enjoy their libations, three flies landed, one in each libations, three flies landed, one in each of their drinks, and became stuck inside of their drinks, and became stuck inside the glasses. The Englishman pushed his the glasses. The Englishman pushed his shot away in disgust. The Scotsman shot away in disgust. The Scotsman fished the fly out of his glass, and fished the fly out of his glass, and continued drinking it, as if nothing had continued drinking it, as if nothing had happened. The Irishman, too, picked the happened. The Irishman, too, picked the fly out of his drink, held it out over the fly out of his drink, held it out over the glass, and started yelling, "SPIT IT OUT, glass, and started yelling, "SPIT IT OUT, SPIT IT OUT YOU BASTARD!!!!" SPIT IT OUT YOU BASTARD!!!!"
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 44
Motivation: A Simple ScotsmanMotivation: A Simple Scotsmanpublic class Scotsman extends Carouserpublic class Scotsman extends Carouser{{
public void imbibe(ScotchWhiskey libation)public void imbibe(ScotchWhiskey libation) {{
stomach.add(libation);stomach.add(libation);bloodAlchoholLevel += 0.01;bloodAlchoholLevel += 0.01;System.out.println("A wee dram...");System.out.println("A wee dram...");
}}
public void imbibe(IrishWhiskey libation)public void imbibe(IrishWhiskey libation){{
stomach.add(libation);stomach.add(libation); bloodAlchoholLevel += 0.00;bloodAlchoholLevel += 0.00; System.out.println("Belfast Bog water...");System.out.println("Belfast Bog water...");
}}
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 55
A Simple IrishmanA Simple Irishmanpublic class Irishman extends Carouserpublic class Irishman extends Carouser{{
public void imbibe (ScotchWhiskey libation)public void imbibe (ScotchWhiskey libation) {{ emptyStomach();emptyStomach(); System.out.System.out.
println("Caledonian Swill...");println("Caledonian Swill...");}}
public void imbibe (IrishWhiskey libation)public void imbibe (IrishWhiskey libation){{
stomach.add(libation);stomach.add(libation); bloodAlchoholLevel += 0.01;bloodAlchoholLevel += 0.01; System.out.println("Sure and begora...");System.out.println("Sure and begora...");
}}
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 66
A Simple, but Naïve TestA Simple, but Naïve Test public void testOverloads()public void testOverloads() {{ Irishman paddy = new Irishman();Irishman paddy = new Irishman(); Scotsman angus = new Scotsman();Scotsman angus = new Scotsman(); System.out.System.out.
println("--> testOverloads()...");println("--> testOverloads()..."); paddy.imbibe(new IrishWhiskey());paddy.imbibe(new IrishWhiskey()); paddy.imbibe(new ScotchWhiskey());paddy.imbibe(new ScotchWhiskey()); angus.imbibe(new IrishWhiskey());angus.imbibe(new IrishWhiskey()); angus.imbibe(new ScotchWhiskey());angus.imbibe(new ScotchWhiskey()); }}
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 77
A Simple, Unsuccessful VariationA Simple, Unsuccessful Variationpublic void testBreakOverloads()public void testBreakOverloads(){{
Irishman paddy = new Irishman();Irishman paddy = new Irishman();Scotsman angus = new Scotsman();Scotsman angus = new Scotsman();
Carouser carouser = paddy;Carouser carouser = paddy; System.out.println("--> testBreakOverloads()...");System.out.println("--> testBreakOverloads()..."); Dram dram = new IrishWhiskey();Dram dram = new IrishWhiskey(); // You can't really do this properly...// You can't really do this properly...
carouser.imbibe(dram);carouser.imbibe(dram);carouser = angus;carouser = angus;
carouser.imbibe(new IrishWhiskey());carouser.imbibe(new IrishWhiskey());}}
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 88
A Useless OverloadA Useless Overloadpublic void imbibe(Dram libation)public void imbibe(Dram libation){{System.out.System.out.
println("Saints preserve us...");println("Saints preserve us...");}}
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 99
A Type CaseA Type Case public void imbibe(Dram libation)public void imbibe(Dram libation) {{ if (libation instanceof ScotchWhiskey)if (libation instanceof ScotchWhiskey) {{ emptyStomach();emptyStomach(); System.out.println("Caledonian Swill...");System.out.println("Caledonian Swill..."); }} else if (libation instanceof IrishWhiskey)else if (libation instanceof IrishWhiskey) {{ stomach.add(libation);stomach.add(libation); bloodAlchoholLevel += 0.01;bloodAlchoholLevel += 0.01; System.out.println("Sure and begora...");System.out.println("Sure and begora..."); }} elseelse System.out.println("Mother of God...");System.out.println("Mother of God..."); }}
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 1010
The Olfactory MethodThe Olfactory Method
Kent Beck: May be Best Remembered as the Man Kent Beck: May be Best Remembered as the Man Who brought Scatology and Software Who brought Scatology and Software Engineering together…Engineering together…
If it stinks, change it!If it stinks, change it!--Grandma Beck--Grandma Beck
Code Smells are (not so) subtle indications a piece Code Smells are (not so) subtle indications a piece of code is in need of attention… …and is a likely of code is in need of attention… …and is a likely candidate for refactoring…candidate for refactoring…
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 1111
Double DispatchDouble Dispatchpublic class Irishman extends Carouserpublic class Irishman extends Carouser{{ public void imbibe(Dram libation)public void imbibe(Dram libation) {{ libation.whenImbibedByIrishman(this);libation.whenImbibedByIrishman(this); }}
public class IrishWhiskey extends Drampublic class IrishWhiskey extends Dram{{
public void whenImbibedByIrishman(Irishman irishman)public void whenImbibedByIrishman(Irishman irishman) {{ irishman.stomach.add(this);irishman.stomach.add(this); irishman.bloodAlchoholLevel += 0.01;irishman.bloodAlchoholLevel += 0.01; System.out.println("Sure and begora...");System.out.println("Sure and begora..."); }}}}
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 1212
Dynamic Multidispatch?Dynamic Multidispatch?public class Scotsman extends Carouserpublic class Scotsman extends Carouser{{
public void imbibe(<public void imbibe(<ScotchWhiskeyScotchWhiskey> libation)> libation) {{
stomach.add(libation);stomach.add(libation);bloodAlchoholLevel += 0.01;bloodAlchoholLevel += 0.01;System.out.println("A wee dram...");System.out.println("A wee dram...");
}}
public void imbibe(<public void imbibe(<IrishWhiskeyIrishWhiskey> libation)> libation){{
stomach.add(libation);stomach.add(libation); bloodAlchoholLevel += 0.00;bloodAlchoholLevel += 0.00; System.out.println("Belfast Bog water...");System.out.println("Belfast Bog water...");
}}
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 1313
Syntax MattersSyntax MattersCLOSCLOS: :
(defmethod speak ((who animal))(defmethod speak ((who animal)) (format t "I'm an animal: ~A~%" who)) (format t "I'm an animal: ~A~%" who))
Dylan:Dylan:
define method main (argv0 :: <byte-string>, define method main (argv0 :: <byte-string>, #rest noise)#rest noise) puts("Hello, World.\n");puts("Hello, World.\n");end;end;
Cecil:Cecil:
x@smallInt + y@smallInt x@smallInt + y@smallInt { ^primAdd(x,y, {&errorCode | … })}{ ^primAdd(x,y, {&errorCode | … })}
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 1414
Multimethods in SmalltalkMultimethods in Smalltalk
ScreenDisplay>>draw: aGraphicalObject <Line>ScreenDisplay>>draw: aGraphicalObject <Line> ”draw a line on a screen” ”draw a line on a screen”
ScreenDisplay>>draw: aGraphicalObject <Arc>ScreenDisplay>>draw: aGraphicalObject <Arc> ”draw an arc on a screen” ”draw an arc on a screen”
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 1515
Browsing MultimethodsBrowsing Multimethods
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 1616
Visitor: BeforeVisitor: Before
ParseNode>>acceptVistor: aVisitorParseNode>>acceptVistor: aVisitor^self subclassResponsibility^self subclassResponsibility
VariableNode>>acceptVistor: aVisitorVariableNode>>acceptVistor: aVisitor^aVisitor visitWithVariableNode: self^aVisitor visitWithVariableNode: self
ConstantNode>>acceptVistor: aVisitorConstantNode>>acceptVistor: aVisitor^aVisitor visitWithConstantNode: self^aVisitor visitWithConstantNode: self
OptimizingVisitor>>visitWithConstantNode: OptimizingVisitor>>visitWithConstantNode: aNodeaNode^aNode value optimized^aNode value optimized
OptimizingVisitor>>visitWithVariableNode: OptimizingVisitor>>visitWithVariableNode: aNodeaNode^aNode lookupIn: self symbolTable^aNode lookupIn: self symbolTable
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 1717
Visitor: AfterVisitor: After
OptimizingVisitor>>visitWithNode: aNode OptimizingVisitor>>visitWithNode: aNode <ConstantNode><ConstantNode>
^self value optimized^self value optimized
OptimizingVisitor>>OptimizingVisitor>> visitWithNode: aNode <VariableNode>visitWithNode: aNode <VariableNode>
^aNode lookupIn: self symbolTable^aNode lookupIn: self symbolTable
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 1818
A Language Built of ObjectsA Language Built of Objects
ObjectObject BehaviorBehavior ClassDescriptionClassDescription ClassClass MetaclassMetaclass MethodMethod MethodDictionaryMethodDictionary CompiledMethodCompiledMethod ByteArrayByteArray
ContextContext MethodContextMethodContext BlockContextBlockContext MessageMessage ProcessProcess ProcessSchedulerProcessScheduler SemaphoreSemaphore SharedQueueSharedQueue CompilerCompiler SystemDictionarySystemDictionary
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 1919
Objects We BuiltObjects We Built MultiMethodMultiMethod SpecializerSpecializer ClassSpecializerClassSpecializer EqualSpeciealizerEqualSpeciealizer GenericMessageGenericMessage MethodCombinationMethodCombination DiscriminatingMethodDiscriminatingMethod Qualifiers (#Before Qualifiers (#Before
#After, etc.)#After, etc.)
SubStandardMethodCombinationSubStandardMethodCombination SimpleMethodCombinationSimpleMethodCombination BetaMethodCombinationBetaMethodCombination DispatchingMethodCombinationDispatchingMethodCombination
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 2020
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 2121
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 2222
N-Way MultidispatchN-Way Multidispatch
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 2323
Generated Redispatching MethodsGenerated Redispatching Methods
n
i
i
j
SjD1 1
|D| = |S|D| = |S11| |
+ |S+ |S22| × |S| × |S11||
+ |S+ |S33| × |S| × |S22| × |S| × |S11| … | …
+ |S+ |Snn| × ... × |S| × ... × |S22| × |S| × |S11| × 2| × 2
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 2424
PerformancePerformanceDispatch Type nanosec.
minnanosec.
maxRatio
1. Multidispatch (2 args) 521 524 1.00
2. Tare (^self) (1 arg) 90 120 0.20
3. Metaobjects (^self) (2 args) 597,000 624,000 1168
4. Metaobjects (super) (2 args) 679,000 750,000 1367
5. Metaobjects cached (2 args) 117,000 125,000 231
6. Dictionary (3 args) 13227 13335 25
7. Case (inline) ( 3 args) 10654 10764 20
8. Multidispatch (3 args) 633 779 1.35
9. Multidispatch (7 args) 1200 1221 2.32
Table I -- Performance Results200MHz Pentium Pro
1,000,000 calls/multiple runs
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 2525
LessonsLessons The Beauty of Smalltalk The Beauty of Smalltalk The Elegance of the CLOS The Elegance of the CLOS
MOPMOP Building Languages of Building Languages of
ObjectsObjects The Power of The Power of
MultimethodsMultimethods
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 2626
I Have Nothing to DeclareI Have Nothing to Declare
End to End ArgumentEnd to End Argument Impact of Dynamic Types and LanguagesImpact of Dynamic Types and Languages The Arrogance of Closed WorldsThe Arrogance of Closed Worlds Reflection as a School of ArchitectureReflection as a School of Architecture
Foote, Johnson, and Noble -- Foote, Johnson, and Noble -- 2727
AcknowledgementsAcknowledgements Ralph JohnsonRalph Johnson James NobleJames Noble
John BrantJohn Brant Don RobertsDon Roberts
Richard P. GabrielRichard P. Gabriel Andrew BlackAndrew Black StStééphane Ducassephane Ducasse Christophe DonyChristophe Dony Anonymous ECOOP ReviewersAnonymous ECOOP Reviewers UIUC Software Architecture GroupUIUC Software Architecture Group