Kann die Seq / par / view / force von Scala collection als Verletzung des Uniform-Return-Type-Prinzips angesehen werden?

8

Der größte Teil der Komplexität der Implementierung des Collection-Frameworks ergibt sich aus der Tatsache, dass Scala im Gegensatz zu C # 's LINQ oder anderen Collection-Frameworks den "besten" Collection-Typ für Funktionen höherer Ordnung zurückgeben kann:

%Vor%

Warum gilt dieses Prinzip nicht für Methoden wie seq , par , view , force ?

%Vor%

Gibt es eine technische Einschränkung, die verhindert, dass es funktioniert? Oder ist das Absicht / Design? Wenn man bedenkt, dass LINQ grundsätzlich faul ist, ist Scalas Äquivalent ( view , force ) nicht typsicherer (nur bei Verwendung der strikten Methoden), oder?

    
soc 17.06.2011, 18:18
quelle

2 Antworten

8

Es ist möglich, mehr Typinformationen in die parallelen Erfassungsklassen einzubetten, so dass Sie die Sammlung zurückbekommen, von der Sie ausgegangen sind, das stimmt. Dies würde bedeuten, dass nach dem Umwandeln eines List in ein ParVector durch Aufrufen von par (in O (n), weil Elemente in den Vektor kopiert werden) und dann Aufruf von seq , erneut ein List . Um die Liste mit seq zu erhalten, müssten Sie alle Elemente aus dem Vektor zurück in die Liste kopieren. Was stattdessen passiert, ist:

  • ParVector wird wieder in ein Vector konvertiert, wenn seq aufgerufen wird - es wird in O (1)
  • konvertiert
  • ruft par erneut für diesen Vektor auf und gibt Ihnen ein ParVector in O (1), da sowohl der Vektor als auch der Parallelvektor dieselben zugrunde liegenden Daten
  • teilen

Beachten Sie, dass eine Auflistung, z. B. eine Liste, neu strukturiert werden muss, wenn sie in eine parallele Sammlung umgewandelt wird. Andernfalls können die Operationen auf dieser Liste nicht effizient parallelisiert werden.

Somit müssen Sie beim Aufruf von par und seq nicht wiederholt für das Kopieren bezahlen - die Conversions werden viel effizienter. Da das primäre Ziel der parallelen Sammlungen die Steigerung der Effizienz war, wurde dies als wichtiger angesehen als das Prinzip des einheitlichen Rückgabetyps.

    
axel22 17.06.2011, 22:38
quelle
1

In Bezug auf den statischen Rückgabetyp einer Sammlungsmethode unterstützt C # das Überladen der LINQ-Erweiterungsmethoden ( Select , Where usw.) und wählt automatisch den spezifischsten im Bereich aus. So kann Seq.Select eine Seq zurückgeben, Enumerable.Select kann eine Enumerable usw. zurückgeben. Dies ist sehr ähnlich wie die spezifischste implizite Implementierung in Scala gewählt wird.

In Bezug auf den dynamischen Typ werden LINQ-Operationen als Erweiterungsmethoden implementiert, sodass keine dynamische Verteilung durchgeführt wird. % Co_de% gibt also (Seq as Enumerable).Select zurück, nicht Enumerable . In Scala werden Sammlungsmethodenaufrufe dynamisch versendet, sodass der dynamische Typ für Seq , map usw. gleich bleibt. Beide Ansätze haben Vorteile / Nachteile. Die einzige saubere Lösung für diese Art von Problem ist Multimethods IMHO und weder Sprache / Runtime unterstützt sie effizient.

Wie beim Laufzeitverhalten gibt LINQ immer eine träge ausgewertete Ansicht der Sammlung zurück. Es gibt keine Methode in der Ansicht, die eine Kollektion des Originaltyps magisch zurückgibt. Sie müssen manuell angeben, dass Sie ein Array verwenden möchten, zum Beispiel mit der Methode filter . IMHO, das ist ein sauberer und einfacher Ansatz als der in Scala, und Lazy Collection-Operationen bilden besser als strikte, aber dies kostet einen extra Methodenaufruf, um eine strikte Sammlung für einzelne Collection-Operationen zu erhalten.

    
Jesper Nordenberg 20.06.2011 11:33
quelle

Tags und Links