Ist die Scala 2.8-Sammlungsbibliothek ein Fall von „der längsten Selbstmordnotiz in der Geschichte“? [geschlossen]

873

Ich habe gerade angefangen, mir die Neuimplementierung der Scala-Sammlungsbibliothek anzusehen, die in der bevorstehenden Version 2.8 verfügbar sein wird. Diejenigen, die mit der Bibliothek ab 2.7 vertraut sind, werden feststellen, dass sich die Bibliothek aus Sicht der Nutzung kaum verändert hat. Zum Beispiel...

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

... würde in beiden Versionen funktionieren. Die Bibliothek ist hervorragend nutzbar : Tatsächlich ist sie fantastisch. Diejenigen, die Scala bisher nicht kannten und sich umschauten, um ein Gefühl für die Sprache zu bekommen, müssen nun Methodensignaturen wie:

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

Für solch eine einfache Funktionalität ist dies eine entmutigende Signatur, die ich nur schwer verstehen kann. Nicht, dass ich denke, dass Scala jemals das nächste Java (oder / C / C ++ / C #) sein würde - ich glaube nicht, dass seine Entwickler es auf diesen Markt abzielten - aber ich denke, dass es für Scala durchaus machbar ist / war der nächste Ruby oder Python (dh um eine bedeutende kommerzielle Benutzerbasis zu gewinnen)

  • Wird dies die Leute davon abhalten, nach Scala zu kommen?
  • Wird dies Scala in der Geschäftswelt einen schlechten Ruf als akademisches Spielzeug geben , das nur engagierte Doktoranden verstehen können? Werden CTOs und Leiter von Software Angst bekommen?
  • War die Neugestaltung der Bibliothek eine vernünftige Idee?
  • Wenn Sie Scala kommerziell nutzen, machen Sie sich darüber Sorgen? Planen Sie die sofortige Einführung von 2.8 oder warten Sie ab, was passiert?

Steve Yegge hat Scala einmal angegriffen (meiner Meinung nach fälschlicherweise), weil er es als sein überkompliziertes Typsystem ansah . Ich mache mir Sorgen, dass jemand einen Feldtag haben wird, an dem FUD mit dieser API verbreitet wird (ähnlich wie Josh Bloch die JCP davon abgehalten hat, Java-Schließungen hinzuzufügen).

Anmerkung - Ich sollte klar sein, dass Joshua Bloch, obwohl ich glaube, dass er Einfluss auf die Ablehnung des BGGA-Schließungsvorschlags hatte, nichts anderes zuschreibt als seine ehrliche Überzeugung, dass der Vorschlag einen Fehler darstellt.


Trotz was meine Frau und Kollegen mich immer wieder sagen, ich glaube nicht , ich bin ein Idiot: Ich habe einen guten Abschluss habe in Mathematik an der University of Oxford , und ich habe die Programmierung im Handel für fast 12 Jahre und in Scala für ca. ein Jahr (auch kommerziell).

Beachten Sie, dass der Titel des entzündlichen Themas ein Zitat über das Manifest einer britischen politischen Partei in den frühen 1980er Jahren ist . Diese Frage ist subjektiv, aber es ist eine echte Frage, ich habe sie CW gemacht und ich hätte gerne einige Meinungen zu diesem Thema.

oxbow_lakes
quelle
10
Fud steht nur für Angst, Unsicherheit und Zweifel - ich denke, das drückt den Ton von Josh Blochs Vortrag, dem ich auch zustimme, ganz klar aus, ist gut argumentiert und begründet usw. Wenn Sie die Änderungen sehen, habe ich Fud ursprünglich nicht gesetzt, weil Ich wollte nicht
-ve
32
Diese Frage wurde in Martin Oderskys
Binil Thomas
7
Was ich an Scala liebe, ist, dass man das komplexe Typensystem nicht verstehen muss, um einfache und elegante Dinge zu tun. Die Syntax kann entmutigend sein, aber sie versichert Ihnen eines: Es gibt keine "Magie", z. B. ist die Magie Teil der Sprache. Es ist ein sehr mutiger und kluger Ansatz. Ich denke, Sie haben eine Sprache, die neue DSLs und neue Mini erstellen kann Sprachen an sich, ja, mit den falschen Händen Scala kann eine sehr gute Ergänzung zu Ihrem italienischen Abendessen sein, aber sobald Sie sich daran gewöhnt haben, ist es eine erstaunliche Sprache
Eran Medan
87
Wie kann diese Frage "nicht konstruktiv" sein, wenn sie dazu führt, dass @MartinOdersky die Benutzerfreundlichkeit von Scala neu bewertet und das Dokumentationssystem Systemdetails verbirgt, ganz zu schweigen von einer aufschlussreichen Diskussion?
Jerry101
14
In der Tat ist SO nur aus technischen Gründen mit dem richtigen Format. Wenn Sie etwas Feines, Faszinierendes und Weitreichendes haben, schauen Sie bitte woanders hin. Es lebe die bürokratische Mentalität.
Qed

Antworten:

892

Ich hoffe, es ist kein "Abschiedsbrief", aber ich kann Ihren Standpunkt verstehen. Sie treffen auf das, was gleichzeitig eine Stärke und ein Problem von Scala ist: seine Erweiterbarkeit . Auf diese Weise können wir die meisten wichtigen Funktionen in Bibliotheken implementieren. In einigen anderen Sprachen sind Sequenzen mit so etwas wie mapoder collecteingebaut, und niemand muss alle Rahmen sehen, die der Compiler durchlaufen muss, damit sie reibungslos funktionieren. In Scala ist alles in einer Bibliothek und daher im Freien.

Tatsächlich ist die Funktionalität map, die durch seinen komplizierten Typ unterstützt wird, ziemlich fortgeschritten. Bedenken Sie:

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!)

Sehen Sie, wie Sie immer den bestmöglichen Typ erhalten? Wenn Sie Ints auf Ints abbilden , erhalten Sie erneut a BitSet, aber wenn Sie Ints auf Strings abbilden , erhalten Sie einen General Set. Sowohl der statische Typ als auch die Laufzeitdarstellung des Kartenergebnisses hängen vom Ergebnistyp der Funktion ab, die an das Ergebnis übergeben wird. Und das funktioniert auch, wenn das Set leer ist, so dass die Funktion nie angewendet wird! Soweit ich weiß, gibt es kein anderes Sammlungsframework mit einer entsprechenden Funktionalität. Aus Anwendersicht sollen die Dinge jedoch so funktionieren.

Das Problem, das wir haben, ist, dass all die clevere Technologie, die dies ermöglicht, in die Typensignaturen eindringt, die groß und beängstigend werden. Aber vielleicht sollte einem Benutzer nicht standardmäßig die vollständige Typensignatur von angezeigt werden map? Wie wäre es, wenn sie aufblickte mapin BitSetsie bekam:

map(f: Int => Int): BitSet     (click here for more general type)

Die Dokumente würden in diesem Fall nicht lügen, da aus Anwendersicht tatsächlich map den Typ hat (Int => Int) => BitSet. Hat aber mapauch einen allgemeineren Typ, der durch Klicken auf einen anderen Link überprüft werden kann.

Wir haben solche Funktionen noch nicht in unsere Tools implementiert. Aber ich glaube, wir müssen dies tun, um die Leute nicht abzuschrecken und nützlichere Informationen zu geben. Mit solchen Tools werden hoffentlich intelligente Frameworks und Bibliotheken nicht zu Selbstmordnotizen.

Martin Odersky
quelle
107
Ich fühle mich wie ein ungezogener Schüler! Vielen Dank, dass Sie sich die Zeit genommen haben, hier zu antworten. Ich denke, dass die Ausgewogenheit der Antworten mir gezeigt hat, dass ich mir keine Sorgen machen muss. Es wird genug Leute geben, die überhaupt nicht eingeschüchtert sind.
oxbow_lakes
164
Nein, ich denke, Sie hatten absolut Recht, diesen Punkt zu treffen. Und andere Menschen werden Angst haben, wenn wir nichts dagegen unternehmen.
Martin Odersky
33
Martin, ich mag Ihren Vorschlag, eine vereinfachte Methodensignatur anzuzeigen und die allgemeinen Details hinter einem Link zu verbergen.
Derek Mahar
18
Ich denke, eine Lösung, die mindestens genauso gut funktionieren würde, sind mehr Erklärungen in den Dokumenten. Ich würde die Signaturen nicht so einschüchternd finden, wenn nicht die meisten Methoden (und sogar die meisten Klassen) nicht mehr als einen einzigen Satz hätten, der ihren Zweck und ihre Funktionsweise beschreibt.
Nick Johnson
98
Update: Die endgültige Version von Scala 2.8 verfügt über einen Mechanismus wie den von mir beschriebenen. Wenn Sie BitSet in den Skaladocs nachschlagen, finden Sie: def map [B] (f: (Int) ⇒ B): BitSet [B] [Anwendungsfall] Erstellt eine neue Sammlung, indem eine Funktion auf alle Elemente dieses Bitsets angewendet wird.
Martin Odersky
226

Ich habe weder einen Doktortitel noch einen anderen Abschluss, weder in CS noch in Mathematik noch in einem anderen Bereich. Ich habe keine Vorkenntnisse mit Scala oder einer ähnlichen Sprache. Ich habe keine Erfahrung mit Systemen, die auch nur aus der Ferne vergleichbar sind. In der Tat, die einzige Sprache , die ich mehr als nur eine oberflächliche Kenntnis von der selbst hat eine Art System ist Pascal, nicht gerade für sein hoch entwickelten Typ - System bekannt. (Es gibt zwar Bereichstypen, die AFAIK 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 sogar ein Typensystem hat.

Und dennoch habe ich keinerlei Probleme, die Signatur der von mapIhnen geposteten Funktion zu verstehen . Es sieht für mich so ziemlich nach der gleichen Signatur aus, mapdie ich in jeder anderen Sprache gesehen habe. Der Unterschied ist, dass diese Version allgemeiner ist. Es sieht eher nach einer C ++ STL-Sache aus als beispielsweise nach Haskell. Insbesondere wird vom konkreten Auflistungstyp abstrahiert, indem nur das Argument verlangt wird IterableLike, und vom konkreten Rückgabetyp wird abstrahiert, indem nur eine implizite Konvertierungsfunktion benötigt wird, die etwas aus dieser Sammlung von Ergebniswerten aufbauen kann . Ja, das ist ziemlich komplex, aber es ist wirklich nur ein Ausdruck des allgemeinen Paradigmas der generischen Programmierung: Nehmen Sie nichts an, was Sie eigentlich nicht müssen.

In diesem Fall muss die Sammlung mapnicht unbedingt eine Liste sein oder bestellt oder sortierbar sein oder ähnliches. Das einzige, was mapwichtig ist, ist, dass es nacheinander auf alle Elemente der Sammlung zugreifen kann, jedoch in keiner bestimmten Reihenfolge. Und es muss nicht wissen, was die resultierende Sammlung ist, es muss nur wissen, wie man sie erstellt. Das ist es also, was seine Typensignatur erfordert.

Also statt

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

Dies ist die traditionelle Typensignatur, für die mapkeine konkrete List, sondern nur eine IterableLikeDatenstruktur erforderlich ist

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

Dies wird dann weiter verallgemeinert, indem nur eine Funktion benötigt wird, die das Ergebnis in die vom Benutzer gewünschte Datenstruktur konvertieren kann :

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

Ich gebe zu, dass die Syntax etwas klobiger ist, aber die Semantik ist dieselbe. Grundsätzlich geht es von

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

Das ist die traditionelle Signatur für map. (Beachten Sie, dass der Eingabelistenparameter aufgrund der objektorientierten Natur von Scala verschwindet, da er nun der implizite Empfängerparameter ist, den jede Methode in einem OO-System mit einem Versand hat.) Dann wurde er von einem konkreten Listzu einem allgemeineren verallgemeinertIterableLike

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

Jetzt ersetzt es die IterableLikeErgebnissammlung durch eine Funktion, die wirklich fast alles erzeugt.

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 mapist. Wenn Sie nur die Typensignatur ohne den Namen der Methode angeben würden, wäre es viel schwieriger herauszufinden, was los ist. Da Sie jedoch bereits wissen, was mapzu tun ist, und wissen, wie die Typensignatur lauten soll, können Sie die Signatur schnell scannen und sich auf die Anomalien konzentrieren, z. B. "Warum werden mapzwei Funktionen als Argumente verwendet, nicht eine?"
  2. Sie müssen in der Lage sein, die Typensignatur tatsächlich zu lesen . Aber selbst wenn Sie Scala noch nie gesehen haben, sollte dies recht einfach sein, da es sich tatsächlich nur um eine Mischung von Typensyntaxen handelt, die Sie bereits aus anderen Sprachen kennen: VB.NET verwendet eckige Klammern für den parametrischen Polymorphismus und verwendet einen Pfeil, um das zu kennzeichnen Rückgabetyp und ein Doppelpunkt zur Trennung von Name und Typ sind eigentlich die Norm.
  3. Sie müssen ungefähr wissen, worum es bei der generischen Programmierung geht. (Was nicht so schwer herauszufinden ist, da im Grunde alles im Namen geschrieben steht: Es wird buchstäblich nur generisch programmiert).

Keiner dieser drei sollte einem professionellen oder sogar Hobby-Programmierer ernsthafte Kopfschmerzen bereiten. mapwar eine Standardfunktion in so ziemlich jeder Sprache, die in den letzten 50 Jahren entwickelt wurde. Die Tatsache, dass verschiedene Sprachen unterschiedliche Syntax haben, sollte für jeden offensichtlich sein, der eine Website mit HTML und CSS entworfen hat und Sie können nicht einmal eine Remote-Programmierung abonnieren verwandte Mailingliste ohne einen nervigen C ++ - Fanboy aus der Kirche St. Stepanov, der die Vorzüge der generischen Programmierung erklärt.

Ja, Scala ist komplex. Ja, Scala verfügt über eines der fortschrittlichsten Systeme, die dem Menschen bekannt sind und mit Sprachen wie Haskell, Miranda, Clean oder Cyclone konkurrieren und diese sogar übertreffen. Aber wenn Komplexität ein Argument gegen den Erfolg einer Programmiersprache wäre, wäre C ++ längst gestorben 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 können, ihr Gehirn einzuschalten, bevor sie sich vor die Tastatur setzen, wird wahrscheinlich nicht der Hauptgrund sein.

Jörg W Mittag
quelle
36
@ Jorg - das ist eine großartige Antwort; Vielen Dank. Unabhängig davon, ob Sie einen Abschluss haben oder nicht, Sie sind ein besserer Mann als ich. Das einzige Problem, das ich habe, ist, dass ich das breite Bild davon verstehe, was in der Methodensignatur vor sich geht. Die Details sind jedoch immer noch verwirrend: Wie wird Thatdarauf geschlossen und mit dem Typ verknüpft, Bist eine Frage, die mir in den Sinn kommt. Woher kommen die Implikationen, wenn man ein anderer ist? Auch ohne diese detaillierten Beobachtungen bin ich persönlich der Meinung, dass dies eine komplexe Signatur ist. Aber offensichtlich gibt es Leute wie Sie da draußen, die davon überhaupt nicht beeindruckt sind!
oxbow_lakes
50
Schöne Erklärung, aber Sie haben mich noch mehr davon überzeugt, dass die Signatur der Scala 2.8 "Map" -Methode sehr kompliziert ist.
Derek Mahar
11
Eine Sprache, die so aussieht: def map [B] (f: (A) ⇒ B): IterableLike [B] ist viel einladender als eine, die so aussieht: def map [B, That] (f: A ⇒ B. ) (implizit bf: CanBuildFrom [Repr, B, That]): That
Mark Essel
215
Ich finde es ziemlich interessant, dass Sie zunächst behaupten, nur Basic, Ruby und Smalltalk zu kennen, und weiterhin behaupten, dass Sie keinen akademischen Hintergrund in diesem Fach haben. ... und später Kenntnisse über die Komplexität von Typsystemen in Sprachen wie Miranda und Clean beanspruchen; Sprachen, die meist nur unter ernsthaften Programmiersprachenfreaks und Akademikern bekannt sind.
Sami
14
Sie haben einen gültigen Punkt, dass der Vergleich mit Haskell falsch ist, da "map :: (a -> b) -> [a] -> [b]" spezifisch für Listen ist. Die verallgemeinerte Version, die der Functor-Klasse, ist jedoch immer noch viel einfacher als die Scala-Version: Klasse Functor f wobei fmap :: (a -> b) -> fa -> fb
Orclev
175

Gleiches in C ++ :

template <template <class, class> class C,
          class T,
          class A,
          class T_return,
          class T_arg
              >
C<T_return, typename A::rebind<T_return>::other>
map(C<T, A> &c,T_return(*func)(T_arg) )
{
    C<T_return, typename A::rebind<T_return>::other> res;
    for ( C<T,A>::iterator it=c.begin() ; it != c.end(); it++ ){
        res.push_back(func(*it));
    }
    return res;
}
skyde
quelle
105
... und sie sagen, Scala ist dunkel. Duh!
fehlender Faktor
24
Stellen Sie sich vor, wie es ausgesehen hätte, wenn anstelle von willkürlichen Großbuchstaben die richtigen selbstbeschreibenden Bezeichner verwendet worden wären. :-)
Ti Strga
14
Es ist nützlich, diesen Vergleich zu sehen, aber es wäre fairer, wenn die Implementierung weggelassen würde.
Aaron Novstrup
2
Ich bin kein großer Fan des obligatorischen Funktionszeigers. Klar , dass die Art der funcsollte ein Template - Parameter sein, und Sie sollten verwenden result_ofund is_callabledie anderen Typen und beschränken die Überlastung Set passend :-) zu erhalten
Kerrek SB
1
Meine Augen tun weh !!!
Ashkan Kh. Nazary
71

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

Was ich damit meine ist, dass ... die meisten Programmierer sich nicht für diese Typensignatur interessieren, weil sie sie nie sehen werden ! Sie lesen keine Dokumentation.

Solange sie ein Beispiel für die Funktionsweise des Codes gesehen haben und der Code sie nicht daran hindert, das erwartete Ergebnis zu erzielen , werden sie sich die Dokumentation niemals ansehen. Wenn dies fehlschlägt, sehen sie sich die Dokumentation an und erwarten oben Anwendungsbeispiele .

In Anbetracht dieser Dinge denke ich, dass:

  1. Jeder (wie bei den meisten Menschen), der jemals auf diese Typensignatur stößt, wird Scala bis zum Äußersten verspotten, wenn er dagegen ist, und sie als Symbol für Scalas Macht betrachten, wenn er Scala mag.

  2. Wenn die Dokumentation nicht erweitert wird, um Verwendungsbeispiele bereitzustellen und klar zu erklären, wozu eine Methode dient und wie sie verwendet wird, kann dies die Einführung von Scala etwas beeinträchtigen.

  3. Auf lange Sicht wird es keine Rolle spielen. Diese Scala kann Dinge tun wie die Bibliotheken für die Scala viel leistungsfähiger und sicherer in der Anwendung geschrieben machen. Diese Bibliotheken und Frameworks werden Programmierer anziehen, die sich für leistungsstarke Tools interessieren.

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

Leider sind Java-Programmierer sehr an Elektrowerkzeugen interessiert. Als Antwort darauf habe ich gerade meine Erwartung einer allgemeinen Einführung von Scala revidiert. Ich habe überhaupt keinen Zweifel daran, dass Scala eine Mainstream-Sprache werden wird. Nicht C-Mainstream, sondern vielleicht Perl-Mainstream oder PHP-Mainstream.

Apropos Java, haben Sie jemals den Klassenlader ersetzt? Haben Sie jemals untersucht, worum es geht? Java kann beängstigend sein, wenn man sich die Orte ansieht, an denen Framework-Autoren arbeiten. Es ist nur so, dass die meisten Leute es nicht tun. Das Gleiche gilt für Scala, IMHO, aber Early Adopters neigen dazu, unter jeden Felsen zu schauen, auf den sie stoßen, um zu sehen, ob sich dort etwas versteckt.

Daniel C. Sobral
quelle
10
As long as they saw some example of how the code works, and the code doesn't fail them in producing the result they expect, they won't ever look at the documentation. When that fails, they'll look at the documentation and expect to see usage examples at the top.Traurig aber wahr.
Gamliela
9
@gamliela, ich glaube nicht, dass wir darüber traurig sein werden. Wissen muss immer auf mehr als einer Ebene angewendet werden, und die Arbeit und das Vertrauen anderer (Peer-Review) in jedes System können immer genutzt werden, genau wie wir täglich Arithmetik verwenden und die dahinter stehenden beängstigenden Algebren völlig ignorieren.
lcn
55

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

Ja, aber es verhindert auch, dass Menschen abgeschreckt werden. Ich habe das Fehlen von Sammlungen, in denen höherwertige Typen verwendet werden, als große Schwäche angesehen, seit Scala Unterstützung für höherwertige Typen erhalten hat. Dies macht die API-Dokumente komplizierter, macht die Verwendung jedoch natürlicher.

Wird dies Scala in der Geschäftswelt einen schlechten Ruf als akademisches Spielzeug geben, das nur engagierte Doktoranden verstehen können? Werden CTOs und Software-Leiter Angst bekommen?

Einige werden es wahrscheinlich tun. Ich denke nicht, dass Scala vielen "professionellen" Entwicklern zugänglich ist, teilweise aufgrund der Komplexität von Scala und teilweise aufgrund der mangelnden Lernbereitschaft vieler Entwickler. Die CTOs, die solche Entwickler beschäftigen, werden zu Recht abgeschreckt sein.

War die Neugestaltung der Bibliothek eine vernünftige Idee?

Absolut. Dadurch passen Sammlungen viel besser zum Rest der Sprache und zum Typensystem, auch wenn sie noch einige Ecken und Kanten aufweisen.

Wenn Sie Scala kommerziell verwenden, machen Sie sich darüber Sorgen? Planen Sie die sofortige Einführung von 2.8 oder warten Sie ab, was passiert?

Ich benutze es nicht kommerziell. Ich werde wahrscheinlich warten, bis mindestens ein paar Umdrehungen in der 2.8.x-Serie sind, bevor ich überhaupt versuche, sie einzuführen, damit die Fehler beseitigt werden können. Ich werde auch abwarten, wie viel Erfolg EPFL bei der Verbesserung seiner Entwicklungs- und Release-Prozesse hat. Was ich sehe, sieht hoffnungsvoll aus, aber ich arbeite für ein konservatives Unternehmen.

Eines der allgemeineren Themen von "Ist Scala für Mainstream-Entwickler zu kompliziert?" ...

Die meisten Mainstream- oder sonstigen Entwickler warten oder erweitern vorhandene Systeme. Dies bedeutet, dass das meiste, was sie verwenden, von Entscheidungen bestimmt wird, die vor langer Zeit getroffen wurden. Es gibt immer noch viele Leute, die COBOL schreiben.

Der Mainstream-Entwickler von morgen wird daran arbeiten, die heute erstellten Anwendungen zu warten und zu erweitern. Viele dieser Anwendungen werden nicht von Mainstream-Entwicklern erstellt. Die Mainstream-Entwickler von morgen werden die Sprache verwenden, die von den erfolgreichsten Entwicklern neuer Anwendungen von heute verwendet wird.

Erik Engbrecht
quelle
31
"Es wird auch verhindern, dass Menschen abgeschreckt werden". diese. absolut. scala ist die erste Sprache, die das Engineering mit etwas vergleichbarem mit haskell (in der Kraft seines Typsystems) für viele von uns zu einer Möglichkeit macht. Es gibt keine Möglichkeit, die Arbeit davon zu überzeugen, Haskell zu verwenden, aber Scala hat wirklich eine Chance und dafür liebe ich es und werde (wenn ich es für sinnvoll halte) versuchen, es zu übernehmen oder zumindest zu akzeptieren. bei der Arbeit.
Andrew Cooke
+1 auch von mir. Angesichts der Prämisse, dass Scala mehr Wert auf sprachliche Tiefe und Genauigkeit legt als auf die Annäherung an die Masse, passen diese Antworten perfekt zusammen.
Carl Smotricz
16
"Die Mainstream-Entwickler von morgen werden die Sprache verwenden, die von den erfolgreichsten Entwicklern neuer Anwendungen von heute verwendet wird." +1. Genial gesagt.
Vasil Remeniuk
46

Eine Möglichkeit, wie die Scala-Community dazu beitragen kann, die Angst vor Programmierern, die neu in Scala sind, zu lindern, besteht darin, sich auf das Üben zu konzentrieren und anhand von Beispielen zu lehren - viele Beispiele, die klein anfangen und allmählich größer werden. Hier sind einige Websites, die diesen Ansatz verfolgen:

Nachdem man einige Zeit auf diesen Websites verbracht hat, stellt man schnell fest, dass Scala und seine Bibliotheken, obwohl sie möglicherweise schwer zu entwerfen und zu implementieren sind, nicht so schwierig zu verwenden sind, insbesondere in den üblichen Fällen.

Derek Mahar
quelle
43

Ich habe einen Bachelor-Abschluss von einer billigen "Massenmarkt" -Universität in den USA, also würde ich sagen, dass ich in die Mitte der User Intelligence- (oder zumindest Bildungs-) Skala falle :) Ich habe mich erst seit ein paar Monaten mit Scala beschäftigt und haben an zwei oder drei nicht trivialen Apps gearbeitet.

Besonders jetzt, da IntelliJ ihre feine IDE mit dem meiner Meinung nach derzeit besten Scala-Plugin veröffentlicht hat, ist die Scala-Entwicklung relativ schmerzlos:

  • Ich finde, ich kann Scala als "Java ohne Semikolons" verwenden, dh ich schreibe ähnlich aussehenden Code wie in Java und profitiere ein wenig von syntaktischer Kürze, wie sie durch Typinferenz gewonnen wird. Wenn ich es überhaupt mache, ist die Ausnahmebehandlung bequemer. Die Klassendefinition ist ohne das Getter / Setter-Boilerplate viel weniger ausführlich.

  • Hin und wieder schaffe ich es, eine einzelne Zeile zu schreiben, um das Äquivalent mehrerer Java-Zeilen zu erreichen. Gegebenenfalls macht es Spaß, Ketten funktionaler Methoden wie Map, Fold, Collect, Filter usw. zu komponieren und elegant anzusehen.

  • Nur selten profitiere ich von Scalas leistungsstärkeren Funktionen: Verschlüsse und Teil- (oder Curry-) Funktionen, Mustervergleich ... so etwas.

Als Neuling kämpfe ich weiterhin mit der knappen und idiomatischen Syntax. Methodenaufrufe ohne Parameter benötigen keine Klammern, außer dort, wo sie vorhanden sind. Fälle in der Übereinstimmungsanweisung benötigen einen fetten Pfeil ( =>), aber es gibt auch Stellen, an denen Sie einen dünnen Pfeil ( ->) benötigen . Viele Methoden haben kurze, aber eher kryptische Namen wie /:oder \:- ich kann meine Sachen erledigen, wenn ich genug manuelle Seiten umblättere, aber ein Teil meines Codes sieht am Ende wie Perl oder Zeilenrauschen aus. Ironischerweise fehlt eine der beliebtesten syntaktischen Abkürzungen in Aktion: Ich werde immer wieder von der Tatsache gebissen, dass Intkeine ++Methode definiert ist.

Dies ist nur meine Meinung: Ich glaube, Scala hat die Leistungsfähigkeit von C ++ in Kombination mit der Komplexität und Lesbarkeit von C ++. Die syntaktische Komplexität der Sprache macht es auch schwierig, die API-Dokumentation zu lesen.

Scala ist in vielerlei Hinsicht sehr gut durchdacht und brillant. Ich vermute, dass viele Akademiker gerne darin programmieren würden. Es ist jedoch auch voller Klugheit und Fallstricke, es hat eine viel höhere Lernkurve als Java und ist schwerer zu lesen. Wenn ich die Foren scanne und sehe, wie viele Entwickler immer noch mit den Feinheiten von Java zu kämpfen haben, kann ich mir nicht vorstellen, dass Scala jemals eine Mainstream-Sprache wird . Kein Unternehmen kann es rechtfertigen, seine Entwickler zu einem dreiwöchigen Scala-Kurs zu schicken, wenn sie früher nur einen einwöchigen Java-Kurs benötigten.

Carl Smotricz
quelle
9
Entschuldigung für alle Kommentare. 1 Woche ist ein Witz für praktisch jede Sprache, aber das hindert Manager nicht daran, diesen Witz in die Praxis umzusetzen. Ich hatte einmal 3 Tage Zeit, um eine Gruppe von C ++ - Entwicklern in Java zu "stürzen". Ich bat um 5 Tage, wurde aber aus Budgetgründen gekürzt.
Carl Smotricz
22
Für meinen ersten Job erhielt ich am Ende des Interviews ein C ++ - Buch zum Lernen, bevor ich am Montag mit der Arbeit begann. Ihr seid alle Trottel.
Tom Hawtin - Tackline
12
@ Tom @ Erik Ihr Jungs habt es einfach. Ich erhielt die Schaltpläne an den Computer (damals noch keine CPU) und sagte, ich hätte zwei Stunden Zeit, um einen Fehler als Interview zu beheben .
Daniel C. Sobral
33
@Daniel @Tom @Erik Ich erhielt einmal eine 0 und eine 1 und wurde gebeten, sie zu verwenden, um das Rucksackproblem in linearer Zeit während des Interviews zu lösen. Ich habe es ausprobiert, aber leider hatte ich nur Zeit, Eclipse zu erstellen (was meiner Meinung nach auf Rucksack reduziert werden kann). #tall_tale
Alex Miller
10
@Alex Das zeigt mangelnde Vorstellungskraft. Platzieren Sie eine große Null links und zwei weitere kleinere Nullen rechts: eine über der anderen, die obere leicht links. Platzieren Sie die Eins zwischen diesen beiden kleineren Nullen von links unten nach rechts oben. Angenommen, das ist die Chance, den Rucksack in linearer Zeit zu lösen. Dort bist du fertig. :-) +1 für die Gleichsetzung von Eclipse und Knapsack. :-)
Daniel C. Sobral
33

Ich denke, das Hauptproblem bei dieser Methode ist, dass das (implicit bf : CanBuildFrom[Repr, B, That])ohne Erklärung geht. Obwohl ich weiß, was implizite Argumente sind, gibt es keine Hinweise darauf, wie sich dies auf den Aufruf auswirkt. Das Jagen durch den Scaladoc macht mich nur verwirrter (nur wenige der Klassen, die sich darauf beziehenCanBuildFrom sogar Dokumentation).

Ich denke, ein einfaches "es muss ein implizites Objekt im Gültigkeitsbereich geben bf, das einen Builder für Objekte vom Typ Bin den Rückgabetyp liefert That" würde etwas helfen, aber es ist eine Art berauschendes Konzept, wenn alles, was Sie wirklich tun möchten, Map A's to ist B's. Tatsächlich bin ich mir nicht sicher, ob das richtig ist, da ich nicht weiß, was der Typ Reprund die Dokumentation dafür bedeutenTraversable gibt mit Sicherheit überhaupt keinen Hinweis.

Ich habe also zwei Möglichkeiten, von denen keine angenehm ist:

  • Angenommen, es funktioniert nur so, wie die alte Karte funktioniert und wie die Karte in den meisten anderen Sprachen funktioniert
  • Stöbern Sie noch etwas im Quellcode

Ich verstehe, dass Scala im Wesentlichen den Mut aufdeckt, wie diese Dinge funktionieren, und dass dies letztendlich eine Möglichkeit bietet, das zu tun, was oxbow_lakes beschreibt. Aber es ist eine Ablenkung in der Unterschrift.

davetron5000
quelle
2
Reprist die durchquerbare Darstellung, dh. Listoder Setoder Map. Ich denke, wenn Sie sich als Framework mit Methodensignaturen befassen möchten (anstatt nur die Methoden durch Kopieren von Beispielen zu verwenden), müssen Sie zuerst das allgemeine Design verstehen. IMHO sollte der Scaladoc voller Beispiele sein
oxbow_lakes
10
Wie hätte ich also festgestellt, was das Reprbedeutet? Ich würde eine Erklärung im Scaladoc erwarten, aber es war mir wirklich nicht klar. Ich denke, dies ist ein allgemeines Muster im Scaladoc (siehe Actor.reactund Actor.receive- mir wurde gesagt und ich habe gesehen, dass sie völlig unterschiedliche Dinge tun, aber ihr Scaladoc ist identisch).
davetron5000
7
Ich stimme davetron5000 zu. Ich bin mit Scala ziemlich vertraut, aber implizite Definitionen machen mir immer noch Kopfschmerzen. Und der Grund ist an sich nicht implizit, sondern wie sie verwendet werden. Es sollte auf jeden Fall eine bessere Dokumentation und Toolunterstützung zum Verständnis der Scala-Typen geben. Trotzdem denke ich, dass das Typensystem wirklich etwas Wichtiges zu bieten hat. Wir stehen aber erst am Anfang des Weges einer vernünftigen Programmierung.
Egaga
22

Ich bin ein Scala-Anfänger und sehe ehrlich gesagt kein Problem mit dieser Typensignatur. Der Parameter ist die zuzuordnende Funktion und der implizite Parameter der Builder, um die richtige Auflistung zurückzugeben. Klar und lesbar.

Das Ganze ist eigentlich ziemlich elegant. Mit den Builder-Typparametern kann der Compiler den richtigen Rückgabetyp auswählen, während der implizite Parametermechanismus diesen zusätzlichen Parameter vor dem Klassenbenutzer verbirgt. Ich habe es versucht:

Map(1 -> "a", 2 -> "b").map((t) => (t._2) -> (t._1)) // returns Map("a" -> 1, "b" -> 2)
Map(1 -> "a", 2 -> "b").map((t) =>  t._2)            // returns List("a", "b")

Das ist Polymorphismus, richtig gemacht.

Nun, zugegeben, es ist kein Mainstream-Paradigma und es wird viele abschrecken. Es wird aber auch viele anziehen, die Wert auf Ausdruckskraft und Eleganz legen.

Thomas Heywood
quelle
20

Leider ist die von Ihnen angegebene Signatur für die Karte falsch und es gibt in der Tat berechtigte Kritik.

Der erste Kritikpunkt ist, dass wir durch das Untergraben der Signatur für die Karte etwas allgemeineres haben. Es ist ein häufiger Fehler zu glauben, dass dies standardmäßig eine Tugend ist. Ist es nicht. Die Kartenfunktion ist sehr gut definiert als kovarianter Funktor Fx -> (x -> y) -> Fy unter Einhaltung der beiden Gesetze der Zusammensetzung und Identität. Alles andere, was "Karte" zugeschrieben wird, ist eine Travestie.

Die angegebene Signatur ist etwas anderes, aber keine Karte. Was ich vermute, ist eine spezialisierte und leicht veränderte Version der "Traverse" -Signatur aus dem Papier "The Essence of the Iterator Pattern". Hier ist seine Unterschrift:

traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)

Ich werde es in Scala umwandeln:

def traverse[A, B](f: A => F[B], a: T[A])(implicit t: Traversable[T], ap: Applicative[F]): F[T[B]

Natürlich scheitert es - es ist nicht allgemein genug! Es ist auch etwas anders (beachten Sie, dass Sie eine Karte erhalten können, indem Sie den Identity-Funktor durchlaufen). Ich vermute jedoch, dass wir diesen Fehler nicht sehen würden, wenn die Autoren der Bibliothek besser über gut dokumentierte Verallgemeinerungen der Bibliothek informiert wären (Applikative Programmierung mit Effekten geht den oben genannten voraus).

Zweitens ist die Kartenfunktion ein Sonderfall in Scala, da sie für das Verständnis verwendet wird. Dies bedeutet leider, dass ein besser ausgestatteter Bibliotheksdesigner diesen Fehler nicht ignorieren kann, ohne auch den syntaktischen Zucker des Verständnisses zu opfern. Mit anderen Worten, wenn die Designer der Scala-Bibliothek eine Methode zerstören sollten, wird dies leicht ignoriert, aber bitte nicht zuordnen!

Ich hoffe, jemand spricht darüber, denn so wie es ist, wird es schwieriger, die Fehler zu umgehen, auf die Scala besteht, anscheinend aus Gründen, gegen die ich starke Einwände habe. Das heißt, die Lösung für "die unverantwortlichen Einwände des durchschnittlichen Programmierers (dh zu hart!)" Ist nicht "sie zu beschwichtigen, um es ihnen leichter zu machen", sondern Hinweise und Unterstützung zu geben, um bessere Programmierer zu werden. Die Ziele von mir und Scala sind in dieser Frage umstritten, aber zurück zu Ihrem Punkt.

Sie haben wahrscheinlich Ihren Standpunkt klargestellt und bestimmte Antworten des "durchschnittlichen Programmierers" vorhergesagt. Das heißt, die Leute, die behaupten werden "aber es ist zu kompliziert!" oder solche. Dies sind die Yegges oder Blochs, auf die Sie sich beziehen. Meine Reaktion auf diese Leute der Anti-Intellektualismus / Pragmatismus-Bewegung ist ziemlich hart und ich erwarte bereits eine Flut von Antworten, also werde ich sie weglassen.

Ich hoffe wirklich, dass sich die Scala-Bibliotheken verbessern oder zumindest die Fehler sicher in einer Ecke versteckt werden können. Java ist eine Sprache, in der "der Versuch, etwas Nützliches zu tun" so unglaublich kostspielig ist, dass es sich oft nicht lohnt, weil die überwältigende Menge an Fehlern einfach nicht vermieden werden kann. Ich flehe Scala an, nicht den gleichen Weg zu gehen.

Tony Morris
quelle
3
Hallo Tony - danke für deinen nachdenklichen Beitrag hier. Ich würde 2 Antworten darauf geben. Das erste ist, dass ich den "durchschnittlichen Programmierer" nicht erwähnt habe und nicht glaube, dass Scala notwendigerweise auf einen ausgerichtet ist. Ob es von mir eingebildet ist oder nicht, ich glaube, ich bin überdurchschnittlich gut; Ich habe jedoch immer noch das Gefühl, dass die Typensignatur entmutigend ist! Mit anderen Worten, ich mache mir immer noch Sorgen, dass überdurchschnittliche Programmierer, Scalas Zielmarkt, vertrieben werden könnten.
oxbow_lakes
6
Der zweite Punkt ist, dass ich Ihnen grundsätzlich nicht zustimme, was Scala ist : Scala ist eine pragmatische Sprache - keine theoretisch reine. Warum sollte es sonst auf der JVM entworfen worden sein? Dies ist eine rein pragmatische Entscheidung - sie richtet sich an Entwickler "in der realen Welt" - eine Entscheidung, die möglicherweise Kompromisse erforderlich gemacht hat! Beachten Sie auch, dass Bloch und Yegge alles andere als durchschnittliche Programmierer sind - aber das ist mein Punkt. Selbst hoch angesehene und intelligente Menschen können Meinungen über Komplexität und Reinheit haben, die sich von Ihren unterscheiden. Leider sind sie auch sehr einflussreich für Sie.
oxbow_lakes
3
Hallo oxbow_lakes, es ist ein erklärtes Ziel von Scala, typische Programmierer zu beruhigen, auch auf Kosten der Genauigkeit und Praktikabilität. Überdurchschnittliche Programmierer werden vertrieben (ich habe mehrere Anekdoten), aber nicht, weil Typensignaturen entmutigend sind, sondern wegen der Art einiger Fehler. Ich habe nicht gesagt, dass Scala pragmatisch oder theoretisch ist oder nicht. Außerdem unterschreibe ich nicht einmal die (übliche?) Idee, dass eine solche Dichotomie existiert. Die Scala-Bibliotheken haben die Kartensignatur verschraubt. Ich arbeite seit Jahren an Scalas Fehlern. insbesondere die Bibliotheken. Zeit, es noch einmal zu tun.
Tony Morris
5
Ich halte Bloch oder Yegge nicht für hoch angesehen oder intelligent, aber sie sind in der Tat ziemlich einflussreich. Ja, das ist unglücklich.
Tony Morris
9
Warum beziehen Sie sich auf die erweiterte Signatur von Scala? Die Karte von Scala für Monofunktoren ist die Standard-FM-Karte. Aber weder BitSet noch Map [A, B] sind Monofunktoren, und Map hat eine aussagekräftige Definition. Das ist die Motivation von Scalas Unterschrift, und Traverse löst dieses Problem nicht. Warum ist Allgemeinheit eine schlechte Sache? Anwendbare Funktoren verfolgen Effekte. Was bringt es in Scala? Schließlich glaube ich, dass Scalas generische Karte in Form einer verallgemeinerten Traverse implementiert werden kann, indem ein CanBuildFrom akzeptiert und ein möglicherweise anderes Traversable zurückgegeben wird: Keine Notwendigkeit, für das Verständnis zu opfern!
Blaisorblade
15

Ich stimme sowohl der Frage als auch Martins Antwort voll und ganz zu :). Selbst in Java ist das Lesen von Javadoc mit Generika aufgrund des zusätzlichen Rauschens viel schwieriger als es sein sollte. Dies wird in Scala noch verstärkt, wo implizite Parameter wie im Beispielcode der Fragen verwendet werden (während die impliziten Parameter sehr nützliche Sammlung-Morphing-Aufgaben ausführen).

Ich denke nicht, dass es ein Problem mit der Sprache an sich ist - ich denke, es ist eher ein Werkzeugproblem. Und obwohl ich dem zustimme, was Jörg W Mittag sagt, denke ich, dass ein Blick auf Scaladoc (oder die Dokumentation eines Typs in Ihrer IDE) so wenig Gehirnleistung wie möglich erfordern sollte, um herauszufinden, was eine Methode ist, was sie benötigt und zurückgibt. Es sollte nicht nötig sein, ein bisschen Algebra auf ein Stück Papier zu hacken, um es zu bekommen :)

Sicherlich brauchen IDEs eine gute Möglichkeit, alle Methoden für jede Variable / jeden Ausdruck / Typ anzuzeigen (wie in Martins Beispiel können alle Generika eingefügt sein, so dass es schön und einfach zu groken ist). Ich mag Martins Idee, die Implikationen auch standardmäßig zu verbergen.

Um das Beispiel in scaladoc zu nehmen ...

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

Wenn ich mir das in scaladoc anschaue, möchte ich, dass der generische Block [B, That] standardmäßig ausgeblendet wird sowie der implizite Parameter (möglicherweise wird angezeigt, wenn Sie mit der Maus über ein kleines Symbol fahren) - als zusätzliches Element zum Groken Lesen, was normalerweise nicht so relevant ist. zB stell dir vor, das sah so aus ...

def map(f: A => B): That

nett und klar und offensichtlich, was es tut. Sie fragen sich vielleicht, was "Das" ist. Wenn Sie mit der Maus darüber fahren oder darauf klicken, wird möglicherweise der Text [B, Das] erweitert, der beispielsweise das "Das" hervorhebt.

Vielleicht könnte ein kleines Symbol für die [] Deklaration und den (impliziten ...) Block verwendet werden, damit klar ist, dass kleine Teile der Anweisung reduziert sind? Es ist schwer, einen Token dafür zu verwenden, aber ich werde einen verwenden. zur Zeit...

def map.(f: A => B).: That

Standardmäßig ist das 'Rauschen' des Typsystems also vor den wichtigsten 80% dessen verborgen, was die Leute betrachten müssen - dem Methodennamen, seinen Parametertypen und seinem Rückgabetyp auf nette, einfache und übersichtliche Weise - mit wenig erweiterbaren Links zum Detail wenn es dich wirklich interessiert.

Die meisten Leute lesen Scaladoc, um herauszufinden, welche Methoden sie für einen Typ aufrufen können und welche Parameter sie übergeben können. Wir überladen Benutzer mit viel zu vielen Details, wie IMHO.

Hier ist ein weiteres Beispiel ...

def orElse[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]): PartialFunction[A1, B1]

Wenn wir nun die Generika-Deklaration versteckt haben, ist sie leichter zu lesen

def orElse(that: PartialFunction[A1, B1]): PartialFunction[A1, B1]

Wenn die Leute dann beispielsweise über A1 schweben, könnten wir die Deklaration von A1 als A1 <: A zeigen. Kovariante und kontravariante Typen in Generika fügen ebenfalls viel Rauschen hinzu, das für Benutzer, wie ich denke, viel einfacher zu verstehen ist.

James Strachan
quelle
5
Aber was bedeutet "Das" als Ergebnistyp?
Blaisorblade
11

Ich weiß nicht, wie ich es Ihnen sagen soll, aber ich habe einen Doktortitel aus Cambridge und verwende 2.8 ganz gut.

Im Ernst, ich habe kaum Zeit mit 2.7 verbracht (es funktioniert nicht mit einer Java-Bibliothek, die ich verwende) und habe vor etwas mehr als einem Monat angefangen, Scala zu verwenden. Ich habe einige Erfahrungen mit Haskell (nicht viel), habe aber die Dinge, über die Sie sich Sorgen machen, einfach ignoriert und nach Methoden gesucht, die meinen Erfahrungen mit Java entsprechen (die ich beruflich verwende).

Also: Ich bin ein "neuer Benutzer" und habe mich nicht abschrecken lassen - die Tatsache, dass es wie Java funktioniert, gab mir genug Selbstvertrauen, um die Teile zu ignorieren, die ich nicht verstand.

(Der Grund, warum ich mich mit Scala befasst habe, war zum Teil, dass ich es bei der Arbeit vorantreiben sollte, und ich werde es noch nicht tun. Die Dokumentation weniger einschüchternd zu machen, würde sicherlich helfen, aber was mich überrascht hat, ist, wie viel es noch ist Ändern und weiterentwickelt werden (um fair zu sein, was mich am meisten überraschte, war, wie großartig es ist, aber die Änderungen kamen nur an zweiter Stelle). Ich denke also, ich würde es vorziehen, wenn die begrenzten Ressourcen dafür eingesetzt würden ein Endzustand - ich glaube nicht, dass sie erwartet hatten, so bald so beliebt zu sein.)

Peter Mortensen
quelle
22
Ich denke, er möchte wissen, ob Menschen ohne Doktortitel aus Cambridge mit Scala 2.8 umgehen können.
Ken Bloom
2
Haha: touche! Nun, ich sagte, dass Scala 2.8 einfach zu bedienen ist - meine Frage war eher, wie es für jemanden aussehen würde, der die API durchsucht, um zu sehen, ob es ihm gefällt, vorausgesetzt, er hat keine Erfahrung mit Scala.
oxbow_lakes
1
@andrew - nach dem Aussehen Ihrer Website ( acooke.org ) fühlen Sie sich mit visuell einschüchternden Konzepten nicht unwohl
oxbow_lakes
Wer sich mit Malbolge-Programmierung beschäftigt, auch wenn es "nur" Hello World ist, wird sich wahrscheinlich von nichts einschüchtern lassen.
Carl Smotricz
10

Ich kenne Scala überhaupt nicht, aber vor ein paar Wochen konnte ich Clojure nicht lesen. Jetzt kann ich das meiste davon lesen, aber noch nichts über die einfachsten Beispiele hinaus schreiben . Ich vermute, Scala ist nicht anders. Sie benötigen ein gutes Buch oder einen guten Kurs, je nachdem, wie Sie lernen. Wenn ich nur die obige Kartenerklärung lese , habe ich vielleicht 1/3 davon.

Ich glaube, die größeren Probleme sind nicht die Syntax dieser Sprachen, sondern die Übernahme und Internalisierung der Paradigmen , die sie im alltäglichen Produktionscode verwendbar machen. Für mich war Java kein großer Sprung von C ++, was kein großer Sprung von C war, was überhaupt kein Sprung von Pascal war, noch Basic usw. Aber das Codieren in einer funktionalen Sprache wie Clojure ist ein großer Sprung (für ich sowieso). Ich denke, in Scala können Sie im Java-Stil oder im Scala-Stil codieren. Aber in Clojure werden Sie ein ziemliches Durcheinander schaffen, wenn Sie versuchen, Ihre zwingenden Gewohnheiten von Java fernzuhalten.

Jeff G.
quelle
5
Es geht nie um Notation (oder nie mehr als beispielsweise 10-15% um Notation), es geht immer um die Konzepte. Und wenn Sie einigermaßen intelligent sind und sich nicht in jahrzehntelangem Wissen aus verschiedenen, möglicherweise widersprüchlichen Modellen festgefahren haben (wie ich es wahrscheinlich bin), ist es normalerweise nicht allzu schwer, diese Dinge zu erfassen. Aber wenn Sie in einer Art und Weise über Dinge nachdenken und sie tun, ist es zumindest ein gewisser Aufwand, sich anzupassen, und viele reagieren auf solche Veränderungen. Es ist nur menschliche Psychologie / Natur. (Ich frage mich, wie sich Weinbergs Psychologie der Computerprogrammierung nach fast 40 Jahren
Randall Schulz
1
@ Randall Schultz und Jeff G: Syntax / Notation ist für eine kluge Person ziemlich einfach zu handhaben. Grundsätzlich unterschiedliche Namen für dieselben Konzepte. Sich in einer neuen Sprache auf den neuesten Stand zu bringen, ist nur eine Frage der Übung. Der Schritt von der prozeduralen zur funktionalen Programmierung ist jedoch ... erschreckend weit. Es ist wirklich eine andere Art zu denken. Ich beschäftige mich seit einigen Monaten mit Clojure und finde es eine relativ "einfache", unterhaltsame FP-Sprache. Aber ich brauche immer noch übermäßig viel Zeit, um Dinge herauszufinden, die bei der prozeduralen Programmierung unkompliziert wären.
Carl Smotricz
7

Scala hat viele verrückte Funktionen (insbesondere wenn es um implizite Parameter geht), die sehr kompliziert und akademisch aussehen, aber die Bedienung vereinfachen sollen. Die nützlichsten erhalten syntaktischen Zucker ( [A <% B]was bedeutet, dass ein Objekt vom Typ A eine implizite Umwandlung in ein Objekt vom Typ B hat) und eine gut dokumentierte Erklärung dessen, was sie tun. In den meisten Fällen können Sie als Client dieser Bibliotheken die impliziten Parameter ignorieren und darauf vertrauen, dass sie das Richtige tun.

Ken Bloom
quelle
Ja, die Ansichtssyntax macht das Erfassen schneller.
Egaga
6

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

Ich denke nicht, dass dies der Hauptfaktor ist, der die Popularität von Scala beeinflussen wird, da Scala viel Leistung besitzt und seine Syntax einem Java / C ++ / PHP-Programmierer nicht so fremd ist wie Haskell, OCaml, SML, Lisps, usw..

Aber ich denke, Scalas Popularität wird weniger als heute ein Plateau erreichen, da ich denke, dass die nächste Mainstream-Sprache stark vereinfacht werden muss und der einzige Weg, den ich sehe, um dorthin zu gelangen, reine Unveränderlichkeit ist, dh deklarativ wie HTML, aber Turing vollständig . Ich bin jedoch voreingenommen, weil ich eine solche Sprache entwickle, aber ich habe dies erst getan, nachdem ich über ein mehrmonatiges Studium ausgeschlossen hatte, dass Scala nicht für das ausreichen konnte, was ich brauchte.

Wird dies Scala in der Geschäftswelt einen schlechten Ruf als akademisches Spielzeug geben, das nur engagierte Doktoranden verstehen können? Werden CTOs und Software-Leiter Angst bekommen?

Ich glaube nicht, dass Scalas Ruf unter dem Haskell-Komplex leiden wird. Aber ich denke, dass einige das Lernen aufschieben werden, weil ich für die meisten Programmierer noch keinen Anwendungsfall sehe, der sie zwingt, Scala zu verwenden, und sie werden das Lernen darüber hinauszögern. Vielleicht ist die hochskalierbare Serverseite der überzeugendste Anwendungsfall.

Und für den Mainstream-Markt ist das erste Erlernen von Scala kein "Hauch frischer Luft", bei dem man sofort Programme schreibt, beispielsweise zuerst HTML oder Python. Scala neigt dazu, auf dir zu wachsen, nachdem man alle Details gelernt hat, über die man von Anfang an stolpert. Wenn ich jedoch von Anfang an Programmieren in Scala gelesen hätte, wären meine Erfahrungen und meine Meinung zur Lernkurve anders gewesen.

War die Neugestaltung der Bibliothek eine vernünftige Idee?

Bestimmt.

Wenn Sie Scala kommerziell nutzen, machen Sie sich darüber Sorgen? Planen Sie die sofortige Einführung von 2.8 oder warten Sie ab, was passiert?

Ich benutze Scala als erste Plattform für meine neue Sprache. Ich würde wahrscheinlich keinen Code in Scalas Sammlungsbibliothek erstellen, wenn ich Scala anderweitig kommerziell verwenden würde. Ich würde meine eigene kategorietheoretische Bibliothek erstellen, da ich beim ersten Mal Scalaz 'Typensignaturen noch ausführlicher und unhandlicher fand als Scalas Sammlungsbibliothek. Ein Teil dieses Problems ist vielleicht Scalas Art, Typklassen zu implementieren, und das ist ein kleiner Grund, warum ich meine eigene Sprache erstelle.


Ich habe mich entschlossen, diese Antwort zu schreiben, weil ich mich zwingen wollte, Scalas Sammlungsklassendesign zu recherchieren und mit dem zu vergleichen, das ich für meine Sprache mache. Könnte auch meinen Denkprozess teilen.

Die Verwendung einer Builder-Abstraktion in den 2.8 Scala-Sammlungen ist ein solides Designprinzip. Ich möchte im Folgenden zwei Design-Kompromisse untersuchen.

  1. NUR SCHREIBCODE: Nachdem ich diesen Abschnitt geschrieben habe, habe ich den Kommentar von Carl Smotricz gelesen der mit dem übereinstimmt, was ich als Kompromiss erwarte. Die Kommentare von James Strachan und davetron5000 stimmen darin überein, dass die Bedeutung von That (es ist nicht einmal That [B]) und der Mechanismus des Impliziten nicht leicht intuitiv zu erfassen sind. Siehe meine Verwendung von Monoid in Ausgabe 2 unten, die meiner Meinung nach viel expliziter ist. In Derek Mahar's Kommentar geht es darum, Scala zu schreiben, aber was ist mit dem Lesen der Scala anderer, was nicht "in den üblichen Fällen" ist.

    Eine Kritik, die ich über Scala gelesen habe, ist, dass es einfacher ist, sie zu schreiben, als den Code zu lesen, den andere geschrieben haben. Und ich finde, dass dies gelegentlich aus verschiedenen Gründen zutrifft (z. B. viele Möglichkeiten, eine Funktion zu schreiben, automatische Schließungen, Einheit für DSLs usw.), aber ich bin unentschlossen, ob dies ein wichtiger Faktor ist. Hier hat die Verwendung impliziter Funktionsparameter Vor- und Nachteile. Auf der positiven Seite reduziert es die Ausführlichkeit und automatisiert die Auswahl des Builder-Objekts. Bei Odersky BeispielDie Konvertierung von einem BitSet, dh Set [Int], in ein Set [String] ist implizit. Der unbekannte Leser des Codes weiß möglicherweise nicht ohne weiteres, um welche Art von Sammlung es sich handelt, es sei denn, er kann gut über alle potenziellen unsichtbaren impliziten Builder-Kandidaten nachdenken, die im aktuellen Paketumfang vorhanden sein könnten. Natürlich wissen der erfahrene Programmierer und der Verfasser des Codes, dass BitSet auf Int beschränkt ist, daher muss eine Zuordnung zu String in einen anderen Sammlungstyp konvertiert werden. Aber welcher Sammlungstyp? Es ist nicht explizit angegeben.

  2. AD-HOC-SAMMLUNGSDESIGN: Nachdem ich diesen Abschnitt geschrieben hatte, las ich Tony Morris 'Kommentar und stellte fest, dass ich fast den gleichen Punkt mache. Vielleicht wird meine ausführlichere Darstellung den Punkt klarer machen.

    In "Fighting Bit Rot with Types" von Odersky & Moors werden zwei Anwendungsfälle vorgestellt. Sie sind die Beschränkung von BitSet auf Int-Elemente und Map to Pair Tuple-Elemente und werden als Grund dafür angegeben, dass die allgemeine Elementzuordnungsfunktion A => B in der Lage sein muss, alternative Zielsammlungstypen zu erstellen. Afaik ist dies jedoch aus kategorietheoretischer Sicht fehlerhaft. Um in der Kategorietheorie konsistent zu sein und somit Eckfälle zu vermeiden, sind diese Sammlungstypen Funktoren, bei denen jeder Morphismus, A => B, zwischen Objekten in derselben Funktorkategorie, Liste [A] => Liste [B], BitSet, zugeordnet werden muss [A] => BitSet [B]. Eine Option ist beispielsweise ein Funktor, der als Sammlung von Mengen aus einem Some (Objekt) und dem None angesehen werden kann. Es gibt keine allgemeine Karte von Option's None oder List's Nil zu anderen Funktoren, die dies nicht tun.

    Hier wird eine Kompromissentscheidung getroffen. In der Design for Collections-Bibliothek meiner neuen Sprache habe ich beschlossen, alles zu einem Funktor zu machen. Wenn ich also ein BitSet implementiere, muss es alle Elementtypen unterstützen, indem eine interne Darstellung ohne Bitfeld verwendet wird, wenn eine Nicht-Bit-Darstellung angezeigt wird Parameter vom Typ Integer, und diese Funktionalität befindet sich bereits in der Menge, von der sie in Scala erbt. Und Map in meinem Design muss nur seine Werte zuordnen, und es kann eine separate Nicht-Funktor-Methode zum Zuordnen seiner (Schlüssel-, Wert-) Paartupel bereitstellen. Ein Vorteil ist, dass jeder Funktor dann meist auch ein Applikativ und vielleicht auch eine Monade ist. Somit werden alle Funktionen zwischen Elementtypen, z. B. A => B => C => D => ..., automatisch auf die Funktionen zwischen angehobenen Anwendungstypen aufgehoben, z. B. Liste [A] => Liste [B] => Liste [ C] => Liste [D] => .... Für die Zuordnung von einem Funktor zu einer anderen Sammlungsklasse biete ich eine Kartenüberladung an, die ein Monoid akzeptiert, z. B. Nil, None, 0, "", Array () usw. Die Builder-Abstraktionsfunktion ist also die Append-Methode eines Monoids und wird explizit als notwendiger Eingabeparameter angegeben, also ohne unsichtbare implizite Konvertierungen. (Tangente: Dieser Eingabeparameter ermöglicht auch das Anhängen an nicht leere Monoide, was Scalas Kartendesign nicht kann.) Solche Konvertierungen sind eine Karte und eine Falte im selben Iterationsdurchlauf. Außerdem biete ich eine durchlaufbare im Sinne der Kategorie "Applikative Programmierung mit Effekten" von McBride & Patterson an, die auch Map + Fold in einem einzigen Iterationsdurchlauf von jeder Durchquerung zu jeder Anwendung ermöglicht, wobei fast jede Sammlungsklasse beides ist.

    Die Scala-Sammlungen sind also "ad-hoc" in dem Sinne, dass sie nicht auf Kategorietheorie beruhen, und Kategorietheorie ist die Essenz der Denotationssemantik auf höherer Ebene. Obwohl die impliziten Builder von Scala auf den ersten Blick "allgemeiner" erscheinen als ein Funktormodell + Monoid-Builder + Traversable -> anwendbar, sind sie afaik nachweislich nicht mit einer Kategorie konsistent, und daher wissen wir nicht, welchen Regeln sie in der Der allgemeinste Sinn und die Eckfälle werden möglicherweise keinem Kategoriemodell gehorchen. Es ist einfach nicht wahr, dass das Hinzufügen weiterer Variablen etwas allgemeineres macht, und dies war einer der großen Vorteile der Kategorietheorie, da sie Regeln bereitstellt, nach denen die Allgemeinheit beibehalten und gleichzeitig zur Semantik auf höherer Ebene übergegangen werden kann. Eine Sammlung ist eine Kategorie.

    Ich habe irgendwo gelesen, ich denke, es war Odersky, als eine weitere Rechtfertigung für das Bibliotheksdesign, dass das Programmieren in einem rein funktionalen Stil die Kosten einer begrenzten Rekursion und Geschwindigkeit verursacht, wenn keine Schwanzrekursion verwendet wird. Ich habe es nicht schwierig gefunden, in jedem Fall, auf den ich bisher gestoßen bin, eine Schwanzrekursion anzuwenden.


Außerdem habe ich die unvollständige Vorstellung, dass einige der Kompromisse von Scala darauf zurückzuführen sind, dass ich versucht habe, sowohl eine veränderliche als auch eine unveränderliche Sprache zu sein, im Gegensatz zu beispielsweise Haskell oder der Sprache, die ich entwickle. Dies stimmt mit Tony Morris 'Kommentar zum Verständnis überein. In meiner Sprache gibt es keine Schleifen und keine veränderlichen Konstrukte. Meine Sprache wird (vorerst) auf Scala sitzen und hat viel zu verdanken, und dies wäre nicht möglich, wenn Scala nicht das allgemeine Typensystem und die Veränderlichkeit hätte. Das mag jedoch nicht zutreffen, da ich denke, dass Odersky & Moors ("Fighting Bit Rot with Types") falsch ist, um zu behaupten, dass Scala die einzige OOP-Sprache mit höheren Arten ist, weil ich (selbst und über Bob Harper) diesen Standard verifiziert habe ML hat sie. Es scheint auch, dass das SML-Typensystem (seit den 1980er Jahren) gleichermaßen flexibel sein kann. Dies kann nicht ohne weiteres erkannt werden, da die Syntax Java (und C ++ / PHP) nicht so sehr ähnelt wie Scala. Auf jeden Fall ist dies keine Kritik an Scala, sondern ein Versuch, eine unvollständige Analyse der Kompromisse vorzulegen, was meiner Meinung nach für die Frage von Belang ist. Scala und SML leiden nicht unter Haskells UnfähigkeitDiamant-Mehrfachvererbung , was kritisch ist und ich verstehe, ist, warum so viele Funktionen im Haskell-Präludium für verschiedene Typen wiederholt werden.

Shelby Moore III
quelle
Wird Ihre Sprache objektorientiert sein?
fehlender Faktor
Ja, erbt das Typensystem von Scala. Ein wesentlicher Unterschied besteht darin, dass das Merkmal in Schnittstelle und Mixin unterteilt ist, wobei die Schnittstelle nur Methodensignaturen und keine Implementierung enthält. Und nur eine Schnittstelle kann als Typ referenziert werden. Die Implikationen werden beseitigt und Typklassen werden in der Schnittstelle auf SPOT-Weise behandelt. Hier ist ein grober Entwurf von Details. Mitarbeiter sind willkommen. Ein Code für die Bibliothek ist hier . Dies ist in Arbeit, Entschuldigung für die Erwähnung von Vaporware. Nur Gedanken teilen.
Shelby Moore III
5

Es scheint notwendig, hier einen Abschluss anzugeben: BA in Politikwissenschaft und B.ed in Informatik.

Auf den Punkt:

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

Scala ist schwierig, weil das zugrunde liegende Programmierparadigma schwierig ist. Funktionale Programmierung macht vielen Menschen Angst. Es ist möglich, Schließungen in PHP zu erstellen, aber die Leute tun dies selten. Also nein, nicht diese Unterschrift, sondern alles andere wird die Menschen abschrecken, wenn sie nicht über die spezifische Ausbildung verfügen, um die Macht des zugrunde liegenden Paradigmas wertzuschätzen.

Wenn diese Ausbildung verfügbar ist, kann es jeder tun. Letztes Jahr habe ich mit ein paar Schulkindern in SCALA einen Schachcomputer gebaut! Sie hatten ihre Probleme, aber am Ende haben sie es gut gemacht.

Wenn Sie Scala kommerziell nutzen, machen Sie sich darüber Sorgen? Planen Sie die sofortige Einführung von 2.8 oder warten Sie ab, was passiert?

Ich würde mir keine Sorgen machen.

Julian Dehne
quelle
4

Ich habe auch einen Mathematik-Abschluss in Oxford! Ich habe eine Weile gebraucht, um die neuen Kollektionen zu bekommen. Aber ich mag es jetzt sehr, wo ich es tue. Tatsächlich war die Eingabe von 'map' eines der ersten großen Dinge, die mich in 2.7 nervten (vielleicht seit ich als erstes eine der Sammlungsklassen untergeordnet habe).

Das Lesen von Martins Artikel über die neuen 2.8-Sammlungen hat wirklich dazu beigetragen, die Verwendung von Implicits zu erklären, aber ja, die Dokumentation selbst muss definitiv die Rolle verschiedener Arten von Implicits in Methodensignaturen von Kern-APIs besser erklären.

Mein Hauptanliegen ist eher Folgendes: Wann wird 2.8 veröffentlicht? Wann werden die Fehlerberichte nicht mehr eingehen? Hat das Scala-Team mehr abgebissen, als es mit 2.8 kauen kann / versucht, zu viel auf einmal zu ändern?

Ich würde wirklich gerne sehen, dass 2.8 für die Veröffentlichung als Priorität stabilisiert wird, bevor überhaupt etwas Neues hinzugefügt wird, und mich fragen (während ich von der Seitenlinie aus schaue), ob einige Verbesserungen an der Art und Weise vorgenommen werden könnten, wie die Entwicklungs-Roadmap für den Scala-Compiler verwaltet wird.

Matt
quelle
-1

Was ist mit Fehlermeldungen auf der verwendeten Website?

Und wann kommt der Anwendungsfall, bei dem vorhandene Typen in einen benutzerdefinierten Typ integriert werden müssen, der zu einem DSL passt? Man muss in Fragen der Assoziation, des Vorrangs, impliziter Konvertierungen, impliziter Parameter, höherer Arten und möglicherweise existenzieller Typen gut ausgebildet sein.

Es ist sehr gut zu wissen, dass es meistens einfach ist, aber es ist nicht unbedingt genug. Zumindest muss es einen geben, der dieses Zeug kennt, wenn eine weit verbreitete Bibliothek entworfen werden soll.

Sujen
quelle
Einer der Hauptpunkte ist jedoch der Unterschied zwischen der Bibliothek aus der Sicht eines Benutzers und den Erstellern. Offensichtlich benötigen die Entwickler ein beeindruckendes Verständnis der erforderlichen Sprachfunktionen (z. B. höherwertige Typen, implizite Priorität) - die Frage lautet: "Tun die Benutzer?"
oxbow_lakes