web-dev-qa-db-fra.com

Pourquoi Scala non implémenté avec C ou C ++

Quelqu'un sait-il pourquoi Scala implémenté en Java et .NET au lieu de C ou C++? La plupart des langages sont implémentés avec Cor C++ [ie Erlang, Python, PHP , Ruby, Perl]. Quels sont les avantages de Scala implémenté dans Java et .NET autrement que de donner accès à Java = et bibliothèques .NET?

MISE À JOUR

Est-ce que Scala ne gagnerait pas plus d'avantages s'il était implémenté en C car il peut être mieux réglé plutôt que de s'appuyer sur JVM?

28
Joshua Partogi

La question est confuse, car C et C++ sont des langages , tandis que JVM est une machine virtuelle et .Net est un plateforme . Scala pourrait être implémenté en C ou C++, et il pourrait générer du code machine au lieu du bytecode pour une machine virtuelle.

Répondre à la question posée:

Scala n'a pas été implémenté en C ou C++ car Scala, le langage dans lequel il est réellement implémenté, est un bien meilleur langage.

Pourquoi est-ce mieux? Eh bien, allez lire Les objectifs d'Odersky pour la langue Scala .

Répondre à la question qui aurait pu être voulue:

Scala génère principalement du bytecode JVM car il offre une grande portabilité ainsi que des fonctionnalités telles qu'un garbage collector fiable et efficace, des optimisations d'exécution et une compilation juste à temps par la JVM .

Permettez-moi de répéter cette dernière chose: JVM compilera pour coder les points chauds du code qu'elle exécute. C'est compiler comme le font les compilateurs C et C++.

Il existe d'autres machines virtuelles disponibles, mais Odersky, le créateur de Scala, connaissait déjà très bien la JVM. Il avait l'intention d'avoir CLR comme alternative, mais l'effort pour le faire n'a pas encore réussi.

Répondre à la question qui aurait pu/aurait dû être posée:

La compilation en code machine n'offre pas suffisamment d'avantages par rapport à la compilation en bytecode JVM.

Il est certainement possible de générer des microbenchmarks en C ou C++ qui battent les équivalents JVM. Il est également vrai que le code extrêmement optimisé en C ou C++ battra le code extrêmement optimisé en Java ou Scala. La différence n'est pas si grande, cependant, pour un programme de longue durée.

Notez que Scala n'est pas un langage de script particulièrement bon précisément parce que la surcharge pour les programmes courts est trop grande.

Cependant, dans la plupart des cas, la vitesse de développement et la facilité de maintenance sont plus importantes que la vitesse d'exécution . Dans ces cas, où les gens sont plus intéressés par l'écriture de code de très haut niveau facilement compréhensible et modifiable, les optimisations d'exécution fournies par la JVM peuvent facilement battre les optimisations de compilation effectuées par les compilateurs C ou C++, ce qui rend JVM (et CLR ) la cible qui s'exécutera plus rapidement.

Donc, peu importe que la question porte sur Scala le compilateur soit un exécutable de code machine, ou Scala les programmes étant du code machine, les gains de vitesse potentiels ne se traduisent pas nécessairement par réel gains de vitesse.

Et, soit dit en passant,

Je vais vous donner un contre-exemple: Haskell. Haskell génère du code machine et, pourtant, les programmes Haskell sont moins bons lors de la fusillade de Debian que de Scala. Compte tenu de cela, quelqu'un peut-il être sûr que les programmes Scala seraient plus rapides s'ils étaient compilés directement en code machine?

59
Daniel C. Sobral

L'un des principaux obstacles auxquels les langues sont confrontées lors de leur introduction dans le monde est la disponibilité des bibliothèques. La réponse traditionnelle à cela a été de fournir une FFI basée sur C (interface de fonction étrangère) pour vous permettre d'accéder aux bibliothèques basées sur C. Ce n'est pas idéal pour diverses raisons, notamment:

  • Les bibliothèques souhaitent interagir de différentes manières qui ne sont pas compatibles avec de nombreux langages de niveau supérieur. Par exemple, si la bibliothèque veut un pointeur vers un struct, comment les langues sans pointeurs [~ # ~] et [~ # ~] no structportée?
  • Il existe des interactions sévères entre les modèles de mémoire de différentes bibliothèques et langages qui ne sont souvent pas résolvables ou, s'ils sont résolvables, sont fortement sujets aux erreurs et aux bogues.
  • Le code de colle pour de nombreux FFI n'est pas trivial et suppose des connaissances qui, en fait, peuvent ne pas être universelles. (Croyez-le ou non, tous les programmeurs ne sont pas des gourous du langage C, et ils ne veulent pas l'être et ne devraient pas l'être!)

Cela devient encore pire avec C++. C++ n'est même pas compatible avec C++ (au niveau binaire, je veux dire) de compilateur en compilateur sur la même plateforme (!), Sans parler des autres langages.

Le ciblage de la JVM résout un grand nombre de ces problèmes tout en vous donnant accès à la suite ( énorme de bibliothèques Java. (Comme c'est énorme? Il suffit de délimiter The Apache Software Foundation la vaste sélection pour les débutants.)

  • Les conventions d'appels et de propriété de Java sont plus régulières que celles de C.
  • La machine virtuelle Java fournit également un modèle de mémoire unique (y compris la récupération de place) pour les langues et les bibliothèques avec lesquelles interagir. Il n'est pas nécessaire de savoir qui possède quoi et qui doit nettoyer où. Le runtime le fait pour vous.
  • Le code de colle pour FFI, pour la plupart des langages construits sur la JVM, est inexistant (comme il est fourni en tant que cadre dans les coulisses du langage). Il n'est pas nécessaire de programmer en Java, par exemple, pour accéder aux bibliothèques Java dans Scala, Clojure, JRuby, etc. Vous accédez de la même manière aux objets Java vous accédez à des "objets" natifs (citations effrayantes car, par exemple, Clojure n'a pas d'objets réels dans le sens OOP) et dans votre langue maternelle.

En plus de ces avantages, vous avez également l'avantage supplémentaire d'exécuter n'importe où Java s'exécute sans recompilation (mais avec test!: écrire une fois, tester partout) et avoir accès à la technologie JIT plutôt impressionnante de Java.

Le CLR offre des forces similaires, mais ajoute ce qui est IMO une faiblesse: c'est à peu près un environnement de verrouillage des fournisseurs. (Oui, je connais Mono. Je pense toujours que c'est un environnement de blocage des fournisseurs.)

31

Selon cette interview , l'accès aux infrastructures et bibliothèques existantes Java) était la principale raison.

... Java est un langage existant avec des contraintes très dures. Par conséquent, je ne pouvais pas faire beaucoup de choses comme j'aurais voulu les faire - comme j'étais convaincu serait la bonne façon de les faire. Donc après cette période, alors que mon travail consistait essentiellement à améliorer Java mieux, j'ai décidé qu'il était temps de prendre du recul. Je voulais pour commencer avec une feuille blanche, et voir si je pouvais concevoir quelque chose de mieux que Java. Mais en même temps, je savais que je ne pouvais pas recommencer à zéro. Je devais me connecter à une infrastructure existante, parce que sinon c'est juste impossible de bootstrap vous-même à partir de rien sans bibliothèques, outils et choses comme ça.

J'ai donc décidé que même si je voulais concevoir un langage différent de Java, il se connecterait toujours à l'infrastructure Java - à la JVM et ses bibliothèques . C'était l'idée ...

18
Jeremiah

Toutes les autres langues que vous mentionnez, Erlang, Python, PHP, Ruby, Perl - elles ont toutes été créées avant Java & .NET. Si les créateurs de ces langues avaient l'environnement Java ou environnement d'exécution .NET à leur disposition à ce moment-là, il est possible qu'ils les aient exploités lors de la construction de leur langage.

Bien sûr, je ne peux pas parler pour les développeurs de ces langages, donc je ne peux pas dire avec certitude qu'ils auraient utilisé .NET et/ou Java lors de leur construction s'ils étaient disponibles, mais cela me semble être une bonne idée. Après tout, en concevant votre langage pour le compiler en Java/.NET bytecode, vous obtenez tout les avantages des compilateurs/optimiseurs JIT, votre langage s'exécute automatiquement sur toutes les plateformes sur lesquelles Java/.NET s'exécute, vous avez accès à toutes les bibliothèques Java/.NET et ainsi de suite.

10
Dean Harding

code C est compilé statiquement en code natif (code machine).

Scala est compilé statiquement en Java bytecode puis, si nécessaire, compilé dynamiquement en code natif optimisé. Le processus:

code Scala --- compilé statiquement ---> code octet JVM --- compilé dynamiquement par JVM-Hotspot-vers ---> - code natif

Options générales pour créer/exécuter n'importe quelle langue:

  • a) interpréter le code source directement via un moteur d'interprétation d'exécution
  • b) compiler statiquement du code en code natif (éventuellement via des étapes intermédiaires, par exemple source -> C -> native)
  • c) compiler statiquement le code source en code intermédiaire de niveau inférieur et l'interpréter au moment de l'exécution
  • d) compiler statiquement le code source en code intermédiaire de niveau inférieur, puis utiliser l'interprétation initiale, suivie par des techniques de compilation dynamique et d'optimisation pour convertir en code natif. Le code est interprété jusqu'à ce que des chemins d'exécution typiques et des goulots d'étranglement soient trouvés, puis le code est compilé pour une exécution plus rapide dans des conditions typiques. Il est recompilé/réajusté lorsque les conditions d'exécution changent suffisamment pour le justifier

Votre question: "Pourquoi Java utilise-t-il (d) avec une machine virtuelle Java, plutôt que (b) avec du code intermédiaire C?"

Réponse:

Tout d'abord, notez que Scala est un langage de niveau beaucoup plus élevé que C, donnant une puissance de programmation, une facilité de programmation et une concision. Il s'agit de "1 niveau supérieur" par rapport à Java en raison de fonctions de première classe et d'ordre supérieur, de fonctions implicites, de fonctions en tant qu'objets, de fermetures et de curry, de la prise en charge de la compilation de la récursivité de queue en boucles de conservation de pile rapides, tout en tant qu'objets, tous les opérateurs en tant que méthodes qui peuvent être (re) définies dans les bibliothèques, les classes de cas et la réduction (correspondance de motifs), la dérivation de type implicite, un polymorphisme plus fort grâce à des traits multi-héritables étendus et des génériques étendus, une syntaxe intégrée pour les paires et les tuples et les inconvénients (listes et arborescences) et cartes, prise en charge des structures de données immutabiles, prise en charge de puissants calculs parallèles et simultanés `` réactifs '' avec copie et transmission de messages entre les acteurs, prise en charge avancée des DSL spécifiques au domaine arbitraires, de la scriptabilité et de la REPL. Java est environ `` 1 niveau supérieur '' à C en raison de l'orientation des objets, de la gestion des pointeurs et de la récupération de place, de la prise en charge des chaînes, de la prise en charge multithread et du contrôle des accès concurrents, ainsi que des bibliothèques d'API standard.

  1. Performances: pour un langage de haut niveau, (d) donne des performances plus rapides que (a) - (c).
    Le code C écrit directement et optimisé à la main est rapide. Cependant, les langages de niveau supérieur compilés statiquement en C sont relativement lents. Les concepteurs de Java le savaient bien. Leur conception actuelle "Hotspot" augmente les performances jusqu'à un ordre de grandeur. Sur un seul cœur, Java le code HotSpot est en moyenne "50% aussi rapide" que le C optimisé par l'homme (dans le meilleur des cas, "120% aussi vite", dans le pire des cas "30% aussi vite") . Mais bien sûr, cela compare les pommes avec les oranges - code de bas niveau contre code de haut niveau. Et ce serait bien pire si l'optimisation Hotspot n'était pas utilisée. Pour confirmer, désactivez simplement la compilation du hotspot via les arguments JVM! Ou considérez Java les performances 1 et 2, lorsque le hotspot n'existait pas ou était immature. Ou essayez de compiler une autre langue via C - par exemple perlcc. Les résultats ci-dessus sont donc d'excellents résultats pour un langage puissant et productif. Avec un développement ultérieur, il est possible (ou même probable) que la JVM dépasse rapidement le C codé à la main en moyenne. Scala est à peine 70-80% aussi lent que Java en moyenne. Mais scala évolue fortement sur plusieurs cœurs (avec d'autres améliorations en cours), tandis que Java le fait partiellement et C non. Les performances Single Core pour ces langages de haut niveau sont notées:

    interprété <compilé statiquement <compilé dynamiquement

    Les performances/évolutivité multicœur sont évaluées:

    code dynamique interprété <code impératif compilé statiquement <code fonctionnel/déclaratif compilé statiquement <code fonctionnel/déclaratif compilé dynamiquement

    Cela place scala dans le siège gagnant car la vitesse du processeur a atteint sa limite et maintenant le nombre de cœurs augmente selon la loi de Moore. Scala est très rapide sur plusieurs cœurs et à l'avenir, pourrait devenir plusieurs fois plus rapide que C ou Java. La compilation statique en C n'est clairement pas l'option la plus rapide.

  2. Interopérabilité: les langues sur un VM largement pris en charge ont une meilleure interopérabilité linguistique que les langues "isolées". Scala "joue automatiquement avec" les classes Java, les interfaces et les objets en les important simplement et en les utilisant comme s'il s'agissait de classes, de traits et d'objets scala. La même chose est possible avec d'autres langages JVM tels que Groovy, Clojure, JRuby et JPython - avec une facilité d'interopérabilité dépendant de la propreté de chaque langage pour être compilé en classes d'exécution/interfaces/objets compréhensibles et utilisables Java. Cela vient pour "gratuit" (comme dans "près de"). Scala interagit avec C via JNA, le successeur de JNI - qui vient avec un certain effort, mais les outils ont été assez bien rationalisés au fil du temps. JNA peut réellement interagir avec le code natif compilé à partir de n'importe quel langage arbitraire - mais vous devez connaître la structure exacte des types de données et des fonctions compilés. Sinon, vous pouvez utiliser un objet wrapper C (ou dans le pire des cas, chaîner un mécanisme `` C vers un autre langage '' supplémentaire), pour interagir avec Objective C, C #, Perl, Ruby, Cobol, etc.

  3. Portabilité: JVM s'exécute sur des dizaines de plates-formes/versions de système d'exploitation "prêtes à l'emploi". Scala est automatiquement porté sur celles-ci. L'exception notée est iOS (iPad/iPhone/iPod) - bloqué "commercialement", plutôt que "techniquement" par Apple. Cela ne pouvait pas être prévu 12 ans auparavant, lors de la conception initiale de la JVM. JVM fonctionne bien sur des dizaines d'autres serveurs, ordinateurs de bureau, mobiles et appareils intégrés, y compris ceux qui ne prennent pas en charge C - y compris Android avec Dalvik VM Google adapté (50% + des nouveaux téléphones vendus). Bien sûr, le code C fonctionne sur une multitude de plates-formes, il peut donc être noté "là-haut avec ou probablement au-delà" Java (notamment, C est un sous-ensemble d'Objective-C). Mais C viendrait à le coût de (1), (2) & (3). Bien sûr, la couche de présentation HTML5/javascript/webkit (ou objective-C) sur iOS peut interagir avec une application scala distante - donc développeur devrait très bien le faire. Bien sûr, ils seront moins productifs.

  4. Outils et bibliothèques: De toute évidence, il existe des milliers de bibliothèques et d'outils commerciaux et open source Java qui peuvent tirer parti/être exploités par Scala - plus que pour C.

  5. Sécurité: - exécuté sur un serveur d'application contrôlé ou un environnement JVM offre un support plus fort pour les politiques et restrictions de sécurité, qui peuvent être très utiles dans un environnement d'entreprise.

6
Glen Best

JVM/CLR

La JVM (et le CLR) offrent des avantages uniques en termes d'optimisation et de portabilité du code.

Pour autant que je sache, seule la version JVM de Scala est maintenue à jour, la version .NET ne l'est pas.

4
Josh K

Il semble que vous mélangez deux choses indépendantes.

Le premier est, quel langage de programmation est utilisé par Scala auteur (s) pour implémenter Scala?

À laquelle la réponse est, Scala elle-même. Et c'est la seule réponse acceptable, vraiment, parce que si vous avez inventé ce nouveau langage, mais ne l'utilisez pas vous-même pour l'implémenter - à quoi bon pour ça?

La deuxième chose est, quelle est la plate-forme cible pour exécuter des programmes écrits en Scala?

Ici, le choix devient plus intéressant, mais pour l'instant, la seule cible qui fonctionne à 100% est JVM. La prise en charge de .NET est toujours en cours. De plus, certaines personnes travaillent pour obtenir Scala à compiler en javacsript. En théorie, rien n'empêche quelqu'un d'ajouter plus de `` backends '' pour la compilation en C, C++, LLVM, code natif ou autre.

Pourquoi JVM a été choisi comme plate-forme principale? Je suppose que c'est parce que

  • tout le monde veut la collecte des ordures
  • grand nombre de bonnes bibliothèques prêtes à l'emploi
  • un grand nombre de programmeurs s'ennuient avec Java prêt à passer à quelque chose de nouveau, mais reste dans les limites de la JVM (personne ne veut migrer son code existant vers une autre plate-forme)
3
artem

Tout d'abord - ce que je suppose que vous vouliez vraiment demander, c'est pourquoi Scala n'est pas un langage compilé de manière stricte. Je vous dirai que je ne sais pas. Mais je vous dirai aussi que il n'y a aucune raison de privilégier la JVM au code natif.

Pourquoi? La raison est simple: toute technologie de virtualisation est gourmande en mémoire, produit une surcharge inutile et une autre couche d'indirection. Ce n'est pas une question de mise en œuvre - c'est une question de fait, de la logique qui se cache derrière le concept de base de la virtualisation. Peu importe ce que vous faites, vous TOUJOURS vous retrouverez avec des caractéristiques inférieures. La JVM est particulièrement gourmande en mémoire. Ce n'est plus si lent, car il a son propre compilateur d'exécution derrière lui, mais il doit quand même exécuter le processus du compilateur pour pouvoir repérer les parties de code les plus encombrées et les transformer en code binaire.

Dit que - la seule raison, je pense, était là pour faire Scala basé sur JVM était probablement la popularité du langage. Je suppose également qu'une certaine paresse était derrière cette décision car il est plus facile d'implémenter un langage sur la JVM que de comprendre à quoi les choses devraient ressembler assemblées pour fonctionner sur plusieurs plates-formes - et même l'utilisation de backends C existants nécessite beaucoup plus de travail car les choses ne sont pas aussi standardisées qu'avec la JVM.

C'est la raison pour laquelle je peux penser, mais gardez à l'esprit qu'il peut y avoir d'autres raisons - comme la délivrance de licences et la politique impliquée là-bas (qui sont des choses sales que je n'aimerai jamais aborder).

0
luke1985