Was ist eine "aufgehobene Darstellung"?

12

Bin gerade auf diesen Begriff hier gestoßen:

http://www.codemesh.io/codemesh2014/viktor-klang

"Wir demonstrieren die Flow-API - eine erweiterte Darstellung - sowie eine steckbare Möglichkeit, die erweiterte Darstellung in die Ausführungsdarstellung - Flow Materialization - umzuwandeln."

Googeln hat nicht viel geholfen.

Den
quelle
Empfohlene Lektüre: Diskutiere diesen $ {blog}
Mücke
11
@gnat es scheint, dass er diesen Begriff nicht erfunden hat, es sieht nicht nach einer Meinung aus, es wird wahrscheinlich keine Diskussion provozieren und mein Bauchgefühl ist, dass er nicht zu breit sein wird (obwohl er sich wie Mathematik anfühlt).
Den
2
Ich diskutiere die Bedeutung von "aufgehoben" im Kontext von C # hier: blogs.msdn.com/b/ericlippert/archive/2007/06/27/… - wahrscheinlich verwenden die Scala-Entwickler den Begriff analog, aber mehr allgemeine Mode.
Eric Lippert

Antworten:

22

Ich bin nicht mit der Flow-API vertraut.

Der Begriff „Heben“ stammt aus der Kategorietheorie. In Programmiersprachen wie Haskell oder Scala liftübernimmt eine Funktion eine Funktion A => Bund führt auf irgendeine Weise Magie aus, so dass die aufgehobene Funktion F[A] => F[B]auf einen Funktor oder eine Monade angewendet werden kann F[A].

Ein konkretes Beispiel mit dem SeqContainer von Scala : Angenommen, wir haben eine Funktion def double(x: Int): Int = 2 * xund eine Sequenz val xs = Seq(1, 2, 3). Wir können nicht double(xs)wegen inkompatiblen Typen. Aber wenn wir einen bekommen val doubleSeq = liftToSeq(double), können wir das tun doubleSeq(xs), was sich auszahlt Seq(2, 4, 6). Hier liftToSeqkann als implementiert werden

def liftToSeq[A, B](f: A => B): (Seq[A] => Seq[B]) =
  (seq: Seq[A]) => seq.map(f)

Der Seq(…)Konstruktor kann auch als Hebevorgang angesehen werden, der die Werte 1, 2, 3in eine SeqInstanz hebt und es uns ermöglicht, Listenabstraktionen für diese Werte zu verwenden.

Monaden ermöglichen es uns, das Innenleben eines bestimmten Typs zu kapseln, indem sie eine wasserdichte, aber zusammensetzbare Oberfläche bieten. Die Verwendung einer gehobenen Darstellung erleichtert das Nachdenken über eine Berechnung. Das Verwenden solcher Abstraktionen bedeutet auch, dass wir das Wissen über die abstrahierten Besonderheiten verlieren, aber diese werden benötigt, um eine effiziente Implementierung unter der Haube zu ermöglichen (Finden einer geeigneten Ausführungsrepräsentation).

amon
quelle
4
Das ist eine gute Beschreibung des mathematischen "Hebens". Wir sollten auch einen Verweis auf die formellere Beschreibung des Heraushebens aus Wikipedia aufnehmen .
Scott Whitlock
3
Ein vielleicht klareres Beispiel für "Heben" ist das Heben auf nullfähige (oder "optionale" oder "vielleicht") Typen. Angenommen, Sie haben einen Operator +wie folgt definiert int + int --> int. Der Operator int? + int? --> int?" Aufgehoben zu Null" hat die Semantik "Wenn einer der Operanden Null ist, ist die Antwort Null, andernfalls verwenden Sie den Operator" Nicht aufgehoben "für die Werte."
Eric Lippert
@ScottWhitlock Hebst du überhaupt?
Helrich
1
@Frank Ich habe den Wikipedia-Artikel gelesen, bevor ich meine Antwort geschrieben habe, und ihn auch nicht verstanden. Stattdessen fand ich das Haskell-Wiki zum Heben zugänglicher. Beachten Sie, dass wir nicht wirklich vier Typen haben. Wir haben vier konkrete Typen, aber nur drei Typvariablen: zwei Typen Aund Bund einen Funktor, Fder ein Typkonstruktor ist.
amon
1
Ich bin nicht zu tief in all das, aber wenn Fes sich um einen Typkonstruktor handelt, dann F[A]ist es einer seiner konstruierten Typen. Warum ist es also falsch, von diesen vier Typen zu sprechen? (Natürlich wären zwei Typen und ein Typkonstruktor gleich gut)
Frank
6

Der Begriff Heben kann natürlich je nach Kontext unterschiedliche Bedeutungen haben.

In der generischen Programmierung wird der Prozess der Abstraktion auf die nächsthöhere Ebene beschrieben. Beispielsweise könnten Sie zwei Codeteile haben, einen mit intund einen mit float. Das Aufheben dieses Codes würde in etwa bedeuten, die Methode mit einem generischen Typ zu versehen T, der für beide intund funktioniert float.

Ich fand, dass diese Verwendung des Begriffs eine gute intuitive Richtlinie dafür ist, was Heben bedeutet. Der einzige Unterschied, der zwischen den verschiedenen Kontexten zu bestehen scheint, ist, was diese höhere Abstraktion wirklich ist.

Insbesondere Viktor ist im Kontext der funktionalen Programmierung bekannt, und in diesem Kontext gibt es visuell unterschiedliche Interpretationen von Heben . Ein Beispiel ist das Heben von Werten in einen Funktor oder das Heben von Funktionen zum Bearbeiten monadischer Werte (z. B. Haskells liftM2).

Ein sehr konkretes Beispiel für eine "aufgehobene Darstellung" könnte dann z. sei a List(1), oder a Some(1).

Frank
quelle
4

Solche Konzepte sind in der Regel am einfachsten anhand eines konkreten Beispiels zu verstehen. Betrachten Sie den folgenden Auszug aus diesem Flow-API-Beispiel :

Flow(text.split("\\s").toVector).
      // transform
      map(line => line.toUpperCase).
      // print to console (can also use ``foreach(println)``)
      foreach(transformedLine => println(transformedLine)).
      onComplete(FlowMaterializer(MaterializerSettings())) {
        case Success(_) => system.shutdown()
        case Failure(e) =>
          println("Failure: " + e.getMessage)
          system.shutdown()
      }

Dies erfordert den folgenden Code:

text.split("\\s").toVector.
      map(line => line.toUpperCase).
      foreach(println)

und "hebt" es in einen FlowKontext. Auf diese Weise können Sie dieselbe Syntax verwenden, mit der Sie vertraut sind, um Ihren Algorithmus zu spezifizieren. Hinter den Kulissen mapwird dies jedoch parallel auf mehreren Prozessoren oder sogar Maschinen durchgeführt, und die foreach(println)Ausgabe wird dann nahtlos zum Drucken an einen Prozessor zurückgesammelt.

Dies ist ein allgemeiner Begriff, der sich auf das Umschließen eines beliebigen Kontexts mit einem beliebigen Typ beziehen kann. Ein anderes bekannteres Beispiel ist mapdie Verwendung einer Funktion, die an einem einzelnen Element arbeitet und es in den neuen Kontext der Arbeit an einer Sammlung dieser Elemente "hebt". Heben ist in der funktionalen Programmierung allgegenwärtig und einer der Hauptgründe, warum es so viel einfacher ist, funktionalen Code wiederzuverwenden.

Karl Bielefeldt
quelle