873 Stimmen

Ist die Scala 2.8-Sammlungsbibliothek ein Fall von "dem längsten Selbstmordbrief in der Geschichte"?

Ich habe gerade erst begonnen, mir die Neuimplementierung der Scala-Sammlungsbibliothek anzuschauen, die mit dem bevorstehenden 2.8-Release kommt. Diejenigen, die mit der Bibliothek aus 2.7 vertraut sind, werden feststellen, dass sich die Bibliothek aus einer Verwendungs-Perspektive wenig geändert hat. Zum Beispiel...

> List("Paris", "London").map(_.length)
res0: List[Int] List(5, 6)

...würde in beiden Versionen funktionieren. Die Bibliothek ist äußerst benutzerfreundlich: tatsächlich ist sie fantastisch. Allerdings müssen sich diejenigen, die früher nicht mit Scala vertraut waren und sich jetzt umsehen, um ein Gefühl für die Sprache zu bekommen, nun mit Methodensignaturen auseinandersetzen wie:

def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That

Für eine so einfache Funktionalität ist dies eine einschüchternde Signatur, bei der ich mich selbst dabei erwische, dass ich Schwierigkeiten habe, sie zu verstehen. Nicht, dass ich glaube, dass Scala jemals wahrscheinlich der nächste Java sein würde (oder /C/C++/C#) - ich glaube nicht, dass seine Schöpfer es auf diesen Markt abgesehen hatten - aber ich denke, dass es sicherlich möglich war/ist, dass Scala der nächste Ruby oder Python wird (d.h. eine bedeutende kommerzielle Benutzerbasis zu gewinnen)

  • Wird das Leute davon abhalten, zu Scala zu kommen?
  • Wird das Scala einen schlechten Ruf in der kommerziellen Welt als akademische Spielerei geben, die nur dedizierte Doktoranden verstehen können? Werden CTOs und Leiter von Software abgeschreckt?
  • War die Neugestaltung der Bibliothek eine vernünftige Idee?
  • Wenn Sie Scala kommerziell verwenden, machen Sie sich darüber Sorgen? Planen Sie, sofort auf 2.8 umzusteigen oder abzuwarten, was passiert?

Steve Yegge griff einmal Scala an (meiner Meinung nach fälschlicherweise) für das, was er als sein überkompliziertes Typsystem ansah. Ich befürchte, dass jemand eine Freude daran haben wird, mit dieser API FUD zu verbreiten (ähnlich wie Josh Bloch die JCP davon abhielt, Closures zu Java hinzuzufügen).

Anmerkung - _Ich möchte klarstellen, dass ich zwar glaube, dass Joshua Bloch maßgeblich am Ablehnen des BGGA-Closures-Vorschlags beteiligt war, dies meiner Meinung nach jedoch nichts anderes als seinen aufrichtig überzeugten Überzeugungen zuzuschreiben ist, dass der Vorschlag einen Fehler darstellte._


Ungeachtet dessen, was meine Frau und meine Kollegen mir immer wieder sagen, glaube ich nicht, dass ich dumm bin: Ich habe einen guten Abschluss in Mathematik von der Universität Oxford und arbeite seit fast 12 Jahren beruflich als Programmierer und seit etwa einem Jahr (ebenfalls beruflich) in Scala.

_Beachten Sie, dass der provokante Betreff ein Zitat über das Manifest einer britischen politischen Partei aus den frühen 1980er Jahren ist. Diese Frage ist subjektiv, aber es handelt sich um eine ernsthafte Frage, ich habe sie zur Community-Wiki gemacht und würde gerne einige Meinungen dazu hören._

10 Stimmen

Fud steht einfach für Angst, Unsicherheit und Zweifel - ich denke, das drückt ganz klar den Ton von Josh Blochs Rede aus, der ich auch zufällig zustimme, ist gut argumentiert und durchdacht usw. Wenn Sie die Bearbeitungen sehen, habe ich ursprünglich kein fud geschrieben, weil ich keine negativen Konnotationen implizieren wollte.

3 Stimmen

Ich sollte sagen, dass ich es zurückgestellt habe, weil ich befürchte, dass FUD über Scala verbreitet wird und ich nur sage, dass dies ähnlich ist zu dem, was Bloch in seiner Präsentation gemacht hat. (Wo eines seiner Argumente war "Warum nicht einfach Scala verwenden")

2 Stimmen

Der BGGA-Vorschlag hatte einige Schwergewichte dahinter. Aus meiner Sicht schien es, als würden Josh Blochs Meinungen einen großen Teil seiner Ablehnung ausmachen. Ich könnte natürlich falsch liegen - aber mit dem Respekt, den er genießt, glaube ich, dass er enormen Einfluss hat. Ich wollte sicherlich nicht Bloch irgendwelche Unehrlichkeit zuschreiben - ich werde das klarstellen.

890voto

Martin Odersky Punkte 20380

Ich hoffe, es handelt sich nicht um einen "Abschiedsbrief", aber ich verstehe deinen Standpunkt. Du triffst damit genau das, was gleichzeitig eine Stärke und ein Problem von Scala ist: seine Erweiterbarkeit. Dadurch können wir die meisten wichtigen Funktionen in Bibliotheken implementieren. In einigen anderen Sprachen wären Sequenzen mit ähnlicher Funktionalität wie map oder collect bereits integriert, und niemand müsste alle Hürden sehen, die der Compiler nehmen muss, um sie reibungslos funktionieren zu lassen. In Scala ist alles in einer Bibliothek und daher offen einsehbar.

Tatsächlich ist die Funktionalität von map, die durch seinen komplexen Typ unterstützt wird, ziemlich fortgeschritten. Betrachte dies:

scala> import collection.immutable.BitSet
import collection.immutable.BitSet

scala> val bits = BitSet(1, 2, 3)
bits: scala.collection.immutable.BitSet = BitSet(1, 2, 3)

scala> val shifted = bits map { _ + 1 }
shifted: scala.collection.immutable.BitSet = BitSet(2, 3, 4)

scala> val displayed = bits map { _.toString + "!" }
displayed: scala.collection.immutable.Set[java.lang.String] = Set(1!, 2!, 3!)

Siehst du, wie du immer den bestmöglichen Typ erhältst? Wenn du Ints in Ints umwandelst, bekommst du wieder ein BitSet, aber wenn du Ints in Strings umwandelst, bekommst du eine generelle Set. Sowohl der statische Typ als auch die Laufzeitdarstellung des Ergebnisses von map hängen vom Ergebnistyp der übergebenen Funktion ab. Und das funktioniert sogar, wenn das Set leer ist, so dass die Funktion nie angewendet wird! Soweit ich weiß, gibt es kein anderes Collection-Framework mit einer äquivalenten Funktionalität. Doch aus Benutzersicht ist dies so, wie es funktionieren soll.

Das Problem, das wir haben, ist, dass die ganzen cleveren Technologien, die dies möglich machen, in die Typsignaturen durchsickern, die groß und beängstigend werden. Aber vielleicht sollte einem Benutzer standardmäßig nicht die vollständige Typsignatur von map angezeigt werden? Wie wäre es, wenn sie nachschlagen würde, was map in BitSet bedeutet:

map(f: Int => Int): BitSet     (hier klicken für allgemeineren Typ)

In diesem Fall würden die Dokumentationen nicht lügen, denn aus Benutzersicht hat map tatsächlich den Typ (Int => Int) => BitSet. Doch map hat auch einen allgemeineren Typ, der durch Klicken auf einen anderen Link inspiziert werden kann.

Wir haben eine solche Funktionalität noch nicht in unseren Tools implementiert. Aber ich glaube, dass wir dies tun sollten, um die Leute nicht abzuschrecken und um nützlichere Informationen zu liefern. Mit solchen Tools sollten hoffentlich intelligente Frameworks und Bibliotheken nicht zu Abschiedsbriefen werden.

107 Stimmen

Ich fühle mich wie ein ungezogener Schuljunge! Vielen Dank, dass Sie sich die Zeit genommen haben, hier zu antworten. Ich denke, dass das Gleichgewicht der Antworten mir gezeigt hat, dass ich mir keine Sorgen machen muss; es wird genug Leute geben, die überhaupt nicht eingeschüchtert sind.

164 Stimmen

Nein, ich denke, du hattest absolut recht, diesen Punkt anzusprechen. Und andere Leute werden erschrocken sein, es sei denn, wir tun etwas dagegen.

33 Stimmen

Martin, ich finde deinen Vorschlag gut, vereinfachte Methodensignaturen anzuzeigen und die allgemeinen Details hinter einem Link zu verbergen.

226voto

Jörg W Mittag Punkte 349574

Ich habe keinen Doktortitel, noch irgendeine andere Art von Abschluss weder in Informatik noch in Mathematik, noch in der Tat in einem anderen Bereich. Ich habe keine Vorerfahrung mit Scala oder einer ähnlichen Sprache. Ich habe keine Erfahrung mit auch nur annähernd vergleichbaren Typsystemen. Tatsächlich ist die einzige Sprache, von der ich mehr als oberflächliche Kenntnisse habe und die überhaupt ein Typsystem hat, Pascal, das nicht gerade für sein ausgeklügeltes Typsystem bekannt ist. (Obwohl es Bereichstypen hat, die meines Wissens so gut wie keine andere Sprache hat, aber das ist hier nicht wirklich relevant.) Die anderen drei Sprachen, die ich kenne, sind BASIC, Smalltalk und Ruby, von denen keine ein Typsystem hat.

Und dennoch habe ich überhaupt kein Problem damit, die Signatur der map-Funktion zu verstehen, die Sie gepostet haben. Es sieht für mich aus wie so ziemlich die gleiche Signatur, die map in jeder anderen Sprache hat, die ich je gesehen habe. Der Unterschied ist, dass diese Version allgemeiner ist. Es sieht mehr wie eine C++ STL-Sache aus als, sagen wir, Haskell. Insbesondere abstrahiert es von der konkreten Sammlungstyp, indem es nur erfordert, dass das Argument 'IterableLike' ist, und abstrahiert auch von der konkreten Rückgabetyp, indem es nur erfordert, dass eine implizite Konvertierungsfunktion existiert, die 'etwas' aus dieser Sammlung von Ergebniswerten erstellen kann. Ja, das ist ziemlich komplex, aber es ist wirklich nur ein Ausdruck des allgemeinen Paradigmas der generischen Programmierung: gehen Sie nicht von etwas aus, was Sie nicht wirklich müssen.

In diesem Fall braucht map die Sammlung nicht tatsächlich, um eine Liste zu sein, geordnet zu sein oder sortierbar zu sein oder so etwas. Das einzige, worauf es map ankommt, ist, dass es Zugriff auf alle Elemente der Sammlung erhalten kann, eines nach dem anderen, aber in keiner bestimmten Reihenfolge. Und es muss nicht wissen, um welche Art von resultierender Sammlung es sich handelt, es muss nur wissen, wie man sie erstellt. Das ist also das, was seine Typsignatur erfordert.

Also anstelle von

map :: (a  b)  [a]  [b]

was die traditionelle Typsignatur für map ist, ist es verallgemeinert, um nicht eine konkrete List zu erfordern, sondern eher eine 'IterableLike'-Datenstruktur

map :: (IterableLike i, IterableLike j)  (a  b)  i  j

was dann weiter verallgemeinert wird, indem nur eine Funktion erforderlich ist, die das Ergebnis in die gewünschte Datenstruktur umwandeln kann:

map :: IterableLike i  (a  b)  i  ([b]  c)  c

Ich gebe zu, die Syntax ist etwas sperrig, aber die Semantik ist die gleiche. Im Grunde genommen beginnt es von

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

was die traditionelle Signatur für map ist. (Beachten Sie, wie aufgrund der objektorientierten Natur von Scala der Eingabelistenparameter verschwindet, da es nun der implizite Empfängerparameter ist, den jede Methode in einem Einzelaufruf-OO-System hat.) Dann verallgemeinert es von einer konkreten 'Liste' zu einem allgemeineren 'IterableLike'

def map[B](f: (A)  B): IterableLike[B]

Jetzt ersetzt es die 'IterableLike'-Ergebnissammlung durch eine Funktion, die 'produziert', nun ja, so ziemlich alles.

def map[B, That](f: A  B)(implicit bf: CanBuildFrom[Repr, B, That]): That

Was ich wirklich glaube, ist nicht so schwer zu verstehen. Es gibt wirklich nur ein paar intellektuelle Werkzeuge, die Sie benötigen:

  1. Sie müssen (ungefähr) wissen, was 'map' ist. Wenn Sie nur die Typsignatur ohne den Namen der Methode gegeben hätten, gebe ich zu, es wäre viel schwieriger herauszufinden, was los ist. Aber da Sie bereits wissen, was 'map' tun soll, und Sie wissen, wie die Typsignatur aussehen soll, können Sie schnell die Signatur durchsuchen und sich auf Anomalien konzentrieren, wie "warum nimmt dieses 'map' zwei Funktionen als Argumente, nicht eine?"
  2. Sie müssen in der Lage sein, die Typsignatur tatsächlich zu 'lesen'. Aber selbst wenn Sie noch nie zuvor Scala gesehen haben, sollte dies recht einfach sein, da es wirklich nur eine Mischung aus Typsyntaxen ist, die Sie bereits aus anderen Sprachen kennen: VB.NET verwendet eckige Klammern für den parametrischen Polymorphismus und verwendet einen Pfeil, um den Rückgabetyp anzugeben, und ein Doppelpunkt trennt Namen und Typ, was eigentlich die Norm ist.
  3. Sie müssen ungefähr wissen, worum es bei der generischen Programmierung geht. (Was nicht so schwer zu verstehen ist, da es im Grunde genommen alles im Namen steht: Es ist buchstäblich nur das Programmieren auf generische Weise).

Keines dieser drei sollte einem professionellen Programmierer oder auch nur einem Hobbyprogrammierer ernsthafte Kopfschmerzen bereiten. 'map' ist eine Standardfunktion in so gut wie jeder Sprache, die in den letzten 50 Jahren entworfen wurde, die Tatsache, dass verschiedene Sprachen eine unterschiedliche Syntax haben, sollte für jeden offensichtlich sein, der eine Website mit HTML und CSS entworfen hat, und Sie können sich nicht für eine auch nur entfernt programmbezogene Mailingliste anmelden, ohne dass Ihnen irgend so ein nerviger C++-Fanboy von der Kirche des hl. Stepanov die Vorzüge der generischen Programmierung erklärt.

Ja, Scala ist komplex. Ja, Scala hat eines der anspruchsvollsten Typsysteme, die dem Menschen bekannt sind, die sogar Sprachen wie Haskell, Miranda, Clean oder Cyclone übertreffen. Aber wenn Komplexität ein Argument gegen den Erfolg einer Programmiersprache wäre, wäre C++ schon lange tot, und wir würden alle Scheme schreiben. Es gibt viele Gründe, warum Scala höchstwahrscheinlich nicht erfolgreich sein wird, aber die Tatsache, dass Programmierer sich nicht die Mühe machen wollen, ihre Gehirne einzuschalten, bevor sie sich vor die Tastatur setzen, wird wahrscheinlich nicht der Hauptgrund sein.

1 Stimmen

Viele C++ Programmierer beginnen als C Programmierer, wissend von C++, was dem von Java entspricht, und kämpfen endlos darum, zu verhindern, dass komplexere Funktionen ihren Weg blockieren. Das Scala-Typsystem ist in Relation zu System F_omega<:, das keineswegs einfach ist. Schließlich denke ich nicht, dass der Zweifel über die Standard-Map-Signatur war, sondern über CanBuildFrom. Behaupten Sie denn, dass das auch trivial ist? Eine kleine Anmerkung ist, dass IterableLike nicht dazu gedacht ist, Teil von Schnittstellen zu sein, sondern nur Implementierungen bereitzustellen. Die aussagekräftigste Annäherung ist Iterable (oder tatsächlich sogar Traversable).

1 Stimmen

@Jörg W Mittag Du bist ein viel klügerer Programmierer als die meisten. Das Problem, denke ich, liegt im mentalen Chunking dessen, was passiert. Das Typsystem von Scala ist fast eine Programmiersprache für sich. Syntax spielt eine Rolle. Es fällt Menschen schwer, sich die Syntax zu merken.

2 Stimmen

@Adam Gent: Tatsächlich ist das Typsystem von Scala Turing-vollständig, daher kann man argumentieren, dass es nicht nur "fast" eine Programmiersprache ist. (Es wird jedoch im Allgemeinen nicht als Programmiersprache verwendet. Tatsächlich ist der einzige Fall, den ich gesehen habe, in dem das Typsystem von Scala verwendet wurde, um ein Programm zu implementieren, der Blogbeitrag, der seine Turing-Vollständigkeit durch die Implementierung eines Interpreter für den Typ-Ebene SKI-Kalkül beweist.)

175voto

skyde Punkte 2601

Dasselbe in C++:

template

105 Stimmen

...und sie sagen, Scala ist obskur. Äh!

24 Stimmen

Stell dir nur vor, wie es ausgesehen hätte, wenn anstelle von willkürlichen Großbuchstaben ordentliche, selbsterklärende Bezeichner verwendet worden wären. :-)

14 Stimmen

Es ist nützlich, diesen Vergleich zu sehen, aber es wäre fairer, wenn die Umsetzung weggelassen würde.

71voto

Daniel C. Sobral Punkte 290004

Nun, ich kann deinen Schmerz verstehen, aber ganz ehrlich, Leute wie du und ich - oder so ziemlich jeder normale Stack Overflow Benutzer - sind nicht die Regel.

Was ich damit meine ist, dass... die meisten Programmierer sich nicht um diese Art von Typ-Signatur kümmern werden, weil sie sie nie sehen werden! Sie lesen keine Dokumentation.

Solange sie ein Beispiel davon gesehen haben, wie der Code funktioniert, und der Code sie nicht im Erzeugen des erwarteten Ergebnisses enttäuscht, werden sie niemals die Dokumentation ansehen. Wenn das scheitert, werden sie die Dokumentation überprüfen und erwarten, Beispielnutzungen oben zu sehen.

Unter Berücksichtigung dieser Dinge denke ich, dass:

  1. Jeder (das heißt, die meisten Leute), der jemals auf diese Typ-Signatur stößt, wird Scala ohne Ende verspotten, wenn sie bereits gegen Scala voreingenommen sind, und werden es als ein Symbol für die Stärke von Scala betrachten, wenn sie Scala mögen.

  2. Wenn die Dokumentation nicht verbessert wird, um Beispiele zur Nutzung zu bieten und klar zu erklären, wofür eine Methode gedacht ist und wie man sie benutzt, kann dies der Verbreitung von Scala ein wenig abträglich sein.

  3. Auf lange Sicht wird es keine Rolle spielen. Dass Scala so etwas kann, wird Bibliotheken, die für Scala geschrieben sind, viel leistungsfähiger und sicherer machen. Diese Bibliotheken und Frameworks werden Programmierer anziehen, die leistungsfähige Werkzeuge bevorzugen.

  4. Programmierer, die Einfachheit und Direktheit mögen, werden weiterhin PHP oder ähnliche Sprachen nutzen.

Ach ja, Java-Programmierer stehen sehr auf leistungsfähige Werkzeuge, daher habe ich gerade meine Erwartung in Bezug auf die Verbreitung von Scala in der breiten Masse überarbeitet. Ich habe überhaupt keine Zweifel daran, dass Scala eine Mainstream-Sprache werden wird. Nicht C-Mainstream, aber vielleicht Perl-Mainstream oder PHP-Mainstream.

Übrigens, hast du jemals den Klassenloader in Java ersetzt? Hast du jemals recherchiert, was das bedeutet? Java kann beängstigend sein, wenn man sich ansieht, was Framework-Entwickler tun. Es ist nur so, dass die meisten Leute das nicht tun. Das Gleiche trifft meiner Meinung nach auf Scala zu, aber Frühannahmende haben die Tendenz, jeden Stein umzudrehen, dem sie begegnen, um zu sehen, ob dort etwas versteckt ist.

10 Stimmen

Solange sie ein Beispiel dafür sehen, wie der Code funktioniert, und der Code sie nicht im Erstellen des erwarteten Ergebnisses enttäuscht, werden sie niemals die Dokumentation betrachten. Wenn das fehlschlägt, werden sie die Dokumentation konsultieren und erwarten, Beispiele zur Verwendung oben zu sehen. Traurig aber wahr.

9 Stimmen

@gamliela, Ich denke nicht, dass wir darüber traurig sein sollten. Wissen hat immer mehr als eine Ebene, auf die es angewendet werden kann, und die Arbeit und das Vertrauen anderer (peer-reviewed) in jedes System können immer genutzt werden, genauso wie wir täglich die Arithmetik nutzen und völlig ignoriert, wie die erschreckenden Algebra dahinter funktionieren.

55voto

Erik Engbrecht Punkte 3174

Wird dies die Leute davon abhalten, nach Scala zu kommen?

Ja, aber es wird auch verhindern, dass die Leute abgeschreckt werden. Ich habe den Mangel an Kollektionen, die höherwertige Typen verwenden, seit Scala die Unterstützung für höherwertige Typen erhalten hat, als eine wesentliche Schwäche betrachtet. Es macht die API-Dokumentation komplizierter, aber es macht die Verwendung wirklich natürlicher.

Wird dies Scala in der kommerziellen Welt einen schlechten Ruf als eine akademische Spielerei geben, die nur dedizierte Doktoranden verstehen können? Werden sich CTOs und Softwareleiter abschrecken lassen?

Einige werden es wahrscheinlich tun. Ich glaube nicht, dass Scala für viele "professionelle" Entwickler zugänglich ist, teilweise aufgrund der Komplexität von Scala und teilweise aufgrund der Unwilligkeit vieler Entwickler zu lernen. Die CTOs, die solche Entwickler beschäftigen, werden zu Recht abgeschreckt sein.

War die Neugestaltung der Bibliothek eine vernünftige Idee?

Auf jeden Fall. Es lässt die Kollektionen viel besser mit dem Rest der Sprache und dem Typsystem zusammenpassen, auch wenn es noch einige raue Kanten hat.

Wenn Sie Scala kommerziell nutzen, machen Sie sich Sorgen darüber? Planen Sie, 2.8 sofort zu übernehmen oder abzuwarten, was passiert?

Ich benutze es nicht kommerziell. Ich werde wahrscheinlich warten, bis mindestens ein paar Versionen der 2.8.x-Serie herausgekommen sind, bevor ich überhaupt versuche, es einzuführen, damit die Fehler behoben werden können. Ich werde auch abwarten, wie erfolgreich EPFL in der Verbesserung seiner Entwicklung und Release-Prozesse ist. Was ich sehe, sieht hoffnungsvoll aus, aber ich arbeite für ein konservatives Unternehmen.

Zum allgemeineren Thema "Ist Scala zu kompliziert für Mainstream-Entwickler?"...

Die meisten Entwickler, mainstream oder nicht, warten bestehende Systeme oder erweitern sie. Das bedeutet, dass das meiste, was sie verwenden, durch Entscheidungen bestimmt wird, die vor langer Zeit getroffen wurden. Es gibt immer noch viele Leute, die COBOL schreiben.

Der Mainstream-Entwickler von morgen wird damit beschäftigt sein, die Anwendungen zu warten und zu erweitern, die heute gebaut werden. Viele dieser Anwendungen werden nicht von Mainstream-Entwicklern gebaut. Die Mainstream-Entwickler von morgen werden die Sprache verwenden, die von den erfolgreichsten Entwicklern der heute neuen Anwendungen verwendet wird.

31 Stimmen

"Es wird auch verhindern, dass Leute abgeschreckt werden". Dies. Absolut. Scala ist die erste Sprache, die technisches Engineering mit etwas vergleichbarem wie Haskell (in der Leistung seines Typensystems) für viele von uns möglich macht. Es gibt keinen verdammten Weg, dass ich Arbeit überzeugen könnte, Haskell zu verwenden, aber Scala hat wirklich eine Chance und dafür liebe ich es und werde (wenn ich denke, dass es Sinn macht) versuchen, es bei der Arbeit zu übernehmen oder zumindest zu akzeptieren.

0 Stimmen

+1 von mir auch. Angesichts der Prämisse, dass Scala mehr Wert auf sprachliche Tiefe und Strenge als auf Massentauglichkeit legt, passen diese Antworten perfekt.

16 Stimmen

"Die zukünftigen Hauptentwickler werden die Sprache verwenden, die heute von den erfolgreichsten Entwicklern neuer Anwendungen verwendet wird." +1. Brillant gesagt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X