Entscheidung für ungeprüfte Ausnahmen in Scala

17

Als Java-Programmierer habe ich ungeprüfte Ausnahmen immer kritisiert. Meistens verwenden Programmierer es, um die Programmierung zu vereinfachen und später Probleme zu verursachen. Auch die Programme (wenn auch unordentlich) mit aktivierten Ausnahmen sind im Vergleich zu nicht aktivierten Gegenstücken sehr robust.

Überraschenderweise gibt es in Scala keine Checked Exceptions. Alle aktivierten und deaktivierten Java-Komponenten sind in Scala deaktiviert.

Was ist die Motivation für diese Entscheidung? Für mich eröffnet sich eine Vielzahl von Problemen bei der Verwendung von externem Code. Und wenn die Dokumentation zufällig schlecht ist, führt dies zu KILL.

Jatin
quelle
11
Als Java-Programmierer habe ich geprüfte Ausnahmen immer kritisiert. Unordentlicher Code ist niemals robust.
Michael Borgwardt

Antworten:

28

Überprüfte Ausnahmen werden meist als Fehlschlag gewertet. Beachten Sie, dass keine Sprachen erstellt wurden, nachdem Java sie übernommen hat. Siehe http://www.artima.com/intv/handcuffs2.html , http://googletesting.blogspot.ru/2009/09/checked-exceptions-i-love-you-but-you.html , http: / /www.mindview.net/Etc/Discussions/CheckedExceptions , etc.

Insbesondere sind sie nicht zusammensetzbar (außer durch Zurücksetzen auf throws Exception).

In Scala haben Sie eine bessere Option: mit algebraischen Typen für Rückgabewerte wie Option[T], Either[Exception, T], Ihre eigene Art , wenn Sie den Benutzer Griff bestimmten Fällen wollen (zB statt

def foo: Int // throws FileNotFoundException, IllegalStateException

du hast

sealed trait FooResult
case class Success(value: Int) extends FooResult
case class FileNotFound(file: File) extends FooResult
case object IllegalState extends FooResult

def foo: FooResult

und der Verbraucher muss nun alle Ergebnisse verarbeiten.)

Für den Umgang mit externem Code, der Ausnahmen auslöst, haben Sie scala.util.control.exceptionoder scala.util.Try(beginnend mit Scala 2.10).

Alexey Romanov
quelle
4
Niemals verstanden, dass die meisten Leute nicht mit geprüften Ausnahmen umgehen . Die meisten Leute sind keine guten Entwickler. Ich garantiere, dass die meisten Entwickler Fehlerergebnisse sowieso nicht verarbeiten werden. Eigentlich try..catchscheint das viel lesbarer zu sein als if. Außerdem kann ich garantieren, dass die meisten Entwickler keinen Code schreiben, der Fehlerergebnisse zurückgibt - zu kompliziert in Scala - Sie können nicht einmal von einer Funktion zurückkehren, wann immer Sie wollen (genau wie in Pascal)
Pijusn,
5
Ich finde Sie Kommentar verwirrend und ohne Beweise, @Pius. In Scala führt die Auswahl von Option als Rückgabetyp wahrscheinlich eher zu einem Mustervergleich als zu If- Anweisungen. Das Zurückgeben von None statt Some in diesem Stil ist trivial und nicht komplex. Weniger kluge Entwickler schreiben möglicherweise keine Funktionen, die algebraische Typen zurückgeben, aber das ist etwas anderes. Schließlich "können Sie nicht einmal von einer Funktion zurückkehren, wann immer Sie wollen" - einfach falsch.
Itsbruce
7

Überprüfte Ausnahmen in Java sind keine schlechte Sache. Natürlich sind ADTs für Scala die bessere Option, aber in Java haben überprüfte Ausnahmen ihren Platz und das saubere Codeargument ist einfach ahnungslos, egal wie viele Blogs es wiederholt haben. Grundsätzlich heißt es, dass Sie strenge und möglicherweise reparierbare Bedingungen, die in Ihrem System auftreten können, gerne ignorieren sollten, da schraubenartiges System, hübscher Code, Ihr System automatisch robust macht. Solche Überlegungen erklären auch, warum so viele Java-Codierer freiwillig ihren Code in XML-Dateien verschieben (Spring, Maven usw.). Ich vermisse jedoch den hübschen Teil hier.

Der von M. Odersky unter http://www.scala-lang.org/old/node/8787.html angegebene Grund für das Fehlen geprüfter Ausnahmen in Scala ist nicht überraschend anders und sinnvoll.

Das Problem mit aktivierten Ausnahmen lässt sich am besten anhand der Kartenmethode in Listen veranschaulichen:

def map[B](f: A => B): List[B]

Wie kommentiere ich eine Karte mit @throws? Wenn map selbst keine @ throws-Annotation erhält, können Sie ihr vermutlich keine Funktion mit einem @ throws übergeben. Dies würde zu umständlichen Einschränkungen und Unterscheidungen bei der Verwendung der Karte führen. Die Dinge wären besser, wenn wir irgendwie sagen könnten, dass map alle Ausnahmen auslöst, die sein Funktionsargument auslöst. Es gibt einige Effektsysteme, die dies ausdrücken können, aber bisher ist jede Notation, die ich gesehen habe, zu schwer.

Lukas Rytz forscht an leichten Effektsystemen, mit denen sich die Art der Karte und andere häufig verwendete Funktionen präzise und präzise ausdrücken lassen. Es ist Forschung, daher ist derzeit unklar, inwieweit wir erfolgreich sein werden und wie viel davon in Scala fließen kann. Idealerweise können wir es irgendwann als optionales Typsystem hinzufügen. Für konkrete Vorhersagen ist es jedoch viel zu früh.

Prost

Ich bin mir nicht sicher, aber ich denke, dass Java 8-Lambdas auch auf ungeprüfte Ausnahmen beschränkt sind.Methoden in den meisten (allen?) Neuen Funktionsschnittstellen in JDK 8 ( java.util.function.*) deklarieren auch keine ungeprüften Ausnahmen.

woky
quelle
2

Wenn Sie an Effizienz gewinnen wollen, müssen Sie aufgeben. Präzision / Kontrolle <- Ich brauche ein besseres Wort dafür.

Was die Abstraktion betrifft, befindet sich die Scala ganz oben. Wenn eines der Ziele von Scala darin besteht, lästigen Kesselcode loszuwerden, ist Javas Ausnahmebehandlung ein naheliegender Ort. Wenn Sie schnellen Code in Java schreiben möchten, werfen Sie einfach Ihre aktivierten Ausnahmen so lange hoch, bis sie eintreffen main()und effektiv deaktiviert werden.

Ich weiß nicht, ob ich genau das finde, wonach Sie fragen, aber dies ist meiner Meinung nach der offensichtlichste Grund.

Nun, ich habe ein bisschen nachgesehen und jemand hat über die Tragödie der Scheckausnahmen geschrieben .

David Cowden
quelle