Exemplos de quando usaremos linguagem interpretada sobre linguagem compilada?

11

Entendo as diferenças entre idiomas interpretados e compilados, mas se alguém puder fornecer alguns exemplos de situações em que é provável que alguém use idiomas interpretados sobre idiomas compilados, bem como situações em que provavelmente usará idiomas compilados em idiomas interpretados, seria seja realmente útil.

KL
fonte

Respostas:

11

(Que eu saiba) não existe uma "linguagem" interpretada ou uma "linguagem" compilada.

Os idiomas especificam a sintaxe e o significado das palavras-chave, construções de fluxo e várias outras coisas do código, mas não conheço nenhum idioma que especifique se deve ou não ser compilado ou interpretado nas especificações de idioma.

Agora, se a sua pergunta é quando você usa um compilador de linguagem versus um intérprete de linguagem, ele realmente se resume aos prós / contras do compilador versus o intérprete e ao objetivo do projeto.

Por exemplo, você pode usar o compilador JRuby para facilitar a integração com as bibliotecas java em vez do interpretador MRI ruby. Provavelmente, também existem razões para usar o intérprete de MRI ruby ​​no JRuby, embora eu não esteja familiarizado com o idioma e não possa falar sobre isso.

Touted benefícios dos intérpretes:

  • Nenhuma compilação significa que o tempo entre a edição do código e o teste do aplicativo pode ser diminuído
  • Não há necessidade de gerar binários para várias arquiteturas porque o interpretador irá gerir a arquitetura de abstração (embora você pode precisar se preocupar ainda sobre os scripts de manipulação inteiro tamanhos corretamente, não apenas a distribuição binária)

Benefícios apontados pelos compiladores:

  • O código nativo compilado não possui a sobrecarga de um intérprete e, portanto, geralmente é mais eficiente no tempo e no espaço
  • A interoperabilidade geralmente é melhor, a única maneira de interoperação em proc com scripts é através de um intérprete, em vez de um FFI padrão
  • Capacidade de suportar arquiteturas para as quais o intérprete não foi compilado (como sistemas incorporados)

No entanto, aposto que em 90% dos casos é mais ou menos assim: quero escrever este software em blub porque o conheço bem e deve fazer um bom trabalho. Usarei o interpretador de blub (ou compilador) porque é o método canônico geralmente aceito para escrever software no blub.

Portanto, TL; DR é basicamente uma comparação caso a caso dos intérpretes versus os compiladores do seu caso de uso específico.

Além disso, FFI: Foreign Function Interface, em outras palavras, interface para interoperar com outros idiomas. Mais leitura na wikipedia

Jimmy Hoffa
fonte
2
Que eu saiba, algumas linguagens de script para SO, como ksh para UNIX, não podem ser compiladas.
NoChance
@ delnan, meu argumento é que não posso ser compilado por meio de um software comercial ou gratuito que eu conheço, não que não possa ser compilado por motivos técnicos.
NoChance
3
@EmmadKareem Não existe algo que não possa ser compilado. Você escreve um programa que lê um programa na linguagem Li e gera um programa equivalente na linguagem La. Esse é um compilador, um compilador. Hesito em invocar o argumento de completação turing, pois na prática é um arenque vermelho, mas cada programa acaba se transformando em uma sequência de instruções de código de máquina. Se tudo mais falhar, desenrole o loop do interpretador (e simplifique o código resultante para remover as partes que você não precisa mais). Se o intérprete for escrito em um idioma sem intérpretes, repita até você acertar algo com um compilador.
1
(Redigi meu comentário para melhor expressá-lo, mas aparentemente agi muito tarde.) @EmmadKareem Sim, obviamente alguns idiomas nunca foram implementados por meio de um compilador. Mas não vejo como isso é relevante. É sempre possível e viável fazê-lo, e pode ser feito a qualquer momento com algum esforço. Isso é uma consequência do ponto principal, que é que uma linguagem não é inerentemente compilada nem interpretada, e pode ser implementada de ambos os modos. E de inúmeras outras maneiras (bem, sem dúvida pequenas variantes e remixes), a propósito.
2
@EmmadKareem, se você quiser, pode pegar a especificação da linguagem ksh e escrever um compilador que a leia e gere um binário nativo. A linguagem que está sendo compilada ou interpretada não está na definição de uma linguagem, é o meu ponto aqui.
Jimmy Hoffa
8

Um ponto importante aqui é que muitas implementações de linguagem realmente fazem algum tipo de híbrido de ambas. Atualmente, muitas linguagens comumente usadas compilam um programa em um formato intermediário, como bytecode, e executam isso em um intérprete. É assim que Java, C #, Python, Ruby e Lua são tipicamente implementados. De fato, é sem dúvida o modo como a maioria dos idiomas em uso atualmente é implementada. Portanto, o fato é que hoje a linguagem interpreta e compila seu código. Algumas dessas linguagens possuem um compilador JIT adicional para converter o código de bytes em código nativo para execução.

Na minha opinião, devemos parar de falar sobre linguagens interpretadas e compiladas porque elas não são mais categorias úteis para distinguir as complexidades das implementações de linguagem atuais.

Quando você pergunta sobre os méritos das linguagens interpretadas e compiladas, provavelmente quer dizer outra coisa. Você pode estar perguntando sobre o mérito da tipagem estática / dinâmica, os méritos da distribuição de executáveis ​​nativos, as vantagens relativas da compilação JIT e AOT. Todos esses são problemas que se confundem com a interpretação / compilação, mas são problemas diferentes.

Winston Ewert
fonte
2

Antes de tudo, uma linguagem de programação pode ser tanto interpretada como compilada. Interpretação e compilação são apenas métodos de geração de código executável a partir do código fonte. Com um intérprete, o código-fonte está sendo lido e interpretado por um intérprete que, em seguida, executa o código como ele o interpreta. Um compilador, por outro lado, lê o código-fonte e gera um arquivo binário executável a partir do código-fonte - para que o programa possa ser executado como um processo separado independentemente.

Agora, antes que alguém se pergunte ... Sim, C / C ++ / C # / Java podem ser interpretados e sim, scripts JavaScript e Bash podem ser compilados. Se há intérpretes ou compiladores de trabalho para esses idiomas, é outra questão.

Agora, para realmente responder à pergunta, quando usaremos "linguagem interpretada" em vez de "linguagem compilada". A questão em si é um pouco confusa, mas presumo que isso significa quando preferir a interpretação à compilação. Uma das desvantagens da compilação é que ela gera alguma sobrecarga devido ao processo de compilação - o código-fonte precisa ser compilado no código de máquina executável, para que não seja adequado para tarefas que exigem um atraso mínimo ao invocar o código-fonte para executar um programa. Por outro lado, o código fonte compilado é quase sempre mais rápido que o código fonte interpretado equivalente devido à sobrecarga causada pela interpretação do código. Os intérpretes, por outro lado, podem invocar e executar o código fonte com muito pouca sobrecarga de invocação, mas à custa do desempenho em tempo de execução.

No final, é quase impossível mencionar casos de uso definidos quando preferir um após o outro, mas, por exemplo, um caso (para o meu significado muito irreal) seria quando o código-fonte do programa muda dinamicamente entre invocações de programas e a sobrecarga de compilação é muito alta. alto para que seja uma escolha viável. Nesse caso, provavelmente seria desejável interpretar o código fonte em vez de compilar.

No entanto, há algo que pode ser considerado um exemplo do mundo real: ocultar o código-fonte na implantação. Com nativamentecódigo compilado, o desenvolvedor implementa o código macine executável do programa e dos dados. Com o código interpretado, o próprio código-fonte precisa ser implantado, o que pode ser inspecionado e submetido a engenharia reversa com muito menos esforço do que o que é fazer engenharia reversa do código de máquina nativo. Uma exceção a isso são linguagens como C # e Java, que são compiladas no idioma / bytecode imediato (MSIL para C # e bytecode Java para Java), que são implementadas e compiladas "just in time" no tempo de execução, como um intérprete. No entanto, existem os chamados decompiladores para MSIL e Java Bytecode que podem reconstruir o código-fonte original com uma precisão relativamente boa e, como tal, esses produtos de engenharia reversa são muito mais triviais do que os produtos de engenharia reversa implementados no código de máquina nativo.

zxcdw
fonte
1
Você faz boas observações, mas sendo o pedante que sou, discordo de algumas frases (ambas referentes ao terceiro parágrafo): 1. Um intérprete não compila. 2. É aceitável (embora essas condições sejam raras) que um compilador ruim que não seja otimizado seja derrotado por um intérprete altamente otimizado (especialmente baseado em bytecode). Isso vale duplamente se você contar os compiladores JIT em intérpretes (o que eu prefiro não fazer, mas algumas pessoas fazem isso).
@dnnan Talvez tenha sido mal escrito, eu não sou um falante nativo de inglês. No entanto, tanto quanto posso dizer no terceiro parágrafo, não implica que um intérprete compile. Para o segundo ponto, enfatizei a palavra equivalente à semelhança de ênfase do código compilado e interpretado para excluir os casos de compilador ruim versus intérprete de alto desempenho, talvez eu não estivesse sendo claro com ele, mas não o vejo. razoáveis para se concentrar em explicar tais casos extremos, uma vez que em nada contribui para o ponto a ser feita entre as diferenças de código fonte execução de compilação ou iterpreting-lo
zxcdw
Desculpe, esqueça o primeiro ponto, eu interpretei algo errado. Mea culpa. Quanto ao segundo ponto: usei "equivalente" para me referir ao código que é interpretado ou compilado (e comparar um compilador e intérprete não faz muito sentido, pois eles fazem coisas fundamentalmente diferentes). Eu não acho que se deva perder tempo detalhando casos estranhos como o meu exemplo, mas eu prefiro abandonar o "sempre" em favor de um fraseado que explique por que pode ser mais rápido em primeiro lugar: nenhum intérprete indireto [que deveria ser IMHO definido] e oportunidade de realizar otimizações antes do tempo de execução.
1

Posso pensar nos seguintes cenários quando você usaria uma linguagem interpretada :

  • Onde não existe nenhum compilador, como scripts de shell do Linux / Unix .
  • Scripts rápidos e sujos que resolvem um pequeno problema
  • Linguagens que facilitam a escrita de páginas HTML dinâmicas e são geralmente interpretadas como JSP (o Tomcat compila em um previos de servidor para execução), PHP, ASP etc.

Posso pensar nos seguintes cenários quando você deseja compilar seu código:

  • Você precisa distribuir binários porque seu aplicativo é de código fechado e não deseja fornecer seu código-fonte.
  • Velocidade, como sistemas embarcados e similares.
  • Você precisa de um nível de segurança de tipo de código que somente um compilador com uma linguagem estritamente digitada possa fornecer. Os compiladores expõem erros de digitação em todos os cantos do código-fonte, enquanto que em programas interpretados, erros de digitação podem não ser descobertos no código de produção.
  • Sistemas grandes e complexos: não pode imaginar um sistema operacional ou um traje de escritório como algo além de binários compilados.
  • Você deseja eliminar todos os custos indiretos e precisa de uma boa comunicação com os snippets do assembler (difícil com qualquer tipo de tempo de execução, especialmente com um intérprete) (esse ponto foi causado por um comentário do @delnam)
Tulains Córdova
fonte
3
Um intérprete de idioma torna o idioma não menos fortemente digitado. Haskell é extremamente fortemente tipado e você pode usar o GHCI para interpretá-lo efetivamente. Tipagem forte / fraca são aspectos de um idioma, não aspectos de um compilador ou intérprete.
21713 Jimmy Jimmy -offoff
1
-1 Sobre os profissionais de compilação: (1) O código de compilação não protege contra a engenharia reversa, apenas o torna um pouco mais difícil. (2) A compilação (remoção da sobrecarga do intérprete, otimização automatizada do código do aplicativo) é apenas uma fonte de desempenho e é superada por otimizações feitas em larga escala por um especialista humano. (3) A verificação de tipo, embora geralmente associada à compilação, é independente dela. Um verificador de tipos é um passe de análise estática; isso pode acontecer sem emitir código e antes de interpretá-lo. (4) Parece bastante falso. Você "não pode imaginar" isso? Por quê? Como é necessário?
1
Existem outras linguagens interpretadas sempre que houver um intérprete em outro programa. Sempre que alguém estiver usando o padrão de intérprete , há uma linguagem interpretada de alguma complexidade.
3
"scripts" não são necessariamente interpretados. Muitas linguagens de "script" são compiladas no bytecode para uma máquina virtual que é então executada (consulte lua, perl, python, ruby). Não há diferença real entre isso e java, exceto quando a compilação ocorre.
3
+1, acho que esse é o tipo de resposta que o OP realmente buscava e, embora os pontos possam não ser 100% verdadeiros, como apontado, existem pelo menos 95% verdadeiros para considerações práticas.
Doc Brown)
1

No final, o grande dilema é entre produtividade (quantas linhas de código você precisa escrever) e desempenho (com que rapidez seu programa será executado).

Como as linguagens interpretadas, quando transformadas em informações da CPU, têm mais informações, elas podem contar com reflexão e digitação dinâmica que aumentam bastante a produtividade . Outra vantagem das linguagens interpretadas é que elas são independentes da plataforma, desde que haja um intérprete para a plataforma.

Como a CPU não deve transformar o código do idioma no código da máquina e executá-lo ao mesmo tempo, como no caso interpretado, os idiomas compilados produzem programas mais rápidos. Além disso, um sistema construído em uma linguagem compilada é mais seguro, pois pode detectar problemas em tempo de compilação, o que basicamente significa que você vê um erro ao digitá-lo (com IDEs modernos) em vez de vê-lo apenas quando você executa o programa (é claro) , isso não corrige erros lógicos).

Sabendo disso, os idiomas interpretados são adequados para:

  1. Desenvolvimento produtivo: desenvolvimento web rápido (PHP, Javascript) ou para prototipagem.
  2. Plataforma cruzada; por exemplo, o JavaScript é suportado em todos os navegadores (incluindo navegadores móveis).

E os idiomas compilados são adequados quando:

  1. O desempenho é crítico (sistemas operacionais) ou os recursos são escassos (microcontroladores).
  2. Os sistemas a serem construídos são complexos; ao criar sistemas grandes (sistemas corporativos), linguagens compiladas são essenciais para lidar com muitos possíveis erros que podem aparecer em idiomas interpretados; Além disso, programas complexos exigem muitos recursos e o equilíbrio tende também a linguagens compiladas.
m3th0dman
fonte
-1 porque você implica que todos os idiomas interpretados são digitados dinamicamente e todos os idiomas compilados são estaticamente, o que é completamente falso.
Daniel Pryden
@DanielPryden Então deve ser pura coincidência o fato de que quase todas as linguagens interpretadas são digitadas dinamicamente e as compiladas estaticamente? É uma coincidência que o modelo de tipo dinâmico seja adequado para linguagens interpretadas?
M3th0dman 6/11/12
Por várias razões, há uma correlação, mas não é um requisito. Na verdade, isso foi perguntado no StackOverflow: Por que os langs interpretados são tipicamente tipados enquanto a compilação possui digitação forte?
precisa saber é o seguinte
1
Erlang é compilado e digitado dinamicamente. Haskell é digitado estaticamente e pode ser compilado ou interpretado
Zachary K
1
@ZacharyK Erlang tem um sistema de tempo de execução; Haskell é compilado na maioria dos casos (programas escritos).
M3th0dman 7/11
1

Além dos motivos mencionados pelos outros, há um caso de uso particularmente importante para escolher uma interpretação ad hoc sobre qualquer forma de compilação ou qualquer abordagem híbrida.

Caso uma linguagem de programação seja usada como protocolo de comunicação e quando a latência da resposta seja importante, faz mais sentido evitar perder tempo na compilação e em qualquer pré-processamento possível.

Isso se aplica aos idiomas dos agentes, por exemplo, ou à maneira como, digamos, Tcl / Tk é normalmente usado.

Outro motivo possível para continuar com a interpretação é quando um intérprete de idioma é usado para iniciar por si próprio ou por uma linguagem mais elaborada e de nível superior, e sua simplicidade é mais importante que o desempenho do processo de inicialização.

Para quase qualquer outro caso de uso possível, a compilação (ou uma abordagem híbrida) é mais adequada.

SK-logic
fonte