O JavaScript é interpretado por design?

70

Eu estou cauteloso em fazer essa pergunta porque ela pode parecer excessivamente exigente. Acabei de abrir o JavaScript: The Definitive Guide, e afirma da primeira página do capítulo 1

"JavaScript is a high-level, dynamic, untyped interpreted programming language”

Eu devo considerar que a parte interpretada é um requisito na especificação da linguagem, ou é enganoso dizer que a linguagem é uma linguagem de programação interpretada quando se respeita a diferença entre uma linguagem e suas muitas implementações?

Não há compiladores estáticos para JavaScript aparentemente - link então talvez seja apenas um reflexo disso.

    
por Matt Esch 06.03.2012 / 16:49
fonte

4 respostas

47

So am I to take it that the interpreted part is a requirement in the language specification, or is it misleading to say that the language is an interpreted programming language when respecting the difference between a language and its many implementations?

Geeks da linguagem EcmaScript geralmente usam o termo "intérprete ES" para se referir a uma implementação do EcmaScript, mas a especificação não usa esse termo. A visão geral da linguagem em particular descreve a linguagem em termos agnósticos entre intérpretes:

ECMAScript is object-based: basic language and host facilities are provided by objects, and an ECMAScript program is a cluster of communicating objects.

Portanto, o EcmaScript assume um "ambiente de host" que é definido como um provedor de definições de objetos, incluindo todos aqueles que permitem E / S ou qualquer outro link para o mundo externo, mas não requer um interpretador.

A semântica de declarações e expressões na linguagem são definidas em termos de especificação de conclusão que são trivialmente implementadas em uma intérprete, mas a especificação não exige isso.

8.9 The Completion Specification Type

The Completion type is used to explain the behaviour of statements (break, continue, return and throw) that perform nonlocal transfers of control. Values of the Completion type are triples of the form (type, value, target), where type is one of normal, break, continue, return, or throw, value is any ECMAScript language value or empty, and target is any ECMAScript identifier or empty.

The term “abrupt completion” refers to any completion with a type other than normal.

As transferências de controle não locais podem ser convertidas em matrizes de instruções com saltos, permitindo compilação nativa ou de código de bytes.

"EcmaScript Engine" pode ser uma maneira melhor de expressar a mesma ideia.

There are no static compilers for JavaScript apparently

Isso não é verdade. O V8 "interpretador" compila internamente código nativo, o Rhino opcionalmente compila internamente o bytecode Java, e vários interpretadores do Mozilla ({Trace, Spider, Jager} Monkey) usam um compilador JIT.

V8 :

V8 increases performance by compiling JavaScript to native machine code before executing it, versus executing bytecode or interpreting it.

Rhino :

public final void setOptimizationLevel(int optimizationLevel)

Set the current optimization level. The optimization level is expected to be an integer between -1 and 9. Any negative values will be interpreted as -1, and any values greater than 9 will be interpreted as 9. An optimization level of -1 indicates that interpretive mode will always be used. Levels 0 through 9 indicate that class files may be generated. Higher optimization levels trade off compile time performance for runtime performance. The optimizer level can't be set greater than -1 if the optimizer package doesn't exist at run time.

TraceMonkey :

TraceMonkey adds native‐code compilation to Mozilla’s JavaScript® engine (known as “SpiderMonkey”). It is based on a technique developed at UC Irvine called “trace trees”, and building on code and ideas shared with the Tamarin Tracing project. The net result is a massive speed increase both in the browser chrome and Web‐page content.

    
por 06.03.2012 / 18:16
fonte
19

A V8 JavaScript VM usada no Chrome não inclui um intérprete. Em vez disso, consiste em dois compiladores e compila o código em tempo real. Um dos compiladores é executado rapidamente, mas gera código ineficiente, o outro é um compilador otimizado.

Eu posso entender por que algumas pessoas considerariam essa "trapaça", já que o V8 usa o código-fonte como entrada toda vez que o código é executado e o usuário precisa ter o V8 instalado. Mas considere um compilador que emite um executável que inclua um intérprete e bytecode completos. Então você teria um programa autônomo. Apenas não seria muito eficiente.

    
por 06.03.2012 / 17:08
fonte
18

O surgimento de compiladores JIT para linguagens de script tem confundido a linha entre compilação e interpretação a um ponto em que a questão não significa tanto assim. É apenas interpretação quando o motor lê uma linha de código e a executa imediatamente? (Scripts de shell ainda são normalmente implementados dessa maneira.) É interpretação quando o mecanismo leva o arquivo inteiro, imediatamente o compila para algum código de byte e, em seguida, interpreta o código de byte? (O mecanismo Mozilla de primeiro estágio funciona dessa maneira, assim como o CPython.) É interpretação quando o mecanismo analisa uma função por vez e o JIT o compila para código nativo? E quanto aos mecanismos que compilam o arquivo inteiro para o código de byte, então JIT uma função de cada vez, conforme necessário? (A maioria dos mecanismos de script atualmente funciona dessa maneira, e a VM Java principal também funciona dessa maneira, exceto que a compilação para código de byte acontece antes do tempo.)

Existem muitos tons entre compilação e interpretação.

Acho que a definição mais útil para interpretação é "é alimentado com o código-fonte do programa em tempo de execução, sem uma etapa separada antes do tempo". Por essa definição, todos os mecanismos de JavaScript são intérpretes. Mas esta certamente não é a única definição possível de interpretação.

Mas o JavaScript é projetado para interpretação? De certo modo, sim: ele tem uma função eval , assim como o construtor Function , que você pode dar ao código do programa como uma string que será executada. A capacidade de construir dinamicamente o código do programa no tempo de execução requer que o mecanismo seja capaz de interpretar o código-fonte. Mas isso não significa que você não possa fazer todo o resto antes do tempo. Mesmo em uma linguagem compilada como C ++ e C # você pode pegar o código fonte, compilá-lo na memória para o novo código de máquina e depois executá-lo. Existem até bibliotecas para isso: LLVM + Clang em C ++ e o projeto Roslyn em C #.

Além disso, o mecanismo de entrega para JavaScript é o código fonte; não há nenhum código de byte reconhecido. C # e Java têm seu código de byte oficial e todos esperam que o C ++ seja entregue como código de máquina. Mas isso ainda não é um aspecto inerente à linguagem, apenas um cenário de uso dominante. Na verdade, o ActionScript relacionado ao JavaScript em Flash é, de fato, fornecido como código de byte (o compilador do Flash pré-compila todos os scripts).

    
por 07.05.2015 / 10:33
fonte
4

Não há uma definição totalmente acordada de "interpretado" versus "compilado". Na distinção clássica, as linguagens compiladas produzem um executável binário autônomo, enquanto as linguagens interpretadas exigem um tempo de execução implantado para executar o código. Máquinas virtuais, bytecode e assim por diante apagam a distinção.

Mas aqui está uma definição possivelmente útil: Uma linguagem interpretada é uma linguagem em que o tempo de execução da linguagem padrão é capaz de obter o texto do código-fonte como entrada e executá-lo. Por essa definição, Perl, Python, Ruby, JavaScript e shell scripts e similares são interpretados (mesmo se eles usarem passos intermediários como bytecode ou mesmo código nativo). Java, C #, C etc. não são. E o JavaScript é interpretado por definição, mesmo que a especificação não use a palavra exata.

    
por 07.05.2015 / 14:19
fonte

Tags