- An introduction to Object Function Programming.
- Cambridge 2010
Ein Einführungsbuch in Scala, Inhalt in Inf.Scala
- sourceCode http://www.stepsinscala.com/ plus errata im readMe erra
Spezialkapitel über
expression problem
wir haben zwei KlassenHierarchien: Daten und Operationen und möchen in beiden Dimensionen erweitern, ohne den Code der GrundImplementierung zu ändern. Drei Schwierigkeitsstufen:
- addierte Daten/Operationen funktionieren im neuen Code
- addierte Daten/Operationen funktionieren in der GrundImplementierung
- von der GrundImplementierung erzeugte Daten/Operationen unterstützen (in der Erweiterung und im GrundCode) auch die neuen Daten/Operationenneuen Code
- Konstruktoren die bestehende Daten kombinieren mit/ohne Casts auf Subtype (der neue Operation unterstützt)
- Casts sind unbeliebt, aber es gibt zwei Stufen
- 1 einziges Cast: code stellt sicher, dass richter Type benutzt wird, aber typen system kann das nicht selbst inferieren
- case instanceOf: FallUnterscheidung im Code, damit kann man natürlich fast alles lösen, aber das ist nicht mehr oo!
- 2 verschiedene Erweiterung können unabhängig implementiert werden oder 2. Erweiterung muss 1. erweitern
- GrundProblem: wir bräuchten 2-dimensionales oo MethodDispatching, das unterstützt aber nur 1-dimensionales - ich glaube auch Multiple Inheritance hilft nicht, wir bräuchten dynamisches Dispatching auf mindestens einem MethodenArgument ==> multi methods scheint das Schlagwort zu sein, das genau das implementiert
Ansätze
- dataCentric:
- Subklassen der Daten funktionieren gut, alle Operationen sind überall definiert
- neue Operationen müssen in jede Daten Grundklasse eingebaut werden! Subklassing der Operationen braucht überall Casts
- OperationCentric: mit Visitor Pattern, dual zu dataCentric, DatenErweiterungen brauchen überall Aenderungen
- wrapper Objekte (die neue Operationen unterstützen)
- automatische TypeConversions (mit implicit, aber die sind natürlich nicht dynamisch dispatch'd!)
- Modul hiding: wir überschreiben die BaseImplementierung in einem Modul, lokal funktioniert es dann wie gewünscht ...
- Factory: wir registrieren die Creators mit allen OperationsMethoden (genügend früh, bevor GrundImplementierung Daten/Operationen erzeugt) ==> braucht immer noch typeCasts)
- Wir registrien Operation, die alle Operationen für einen DatenSubtype enthält im Companion Object, die Operation holen wir immer von da LitPlus.epRe1