LS10: Christos K.K. Loverdos, Apostolos Syropoulos. Steps in Scala

  • An introduction to Object Function Programming.
  • Cambridge 2010

Ein Einführungsbuch in Scala, Inhalt in Inf.Scala

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:

  1. addierte Daten/Operationen funktionieren im neuen Code
  2. addierte Daten/Operationen funktionieren in der GrundImplementierung
  3. von der GrundImplementierung erzeugte Daten/Operationen unterstützen (in der Erweiterung und im GrundCode) auch die neuen Daten/Operationenneuen Code
  4. Konstruktoren die bestehende Daten kombinieren mit/ohne Casts auf Subtype (der neue Operation unterstützt)
  5. Casts sind unbeliebt, aber es gibt zwei Stufen
    1. 1 einziges Cast: code stellt sicher, dass richter Type benutzt wird, aber typen system kann das nicht selbst inferieren
    2. case instanceOf: FallUnterscheidung im Code, damit kann man natürlich fast alles lösen, aber das ist nicht mehr oo!
  6. 2 verschiedene Erweiterung können unabhängig implementiert werden oder 2. Erweiterung muss 1. erweitern
  7. 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

symbolic computing