Por que o Scala não foi implementado com C ou C ++

28

Alguém sabe por que o Scala foi implementado em Java e .NET em vez de C ou C ++? A maioria das linguagens é implementada com Cor C ++ [ou seja, Erlang, Python, PHP, Ruby, Perl]. Quais são as vantagens do Scala implementado em Java e .NET além de fornecer acesso às bibliotecas Java e .NET?

ATUALIZAR

O Scala não obteria mais benefício se fosse implementado em C porque pode ser ajustado melhor do que depender da JVM?

Joshua Partogi
fonte
18
Além disso, poder usar as bibliotecas Java existentes e interagir fortemente com o código java é um benefício enorme, não uma coisa pequena.
Tamás Szelei
6
@OP: você fala como se fosse ruim ter uma linguagem implementada no topo da JVM (ou CLR). O ajuste que você menciona que é possível em C não chega nem perto da quantidade de ajuste colocada no CLR ou na JVM. E se a plataforma melhorar, seu idioma automaticamente o obtém gratuitamente. Dada a escolha, ninguém deve mais implementar sua linguagem em cima do good'ol C imho.
quer
8
@Chii, apenas admiti-lo, Java ainda mais lento é que C.
Joshua Partogi
19
@ jpartogi, Java não pode ser mais lento ou mais rápido que C. Eles são ambos idiomas, não garanhões. Em algumas condições específicas, algum código específico compilado pelo compilador Java e executado com uma certa JVM é mais lento que um código aproximadamente comparável, gerado por um compilador C. Em algumas outras condições, o último será mais lento.
SK-lógica
4
O ambiente de tempo de execução do Scala é um programa C ++; a JVM.
mike30

Respostas:

59

A questão é confusa, pois C e C ++ são linguagens , enquanto a JVM é uma máquina virtual e o .Net é uma plataforma . O Scala pode ser implementado em C ou C ++ e gerar código de máquina em vez de código de código para uma máquina virtual.

Respondendo à pergunta que foi feita:

O Scala não foi implementado em C ou C ++ porque o Scala, a linguagem na qual é realmente implementada, é uma linguagem muito melhor.

Porque é melhor? Bem, leia os objetivos de Odersky para o idioma Scala .

Respondendo à pergunta que pode ter sido pretendida:

O Scala gera principalmente o bytecode da JVM, pois fornece grande portabilidade, além de recursos como um coletor de lixo confiável e eficiente, otimizações em tempo de execução e compilação just-in-time pela JVM .

Deixe-me repetir a última coisa: a JVM irá compilará os pontos de acesso do código de máquina no código em execução. Isso é compilar exatamente como os compiladores C e C ++.

Existem outras máquinas virtuais disponíveis, mas Odersky, criador da Scala, já estava muito familiarizado com a JVM. Ele pretendia ter o CLR como uma alternativa, mas o esforço para fazer isso ainda não obteve sucesso.

Respondendo à pergunta que poderia / deveria ter sido feita:

A compilação no código da máquina não fornece benefícios suficientes sobre a compilação no bytecode da JVM.

Certamente, é possível gerar marcas de microbench em C ou C ++ que superem os equivalentes da JVM. Também é verdade que o código extremamente otimizado em C ou C ++ superará o código extremamente otimizado em Java ou Scala. A diferença não é tão grande, no entanto, para programas de longa duração.

Observe que Scala não é uma linguagem de script particularmente boa precisamente porque a sobrecarga para programas de execução curta é muito grande.

No entanto, na maioria dos casos, a velocidade de desenvolvimento e a facilidade de manutenção são mais importantes que a velocidade de execução . Nesses casos, onde as pessoas estão mais preocupadas em escrever códigos de nível muito alto que sejam facilmente compreendidos e alterados, as otimizações em tempo de execução fornecidas pela JVM podem superar facilmente as otimizações em tempo de compilação feitas pelos compiladores C ou C ++, tornando a JVM (e CLR ) o destino que realmente será executado mais rapidamente.

Portanto, não importa se a pergunta era sobre o compilador Scala sendo um código de máquina executável ou programas Scala sendo código de máquina, os possíveis ganhos de velocidade não necessariamente se traduzem em ganhos reais de velocidade.

E, aliás,

Vou lhe dar um contra-exemplo: Haskell. Haskell gera código de máquina e, ainda assim, os programas Haskell se saem pior no tiroteio do Debian do que no Scala. Dado isso, alguém pode ter certeza de que os programas Scala seriam mais rápidos se compilados diretamente no código da máquina?

Daniel C. Sobral
fonte
3
@ mike30 O Scala funcionaria em qualquer JVM, mesmo que não estivesse escrita em C ++, para que o argumento não se mantenha. E, no tempo de execução, não há código C ++, apenas código de máquina. Não sei ao certo sobre o que é esse comentário.
Daniel C. Sobral
3
o ponto real é: gerar código de máquina é muito mais complexo do que gerar código de bytes e requer uma implementação específica para todos os sistemas operacionais ao redor, além de ajuste em CPUs e arquiteturas diferentes (ARM, x86, x86_64) e instruções avançadas (MMX, SSE ...) Portanto, dessa maneira é delegado à JVM esse aspecto.
Raffaello
2
Se você fala muito sobre o desempenho da execução, por que não fala sobre o desempenho da memória? Você tem medo de que as coisas não saiam tão bem quanto você imagina?
luke1985
3
@ lukasz1985 Ele impulsiona o desempenho, mas a discussão sobre o desempenho cobre isso, portanto é irrelevante a esse respeito. Tudo o que resta é se você se importa com a quantidade de memória que um aplicativo ocupa e, em seguida, precisa escolher entre o GC e isso, e eu o escolherei sempre, exceto em espaços de desenvolvimento muito específicos, nenhum dos quais ocupado pelo Scala. E "ninguém está certo em dizer" é besteira - todo mundo TEM esse direito. E embora o C / C ++ seja muito relevante devido ao legado, eles nunca se tornariam populares se tivessem sido lançados nos últimos cinco anos.
Daniel C. Sobral
3
@ lukasz1985 Sua única evidência de que não entendo é que discordo de você. Uma explicação alternativa para isso é que você está errado. E, como alguém vivo e programando "então", tenho uma perspectiva em primeira mão da tomada de decisão envolvida na escolha de C e C ++ em detrimento de alternativas contemporâneas, que menciono não para provar meu argumento, mas para oferecer um contraponto ao seu: similaridade a linguagem falada não era relevante, enquanto a semelhança com o código da máquina era.
21916 Daniel C. Sobral
31

Um dos grandes obstáculos que os idiomas enfrentam ao serem apresentados ao mundo em geral é a disponibilidade de bibliotecas. A resposta tradicional a isso tem sido fornecer uma FFI (interface de função externa) baseada em C para permitir o acesso a bibliotecas baseadas em C. Isso não é ideal por várias razões, entre elas a principal:

  • Existem várias maneiras pelas quais as bibliotecas desejam interagir que não são compatíveis com muitas linguagens de nível superior. Por exemplo, se a biblioteca deseja um ponteiro para a struct, como os idiomas sem ponteiros E sem structlida?
  • Existem interações duras entre modelos de memória de diferentes bibliotecas e linguagens que geralmente não são solucionáveis ​​ou, se resolvíveis, são altamente propensas a erros e erros.
  • O código de cola para muitos FFIs não é trivial e pressupõe conhecimentos que podem não ser, de fato, universais. (Acredite ou não, nem todos os programadores são curus, e nem querem ser nem devem ser!)

Isso fica ainda pior com o C ++. C ++ nem é compatível com C ++ (em nível binário, quero dizer) de compilador a compilador na mesma plataforma (!), Sem mencionar outras linguagens.

A segmentação da JVM resolve muitos desses problemas, fornecendo acesso ao conjunto absolutamente enorme de bibliotecas baseadas em Java. (Quão grande? Basta analisar a enorme seleção de iniciantes da The Apache Software Foundation .)

  • As convenções de chamada e propriedade de Java são mais regulares que as de C.
  • A JVM também fornece um único modelo de memória (incluindo coleta de lixo) para linguagens e bibliotecas, ambas com as quais interagir. Não há necessidade de acompanhar quem possui o quê e o que precisa limpar onde. O tempo de execução faz isso por você.
  • O código de cola para a FFI, para a maioria dos idiomas criados na JVM, é inexistente (como é fornecido como uma estrutura nos bastidores da linguagem). Não é necessário programar em Java, por exemplo, para acessar bibliotecas Java no Scala, Clojure, JRuby, etc. Você acessa os objetos Java da mesma maneira que acessa "objetos" nativos (aspas assustadoras porque, por exemplo, Clojure não objetos reais no sentido de POO) e no seu idioma nativo.

Além dessas vantagens, você também tem as vantagens adicionais de executar em qualquer lugar que o Java é executado sem recompilação (mas com teste !: escreva uma vez, teste em qualquer lugar) e tenha acesso à impressionante tecnologia JIT do Java.

O CLR fornece forças semelhantes, mas acrescenta o que é um ponto fraco da IMO: é praticamente um ambiente de aprisionamento de fornecedores. (Sim, eu sei sobre o Mono. Ainda acho que é um ambiente de aprisionamento de fornecedores.)

APENAS MINHA OPINIÃO correta
fonte
3
Você percebe que o C # e o CLR são na verdade um padrão aberto que qualquer um pode usar.
Erin
7
Eu acho que o pouco sobre onde eu "conheço o Mono" e depois "ainda acho que é um ambiente de aprisionamento de fornecedores" deve lhe dar uma pista, Erin.
APENAS MINHA OPINIÃO correta
3
@ Err nem todo o .NET Framework é
alternativa
1
@alternative: Se isso é demais, considere que os testes de conformidade com o Java ainda não são gratuitos e, na melhor das hipóteses, são 6 de um, meia dúzia do outro para Java.
Deduplicator
18

De acordo com esta entrevista , o acesso à infraestrutura e bibliotecas Java existentes foi o principal motivo.

... Java é uma linguagem existente com restrições muito rígidas. Como resultado, eu não podia fazer muitas coisas da maneira que gostaria de fazê-las - a maneira como estava convencido seria a maneira certa de fazê-las. Então, depois desse tempo, quando o foco principal do meu trabalho era melhorar o Java, decidi que era hora de dar um passo atrás. Eu queria começar com uma planilha limpa e ver se conseguia projetar algo melhor que o Java. Mas, ao mesmo tempo, sabia que não poderia começar do zero. Eu tive que me conectar a uma infraestrutura existente, porque, caso contrário, é impraticável inicializar-se do nada sem bibliotecas, ferramentas e coisas assim.

Então, decidi que, embora desejasse projetar uma linguagem diferente de Java, ela sempre se conectaria à infraestrutura Java - à JVM e suas bibliotecas . Essa foi a ideia ...

Jeremias
fonte
10

Todas as outras linguagens mencionadas, Erlang, Python, PHP, Ruby, Perl - todas foram criadas antes do Java e .NET. Se os criadores dessas linguagens tivessem o ambiente de tempo de execução Java ou .NET disponível para eles no momento, é possível que eles os tenham aproveitado ao criar sua linguagem.

É claro que não posso falar pelos desenvolvedores dessas linguagens; portanto, não posso dizer com certeza que eles usariam .NET e / ou Java ao construí-los, caso estivessem disponíveis, mas me parece um boa ideia. Afinal, ao projetar sua linguagem para compilar no bytecode Java / .NET, você obtém todas as vantagens dos otimizadores / compiladores JIT, sua linguagem é executada automaticamente em todas as plataformas nas quais o Java / .NET é executado, você tem acesso a todos as bibliotecas Java / .NET e assim por diante.

Dean Harding
fonte
2
As vantagens descritas são algumas das razões pelas quais, por exemplo, o Python foi reimplementado para JVM (Jython) e .NET (IronPython).
dancek
2
-1: Assumir que novos idiomas poderiam ter sido dependentes de uma plataforma específica (.Net ou JVM) porque eles estariam disponíveis não me parece um bom argumento. Por exemplo, não vejo nenhuma boa razão para o Python ou o Erlang rodarem nessa plataforma. A história não diz tudo.
Klaim
1
E mesmo o PHP nunca seria capaz de fazer o que faz na JVM ou no .Net. @ Dean Harding> Eu não acho que o IronPython ou o Jython tenham provado algo de valor.
Klaim
1
Desculpe, eu não estava claro, o que eu quis dizer é que ele não teria "sucesso" (PHP ou Python), porque o trabalho em uma JVM ou .Net implica muitas coisas que teriam irritado muitos desenvolvedores, tornando eles têm mais linguagem de nicho do que atualmente. No lado técnico, a plataforma (.Net ou JVM) teria sido um problema, pois conduz a maneira como você constrói um idioma sobre ela. Declarar com a máquina é uma maneira de criar exatamente o idioma que você deseja. Portanto, com ou sem a JVM disponível, vejo 0 boas razões para construir sobre .Net e JVM. Diferente de implementação rápida.
Klaim
2
Correção pequena: Java é mais antigo que PHP. Mas o PHP começou como programa CGI, mais tarde se tornou um módulo httpd do Apache e, como tal, tornou-se grande. Ambas as coisas (módulo cgi e httpd) não funcionam bem para Java. Portanto, as coisas não são tão fáceis, uma JVM não é a plataforma para tudo. ;-)
johannes
6

O código C é estaticamente compilado no código nativo (código de máquina).

O Scala é estaticamente compilado no bytecode java e, conforme necessário, compilado dinamicamente para código nativo otimizado. O processo:

Código Scala --- código compilado estaticamente em ---> código de bytes da JVM --- código compilado dinamicamente por JVM-Hotspot para ---> código nativo

Opções gerais para criar / executar qualquer idioma:

  • a) interpretar o código-fonte diretamente por meio de um mecanismo de intérprete em tempo de execução
  • b) compilar estaticamente o código para o código nativo (possivelmente por estágios intermediários, por exemplo, fonte -> C -> nativa)
  • c) compilar estaticamente o código fonte para o código intermediário de nível inferior e interpretá-lo em tempo de execução
  • d) compilar estaticamente o código fonte para o código intermediário de nível inferior e, em seguida, usar a interpretação inicial, seguida por técnicas dinâmicas de compilação e otimização para converter em código nativo. O código é interpretado até encontrar caminhos e gargalos típicos de execução e, em seguida, o código é compilado para uma execução mais rápida em condições típicas. É recompilado / reajustado quando as condições de execução mudam o suficiente para garantir isso

Sua pergunta: "Por que o Java usa (d) com uma JVM, em vez de (b) com código intermediário C?"

Responda:

Em primeiro lugar, observe que Scala é muitolinguagem de nível superior a C, fornecendo poder de programação, facilidade de programação e concisão. É sobre '1 nível mais alto' que Java devido a funções de primeira classe e de ordem superior, funções implícitas, funções como objetos, fechamentos e currying, suporte para compilação de recursão de cauda para loops de conservação de pilha rápidos, tudo como objetos, todos os operadores como métodos que pode ser (re) definido em bibliotecas, classes de casos e redução (correspondência de padrões), derivação implícita de tipos, polimorfismo mais forte por meio de traços multi-herdáveis ​​expandidos e genéricos expandidos, sintaxe integrada para pares e tuplas e contras (listas e árvores ) e mapas, suporte para estruturas de dados imutáveis, suporte para computação paralela e reativa 'reativa' poderosa com cópia e passagem de mensagens entre atores, suporte avançado para DSLs arbitrárias específicas do domínio, capacidade de script e o REPL. O Java é '1 nível superior' a C devido à orientação a objetos, gerenciamento de ponteiros e coleta de lixo, suporte a cadeias, suporte a vários threads e controle de simultaneidade, além de bibliotecas API padrão.

  1. Desempenho: para um idioma de alto nível, (d) oferece desempenho mais rápido que (a) - (c).
    O código C diretamente escrito e otimizado à mão é rápido. No entanto, linguagens de nível superior compiladas estaticamente em C são relativamente lentas. Os designers de java sabiam disso muito bem. Seu atual design "Hotspot" aumenta o desempenho em uma ordem de magnitude. Em um único núcleo, o código do Java HotSpot é, em média, '50% mais rápido 'que o C otimizado para humanos (no melhor caso,' 120% mais rápido ', no pior caso, '30% mais rápido'). Mas é claro que está comparando maçãs com laranjas - código de baixo nível x código de alto nível. E isso seria muitopior se a otimização do Hotspot não foi usada. Para confirmar, basta desativar a compilação do ponto de acesso via args da JVM! Ou considere o desempenho do java 1 e 2, quando o ponto de acesso não existia ou era imaturo. Ou tente compilar outro idioma via C - por exemplo, perlcc. Portanto, os resultados acima são ótimos para uma linguagem poderosa e produtiva. Com o desenvolvimento adicional, é possível (ou até provável) que a JVM em breve supere o C codificado manualmente em média. Scala é apenas 70-80% mais lento que o java em média. Mas o scala escala fortemente em vários núcleos (com outras melhorias em andamento), enquanto o java faz parcialmente e o C não. O desempenho do núcleo único para esses idiomas de alto nível é classificado:

    interpretado <compilado estaticamente <compilado dinamicamente

    O desempenho / escalabilidade multinúcleo está classificado:

    código dinâmico interpretado <código imperativo compilado estaticamente <código funcional / declarativo compilado estaticamente <código funcional / declarativo compilado dinamicamente

    Isso coloca a scala no lugar vencedor, porque a velocidade do processador atingiu seu limite e agora o número de núcleos está aumentando pela lei de Moore. O Scala é muito rápido em múltiplos núcleos e, no futuro, pode se tornar várias vezes mais rápido que C ou java. Compilar estaticamente em C claramente não é a opção mais rápida.

  2. Interoperabilidade: os idiomas em uma VM amplamente suportada têm melhor interoperabilidade de idiomas do que os idiomas 'isolados'. O Scala "brinca automaticamente com" classes, interfaces e objetos java simplesmente importando-os e usando-os como se fossem classes, características e objetos do scala. Semelhante é possível com outras linguagens da JVM, como Groovy, Clojure, JRuby e JPython - com facilidade de interoperabilidade, dependendo de quão limpa cada linguagem foi feita para compilar para classes / interfaces / objetos de tempo de execução Java compreensíveis e utilizáveis. Isso vale muito para 'grátis' (como em 'próximo a'). O Scala interopera com o C via JNA, o sucessor do JNI - que vem com algum esforço, mas as ferramentas foram bastante bem simplificadas ao longo do tempo. O JNA pode realmente interoperar com o código nativo compilado a partir de qualquer linguagem arbitrária - mas você deve conhecer a estrutura exata dos tipos de dados e funções compilados. Se não,

  3. Portabilidade: a JVM é executada em dezenas de plataformas / versões de sistemas operacionais 'prontas para uso'. O Scala é automaticamente portado para eles. A exceção notável é o iOS (iPad / iPhone / iPod) - bloqueado 'comercialmente', em vez de 'tecnicamente' pela Apple. Isso não poderia ter sido antecipado 12 anos antes, durante o design inicial da JVM. A JVM funciona bem em dezenas de outros servidores, desktops, celulares e dispositivos incorporados, incluindo aqueles que não suportam C - incluindo o Android com o Dalvik VM adaptado ao Google (mais de 50% dos novos telefones vendidos). Certamente, o código C funciona em várias plataformas, portanto pode ser classificado 'lá em cima ou provavelmente além' de Java (notavelmente, C é um subconjunto do Objective-C). Mas C custaria (1), (2) e (3). Obviamente, a camada de apresentação HTML5 / javascript / webkit (ou objetivo-C) no iOS pode interoperar com um aplicativo de escala remota - portanto, o desenvolvedor deve fazer isso. Claro, eles serão menos produtivos.

  4. Ferramentas e bibliotecas : Obviamente, existem milhares de bibliotecas e ferramentas Java comerciais e de código aberto que podem aproveitar / ser aproveitadas pelo Scala - mais do que para C.

  5. Segurança: - a execução em um servidor de aplicativos controlado ou em um ambiente JVM oferece suporte mais forte a políticas e restrições de segurança, que podem ser altamente valiosas em um ambiente corporativo.

Glen Best
fonte
4

JVM / CLR

A JVM (e o CLR) oferecem vantagens exclusivas em termos de otimização e portabilidade de código.

Até onde eu sei, apenas a versão JVM do Scala está sendo mantida atualizada, a versão .NET não.

Josh K
fonte
3

Parece que você está misturando duas coisas não relacionadas.

O primeiro é: qual linguagem de programação é usada pelos autores do Scala para implementar o Scala?

Para qual é a resposta, o próprio Scala. E é a única resposta aceitável, realmente, porque se você inventou essa nova linguagem, mas não a utiliza para implementá-la - para que serve?

A segunda coisa é: qual é a plataforma de destino para executar programas escritos no Scala?

Aqui a escolha se torna mais interessante, mas, por enquanto, o único destino que funciona 100% é a JVM. O suporte ao .NET ainda está em andamento. Além disso, algumas pessoas estão trabalhando para que o Scala seja compilado para javacsript. Em teoria, nada impede que alguém adicione mais 'back-end' para compilar em C, C ++, LLVM, código nativo ou qualquer outra coisa.

Por que a JVM foi escolhida como plataforma principal? Meu palpite é porque

  • todo mundo quer coleta de lixo
  • grande número de boas bibliotecas prontas para uso
  • grande número de programadores entediados com Java prontos para pular para algo novo, mas permanecem dentro dos limites da JVM (ninguém deseja migrar seu código existente para outra plataforma)
artem
fonte
Não vejo por que um coletor de lixo não pode ser implementado com C ou C ++? Não vejo isso como uma boa razão. Python fizeram isso. Ruby fez isso. Heck mesmo erlang ter feito isso. Quem sabe que o Scala pode acabar com um coletor de lixo melhor se for escrito em C ou C ++?
Joshua Partogi
1
Eu quis dizer coleta de lixo 'real'. Não acho que essa coleta de lixo que provoque perguntas como essa seja boa o suficiente. Heck mesmo JVM não é bom o suficiente - caso contrário, pessoas como AzulSystems não seriam capazes de ganhar a vida, ajudando outras pessoas a superar deficiências JVM.
Artem
Além disso, bibliotecas. É realmente difícil usar bibliotecas escritas para gerenciamento explícito de memória em um idioma com coleta de lixo. Uma indicação é a insistência peculiar do java de ter tudo em 'java puro'.
Artem
0

Primeiro de tudo - o que eu acho que você realmente queria perguntar é por que o Scala não é uma linguagem compilada de maneira estrita. Eu vou te dizer que não sei. Mas vou lhe dizer também que não há razão para favorecer a JVM sobre o código nativo.

Por quê? O motivo é simples: qualquer tecnologia de virtualização consome muita memória, produz sobrecarga desnecessária e outra camada de indireção. Isso não é uma questão de implementação - é uma questão de fato, da lógica que está por trás do conceito principal de virtualização. Não importa o que você faça, você sempre terá características inferiores. Especialmente a JVM tem muita memória. Não é mais tão lento, porque possui seu próprio compilador de tempo de execução rodando atrás, mas ainda assim - ele precisa executar o processo do compilador para poder detectar as partes mais congestionadas do código e transformá-las em código binário.

Disse que - a única razão pela qual acho que estava lá para criar o Scala JVM provavelmente foi a popularidade do idioma. Também acho que alguma preguiça estava por trás dessa decisão, porque é mais fácil implementar uma linguagem sobre a JVM do que descobrir como as coisas devem parecer montadas para funcionar em várias plataformas - e mesmo o uso de back-end C existente exige muito mais trabalho devido ao fato de que que as coisas não são tão padronizadas quanto na JVM.

Essa é a razão pela qual consigo pensar, mas lembre-se de que pode haver outras razões - como emissão de licenças e política envolvida lá (que são coisas sujas em que nunca vou gostar de me meter).

luke1985
fonte
-2

Não está claro que ter capacidade de ajustar melhor seria uma boa opção. As JVMs podem otimizar em tempo de execução, e isso geralmente é bom o suficiente, se não superior ao que normalmente acontece com a compilação estática. (Obviamente, em princípio, para um aplicativo e carga de trabalho específicos, deve ser possível vencer o JIT com otimizações estáticas, mas praticamente você não tem a carga de trabalho precisa ou mesmo o aplicativo inteiro).

Bruce Stephens
fonte
este lê mais como um comentário, consulte Como responder
mosquito