it-swarm.dev

Warum wurde Scala nicht mit C oder C ++ implementiert?

Weiß jemand, warum Scala in Java und .NET anstelle von C oder C++ implementiert wurde?). Die meisten Sprachen werden mit Cor C++ [dh Erlang, Python, PHP implementiert , Ruby, Perl]. Was sind die Vorteile für Scala implementiert in Java und .NET außer dem Zugriff auf Java)? = und .NET Bibliotheken?

UPDATE

Würde Scala nicht mehr Nutzen bringen, wenn es in C implementiert würde, weil es besser optimiert werden kann, als sich auf JVM zu verlassen?

28
Joshua Partogi

Die Frage ist verwirrend, da C und C++ Sprachen sind, während JVM eine virtuelle Maschine und .Net eine Plattform Ist =. Scala könnte in C oder C++ implementiert werden und Maschinencode anstelle von Bytecode für eine virtuelle Maschine generieren.

Beantwortung der gestellten Frage:

Scala wurde nicht in C oder C++ implementiert, da Scala, die Sprache, in der es tatsächlich implementiert ist, eine viel bessere Sprache ist.

Warum ist es besser? Lesen Sie weiter über Oderskys Ziele für die Sprache Scala .

Beantwortung der möglicherweise beabsichtigten Frage:

Scala generiert hauptsächlich JVM-Bytecode, da dies eine hervorragende Portabilität sowie Funktionen wie einen zuverlässigen und effizienten Garbage Collector, Laufzeitoptimierungen und Just-in-Time-Kompilierung bietet von der JVM.

Lassen Sie mich das Letzte wiederholen: JVM wird kompilieren, um Code-Hotspots in dem Code zu bearbeiten, den es ausführt. Das ist genau wie C- und C++ - Compiler kompilieren.

Es sind andere virtuelle Maschinen verfügbar, aber Odersky, Scalas Schöpfer, war mit JVM bereits sehr vertraut. Er wollte CLR als Alternative haben, aber die Bemühungen, dies in Gang zu bringen, haben noch keinen Erfolg erzielt.

Beantwortung der Frage, die hätte gestellt werden können/sollen:

Das Kompilieren in Maschinencode bietet nicht genügend Vorteile gegenüber dem Kompilieren in JVM-Bytecode.

Es ist sicherlich möglich, Mikrobenchmarks in C oder C++ zu generieren, die JVM-Äquivalente übertreffen. Es ist auch wahr, dass extrem optimierter Code in C oder C++ extrem optimierten Code in Java oder Scala) schlägt. Der Unterschied ist jedoch für lang laufende Programme nicht allzu groß.

Beachten Sie, dass Scala keine besonders gute Skriptsprache ist, gerade weil der Overhead für kurz laufende Programme zu groß ist.

In den meisten Fällen sind jedoch die Geschwindigkeit von Entwicklung und die Wartungsfreundlichkeit wichtiger als die Geschwindigkeit von Ausführung. In den Fällen, in denen die Leute mehr daran interessiert sind, Code auf sehr hoher Ebene zu schreiben, der leicht zu verstehen und zu ändern ist, können die von der JVM bereitgestellten Laufzeitoptimierungen die von C- oder C++ - Compilern vorgenommenen Optimierungen zur Kompilierungszeit leicht übertreffen und JVM (und CLR) machen ) das Ziel, das tatsächlich schneller ausgeführt wird.

Egal, ob es sich bei der Frage um Scala Compiler um eine ausführbare Maschinencode-Datei oder um Scala Programme Da es sich um Maschinencode handelt, bedeutet das Potenzial Geschwindigkeitsgewinne nicht unbedingt real Geschwindigkeitsgewinne.

Und übrigens

Ich gebe Ihnen ein Gegenbeispiel: Haskell. Haskell generiert Maschinencode, und dennoch schneiden Haskell-Programme bei Debians Shootout schlechter ab als bei Scala. Kann jemand sicher sein, dass Scala Programme schneller wären, wenn sie direkt in Maschinencode kompiliert würden?

59

Eine der großen Hürden für Sprachen bei der Einführung in die Welt ist die Verfügbarkeit von Bibliotheken. Die traditionelle Antwort darauf war die Bereitstellung eines C-basierten FFI (Foreign Function Interface), um Ihnen den Zugriff auf C-basierte Bibliotheken zu ermöglichen. Dies ist aus verschiedenen Gründen nicht ideal, vor allem aus folgenden Gründen:

  • Es gibt viele verschiedene Arten, wie Bibliotheken interagieren möchten, die nicht mit vielen höheren Sprachen kompatibel sind. Wenn die Bibliothek beispielsweise einen Zeiger auf ein struct möchte, wie funktionieren die Sprachen ohne Zeiger [~ # ~] und [~ # ~] no structUmfang?
  • Es gibt harte Wechselwirkungen zwischen Speichermodellen verschiedener Bibliotheken und Sprachen, die häufig nicht auflösbar oder, falls sie auflösbar sind, sehr fehler- und fehleranfällig sind.
  • Der Klebercode für viele FFIs ist nicht trivial und setzt Wissen voraus, das möglicherweise nicht universell ist. (Ob Sie es glauben oder nicht, nicht alle Programmierer sind C-Gurus, und sie wollen es auch nicht sein und sollten es auch nicht sein müssen!)

Dies wird mit C++ noch schlimmer. C++ ist nicht einmal kompatibel mit C++ (auf einer binären Ebene, meine ich) von Compiler zu Compiler auf derselben Plattform (!), Ganz zu schweigen von anderen Sprachen.

Durch die Ausrichtung auf die JVM werden viele dieser Probleme gelöst, und Sie erhalten Zugriff auf die absolut enorme Suite von Java-basierten Bibliotheken. (Wie riesig? Schauen Sie sich einfach The Apache Software Foundation 's riesige Auswahl für den Anfang an.)

  • Die Aufruf- und Besitzkonventionen von Java sind regelmäßiger als die von C.
  • Die JVM bietet auch ein einzelnes Speichermodell (einschließlich Garbage Collection) für Sprachen und Bibliotheken, mit denen beide eine Schnittstelle herstellen können. Es ist nicht nötig zu verfolgen, wem was gehört und wer wo aufräumen muss. Die Laufzeit erledigt das für Sie.
  • Der Klebercode für FFI ist für die meisten auf der JVM basierenden Sprachen nicht vorhanden (da er als Rahmen hinter den Kulissen der Sprache bereitgestellt wird). Sie müssen beispielsweise nicht in Java programmieren, um auf Java Bibliotheken in Scala, Clojure, JRuby usw. zuzugreifen. Sie greifen auf die Objekte Java auf dieselbe Weise zu) Sie greifen auf native "Objekte" zu (erschreckende Anführungszeichen, weil Clojure beispielsweise keine tatsächlichen Objekte im Sinne von OOP) und in Ihrer Muttersprache hat.

Zusätzlich zu diesen Vorteilen haben Sie die zusätzlichen Vorteile, dass Sie überall ausgeführt werden können Java läuft ohne Neukompilierung (aber with Testen!: einmal schreiben, überall testen) und Zugriff auf Javas beeindruckende JIT-Technologie haben.

Die CLR bietet ähnliche Stärken, fügt jedoch die Schwäche von IMO hinzu: Es handelt sich so ziemlich um eine Vendor-Lock-In-Umgebung. (Ja, ich weiß über Mono Bescheid. Ich denke immer noch, dass es sich um eine Vendor Lock-In-Umgebung handelt.)

Laut dieses Interview war der Zugriff auf vorhandene Java Infrastruktur und Bibliotheken der Hauptgrund.

... Java ist eine existierende Sprache mit sehr strengen Einschränkungen. Infolgedessen konnte ich viele Dinge nicht so tun, wie ich es gerne getan hätte - so wie ich überzeugt war wäre der richtige Weg, um sie zu machen. Nach dieser Zeit, als der Schwerpunkt meiner Arbeit im Wesentlichen darin bestand, Java besser zu machen), entschied ich, dass es Zeit war, einen Schritt zurückzutreten. Ich wollte Um mit einem leeren Blatt zu beginnen und zu sehen, ob ich etwas entwerfen kann, das besser als Java ist. Gleichzeitig wusste ich, dass ich nicht bei Null anfangen konnte. Ich musste mich mit einer vorhandenen Infrastruktur verbinden, weil es sonst einfach unpraktisch ist bootstrap dich aus dem Nichts ohne Bibliotheken, Tools und ähnliches.

Deshalb habe ich beschlossen, dass ich, obwohl ich eine andere Sprache als Java entwerfen wollte , immer eine Verbindung zur Java -Infrastruktur - zur JVM und ihrer) herstellen würde Bibliotheken . Das war die Idee ...

18
Jeremiah

Alle anderen Sprachen, die Sie erwähnen, Erlang, Python, PHP, Ruby, Perl - diese wurden alle erstellt vorher Java & .NET. Wenn die Ersteller dieser Sprachen Wenn ihnen zu diesem Zeitpunkt die Laufzeitumgebung Java oder .NET zur Verfügung stand), haben sie diese möglicherweise beim Erstellen ihrer Sprache genutzt.

Natürlich kann ich nicht für die Entwickler dieser Sprachen sprechen, daher kann ich nicht mit Sicherheit sagen , dass sie .NET und verwendet hätten/or Java beim Erstellen, wenn sie verfügbar waren, aber es scheint mir eine gute Idee zu sein. Wenn Sie Ihre Sprache so gestalten, dass sie mit Java/.NET-Bytecode kompiliert wird, erhalten Sie schließlich alles Aufgrund der Vorteile der JIT-Compiler/-Optimierer wird Ihre Sprache automatisch auf allen Plattformen ausgeführt, auf denen Java/.NET ausgeführt wird. Sie haben Zugriff auf alle Java/.NET-Bibliotheken usw.

10
Dean Harding

C-Code wird statisch zu nativer Code (Maschinencode) kompiliert.

Scala wird statisch zu Java Bytecode kompiliert und dann nach Bedarf dynamisch zu optimiertem nativem Code kompiliert. Der Prozess:

Scala-Code --- statisch kompiliert nach ---> JVM-Byte-Code --- dynamisch kompiliert nach JVM-Hotspot nach ---> - nativer Code

Allgemeine Optionen zum Erstellen/Ausführen einer beliebigen Sprache:

  • a) Interpretieren Sie den Quellcode direkt über eine Laufzeitinterpreter-Engine
  • b) Code statisch zu nativem Code kompilieren (möglicherweise über Zwischenstufen, z. B. Quelle -> C -> nativ)
  • c) Kompilieren Sie den Quellcode statisch zu Zwischencode niedrigerer Ebene und interpretieren Sie ihn zur Laufzeit
  • d) Kompilieren Sie den Quellcode statisch in Zwischencode niedrigerer Ebene und verwenden Sie dann die anfängliche Interpretation, gefolgt von dynamischen Kompilierungs- und Optimierungstechniken, um ihn in nativen Code zu konvertieren. Code wird interpretiert, bis typische Ausführungspfade und Engpässe gefunden werden. Anschließend wird Code für die schnellste Ausführung unter typischen Bedingungen kompiliert. Es wird neu kompiliert/neu abgestimmt, wenn sich die Ausführungsbedingungen so weit ändern, dass dies gerechtfertigt ist

Ihre Frage: "Warum verwendet Java (d) mit einer JVM anstelle von (b) mit C-Zwischencode?"

Antwort :

Beachten Sie zunächst, dass Scala eine viel höhere Sprache als C ist, was Programmierleistung, einfache Programmierung und Prägnanz bietet. Es ist ungefähr '1 Level höher' als Java aufgrund von erstklassigen Funktionen und Funktionen höherer Ordnung, impliziten Funktionen, Funktionen als Objekte, Closures und Currying, Unterstützung für das Kompilieren der Schwanzrekursion zu schnellen stapelschonenden Schleifen, alles als Objekte, Alle Operatoren als Methoden, die in Bibliotheken (Fallklassen und Reduktion (Pattern Matching) (neu) definiert werden können, implizite Typableitung, stärkerer Polymorphismus durch erweiterte mehrfach vererbbare Merkmale und erweiterte Generika, integrierte Syntax für Paare & Tupel & Nachteile (Listen & Bäume) & Karten, Unterstützung für unveränderliche Datenstrukturen, Unterstützung für leistungsstarkes "reaktives" paralleles und gleichzeitiges Rechnen mit Kopieren und Weitergeben von Nachrichten zwischen Akteuren, erweiterte Unterstützung für beliebige domänenspezifische DSLs, Skriptfähigkeit und REPL. Java ist aufgrund von Objektorientierung, Zeigerverwaltung und Speicherbereinigung, Zeichenfolgenunterstützung, Multithreading-Unterstützung und Parallelitätskontrolle sowie Standard-API-Bibliotheken etwa 1 Stufe höher als C.

  1. Leistung: Für eine Hochsprache bietet (d) eine schnellere Leistung als (a) - (c).
    Direkt geschriebener und handoptimierter C-Code ist schnell. Übergeordnete Sprachen, die statisch zu C kompiliert wurden, sind jedoch relativ langsam. Die Java Designer wussten das gut. Ihr aktuelles "Hotspot" -Design steigert die Leistung um bis zu eine Größenordnung. Auf einem einzelnen Kern ist Java HotSpot-Code im Durchschnitt "50% so schnell" wie vom Menschen optimiertes C (im besten Fall "120% so schnell", im schlimmsten Fall "30% so schnell"). . Aber das ist natürlich ein Vergleich zwischen Äpfeln und Orangen - Low-Level-Code gegen High-Level-Code. Und das wäre viel schlimmer, wenn die Hotspot-Optimierung nicht verwendet würde. Deaktivieren Sie zur Bestätigung einfach die Hotspot-Kompilierung über JVM-Argumente! Oder betrachten Sie die Leistung von Java 1 & 2, wenn kein Hotspot vorhanden oder unreif war. Oder versuchen Sie, eine andere Sprache über C zu kompilieren - z. perlcc. Die oben genannten Ergebnisse sind also großartige Ergebnisse für eine leistungsstarke und produktive Sprache. Mit der weiteren Entwicklung ist es möglich (oder sogar wahrscheinlich), dass JVM das handcodierte C im Durchschnitt bald übertrifft. Scala ist im Durchschnitt nur 70-80% so langsam wie Java. Aber scala skaliert stark über mehrere Kerne (mit weiteren Verbesserungen), während Java teilweise und C nicht. Die Single Core-Leistung für solche Hochsprachen wird bewertet:

    interpretiert <statisch kompiliert <dynamisch kompiliert

    Multi-Core-Leistung/Skalierbarkeit wird bewertet:

    interpretierter dynamischer Code <statisch kompilierter Imperativcode <statisch kompilierter funktionaler/deklarativer Code <dynamisch kompilierter funktionaler/deklarativer Code

    Dies bringt scala auf den Siegerplatz, da die Prozessorgeschwindigkeit an ihre Grenzen gestoßen ist und nun die Anzahl der Kerne nach Moores Gesetz zunimmt. Scala ist auf Multi-Cores sehr schnell und könnte in Zukunft um ein Vielfaches schneller sein als C oder Java. Statisches Kompilieren zu C ist eindeutig nicht die schnellste Option.

  2. Interoperabilität: Sprachen auf einer weit verbreiteten VM haben eine bessere Sprachinteroperabilität als 'isolierte' Sprachen. Scala "spielt automatisch mit" Java Klassen, Schnittstellen und Objekten, indem sie einfach importiert und verwendet werden, als wären sie scala Klassen, Merkmale und Objekte. Ähnliches ist mit anderen JVM-Sprachen wie Groovy, Clojure, JRuby und JPython möglich. Die einfache Interoperabilität hängt davon ab, wie sauber jede Sprache zum Kompilieren verständlicher und verwendbarer Java Laufzeitklassen/Schnittstellen/Objekte gemacht wurde. So viel ist kostenlos (wie in "in der Nähe von"). Scala arbeitet mit C über JNA, den Nachfolger von JNI, zusammen - was mit einigem Aufwand verbunden ist, aber die Tools wurden im Laufe der Zeit recht gut optimiert. JNA kann tatsächlich mit kompiliertem nativem Code aus einer beliebigen Sprache zusammenarbeiten - Sie müssen jedoch die genaue Struktur kompilierter Datentypen und Funktionen kennen. Wenn nicht, können Sie ein C-Wrapper-Objekt verwenden (oder im schlimmsten Fall einen zusätzlichen Mechanismus "C mit einer anderen Sprache" verketten), um mit Objective C, C #, Perl, Ruby, Cobol usw. zusammenzuarbeiten.

  3. Portabilität: JVM läuft auf Dutzenden von Betriebssystemplattformen/-versionen "out of the box". Scala wird automatisch auf diese portiert. Bemerkenswerte Ausnahme ist iOS (iPad/iPhone/iPod) - von Apple "kommerziell" und nicht "technisch" blockiert. Dies war 12 Jahre zuvor bei der ersten Entwicklung von JVM nicht zu erwarten gewesen. JVM läuft einwandfrei auf Dutzenden anderer Server, Desktops, Handys und eingebetteter Geräte, einschließlich solcher, die C nicht unterstützen - einschließlich Android mit Google-angepasstem Dalvik VM (50% + der neu verkauften Telefone). Sicher, C-Code funktioniert auf einer Vielzahl von Plattformen und kann daher als "dort oben mit oder wahrscheinlich darüber hinaus" Java eingestuft werden (insbesondere ist C eine Teilmenge von Objective-C). Aber C würde dazu kommen Die Kosten für (1), (2) und (3). Natürlich kann die Präsentationsschicht HTML5/Javascript/Webkit (oder Objective-C) unter iOS mit einer Remote-App scala zusammenarbeiten - also von Entwicklern sollte das sehr viel tun. Natürlich werden sie weniger produktiv sein.

  4. Tools und Bibliotheken: Offensichtlich gibt es Tausende von kommerziellen und Open-Source-Bibliotheken und -Tools Java, die von Scala genutzt werden können - mehr als für C.

  5. Sicherheit : - Die Ausführung auf einem kontrollierten App-Server oder einer JVM-Umgebung bietet eine stärkere Unterstützung für Sicherheitsrichtlinien und -einschränkungen, die in einer Unternehmensumgebung von großem Wert sein können.

6
Glen Best

JVM/CLR

Die JVM (und die CLR) bieten einzigartige Vorteile in Bezug auf Optimierung und Code-Portabilität.

Soweit ich weiß, wird nur die JVM-Version von Scala) auf dem neuesten Stand gehalten, die .NET-Version jedoch nicht.

4
Josh K

Es sieht so aus, als würden Sie zwei Dinge miteinander vermischen.

Die erste ist, welche Programmiersprache von Scala Autor (en)) verwendet wird, um Scala zu implementieren?

Auf die die Antwort lautet: Scala selbst. Und es ist wirklich die einzig akzeptable Antwort, denn wenn Sie diese neue Sprache erfunden haben, sie aber nicht selbst für die Implementierung verwenden - was nützt das? es für?

Die zweite Sache ist, was ist die Zielplattform zum Ausführen von in Scala geschriebenen Programmen?

Hier wird die Auswahl interessanter, aber das einzige Ziel, das zu 100% funktioniert, ist JVM. Die Unterstützung für .NET ist noch in Arbeit. Außerdem arbeiten einige Leute daran, Scala zum Kompilieren nach Javacsript) zu erhalten. Theoretisch hindert nichts jemanden daran, mehr Backends zum Kompilieren in C, C++, LLVM, nativem Code oder was auch immer hinzuzufügen.

Warum wurde JVM als primäre Plattform ausgewählt? Meine Vermutung ist, weil

  • jeder will Müllabfuhr
  • große Anzahl guter Bibliotheken gebrauchsfertig
  • eine große Anzahl von Programmierern langweilt sich mit Java ist bereit, zu etwas Neuem zu springen, hält sich aber an die Grenzen von JVM (niemand möchte seinen vorhandenen Code auf eine andere Plattform migrieren).
3
artem

Zuallererst - ich denke, Sie wollten wirklich fragen, warum Scala ist keine streng kompilierte Sprache. Ich werde Ihnen sagen, dass ich es nicht weiß. Aber ich werde Ihnen auch das sagen Es gibt keinen Grund, JVM gegenüber nativem Code zu bevorzugen.

Warum? Der Grund ist einfach: Jede Virtualisierungstechnologie ist speicherhungrig, erzeugt unnötigen Overhead und eine weitere Indirektionsebene. Dies ist keine Frage ihrer Implementierung - dies ist eine Tatsache der Logik, die hinter dem Kernkonzept der Virtualisierung steckt. Egal was Sie tun, Sie werden IMMER mit minderwertigen Eigenschaften enden. Besonders JVM ist speicherhungrig. Es ist nicht mehr so ​​langsam, weil es einen eigenen Laufzeit-Compiler hat, der hinter dem Rücken läuft, aber dennoch - es muss den Compiler-Prozess ausführen, um die am meisten überlasteten Teile des Codes erkennen und in Binärcode umwandeln zu können.

Sagte das - der einzige Grund, warum ich denke, dass es da war, um Scala JVM-basiert) zu machen, war wahrscheinlich die Popularität der Sprache. Ich denke auch, dass hinter dieser Entscheidung eine gewisse Faulheit steckt, weil es einfacher ist, eine Sprache zu implementieren über die JVM als herauszufinden, wie die Dinge aussehen sollten, um plattformübergreifend zu arbeiten - und selbst die Verwendung vorhandener C-Backends erfordert viel mehr Arbeit, da die Dinge nicht so gut standardisiert sind wie bei JVM.

Das ist der Grund, an den ich denken kann, aber denken Sie daran, dass es andere Gründe geben kann - wie Lizenzprobleme und damit verbundene Politik (das sind schmutzige Dinge, auf die ich nie gerne eingehen werde).

0
luke1985