¿Ejemplos de cuándo usaremos lenguaje interpretado sobre lenguaje compilado?

11

Entiendo las diferencias entre los idiomas interpretados y compilados, pero si alguien pudiera proporcionar algunos ejemplos de situaciones en las que es probable que se usen idiomas interpretados sobre idiomas compilados, así como situaciones en las que es probable que se usen idiomas compilados sobre idiomas interpretados, sería Ser realmente útil.

KL
fuente

Respuestas:

11

No hay (que yo sepa) tal cosa como un "idioma" interpretado o un "idioma" compilado.

Los idiomas especifican la sintaxis y el significado de las palabras clave del código, las construcciones de flujo y varias otras cosas, pero no conozco ningún idioma que especifique si debe compilarse o interpretarse en la especificación del idioma.

Ahora, si su pregunta es cuando utiliza un compilador de idiomas frente a un intérprete de idiomas, realmente se trata de los pros / contras del compilador frente al intérprete y el propósito del proyecto.

Por ejemplo, puede usar el compilador JRuby para una integración más fácil con las bibliotecas java en lugar del intérprete ruby ​​MRI. Probablemente también haya razones para usar el intérprete de rubí MRI sobre JRuby, aunque no estoy familiarizado con el idioma y no puedo hablar de esto.

Beneficios promocionados de los intérpretes:

  • Sin compilación significa que el tiempo desde la edición del código hasta la prueba de la aplicación se puede disminuir
  • No es necesario generar binarios para múltiples arquitecturas porque el intérprete administrará la abstracción de la arquitectura (aunque es posible que deba preocuparse por los scripts que manejan los tamaños enteros correctamente, pero no por la distribución binaria)

Beneficios promocionados de los compiladores:

  • El código nativo compilado no tiene la sobrecarga de un intérprete y, por lo tanto, suele ser más eficiente en tiempo y espacio
  • La interoperabilidad suele ser mejor, la única forma de interoperación en proceso con scripts es a través de un intérprete en lugar de un FFI estándar
  • Capacidad para admitir arquitecturas para las que el intérprete no se ha compilado (como los sistemas integrados)

Sin embargo, apostaría en el 90% de los casos a que es más o menos así: quiero escribir este software en blub porque lo conozco bien y debería hacer un buen trabajo. Usaré el intérprete (o compilador) de blub porque es el método canónico generalmente aceptado para escribir software en blub.

Entonces, TL; DR es básicamente una comparación caso por caso de los intérpretes frente a los compiladores para su caso de uso particular.

Además, FFI: Interfaz de función externa, en otras palabras, interfaz para interoperar con otros idiomas. Más lecturas en wikipedia

Jimmy Hoffa
fuente
2
Que yo sepa, algunos lenguajes de script para SO como ksh para UNIX no se pueden compilar.
NoChance
@delnan, mi punto es que no se puede compilar a través de un software comercial o gratuito que conozco, no es que no se pueda compilar por razones técnicas.
NoChance
3
@EmmadKareem No hay tal cosa como "no se puede compilar". Usted escribe un programa que lee un programa en lenguaje Li y genera un programa equivalente en lenguaje La. Eso es un compilador un compilador. Dudo en invocar el argumento de integridad de Turing, ya que es un arenque rojo en la práctica, pero cada programa finalmente se convierte en una secuencia de instrucciones de código de máquina. Si todo lo demás falla, desenrolle el bucle de intérprete (y simplifique el código resultante para eliminar las partes que ya no necesita). Si el intérprete está escrito en un idioma sin intérpretes, repita hasta que encuentre algo con un compilador.
1
(Redacté mi comentario para expresarlo mejor, pero aparentemente actué demasiado tarde.) @EmmadKareem Sí, obviamente, algunos lenguajes nunca se implementaron a través de un compilador. Pero no veo cómo esto es relevante. Siempre es posible y factible hacerlo, y se puede hacer en cualquier momento con cierto esfuerzo. Esto es una consecuencia del punto principal, que es que un lenguaje no se compila ni interpreta de manera inherente, y puede implementarse de ambas maneras. Y en una miríada de otras formas (bueno, posiblemente variantes y remixes menores), por cierto.
2
@EmmadKareem si lo desea, puede tomar la especificación del lenguaje ksh y escribir un compilador que lo lea y genere un binario nativo. El idioma que se está compilando o interpretando no está en la definición de un idioma, es mi punto aquí.
Jimmy Hoffa
8

Un punto importante aquí es que muchas implementaciones de lenguaje realmente hacen algún tipo de híbrido de ambos. Muchos lenguajes de uso común en la actualidad funcionan compilando un programa en un formato intermedio, como bytecode, y luego ejecutándolo en un intérprete. Así es como se implementan Java, C #, Python, Ruby y Lua. De hecho, esta es posiblemente la forma en que se implementa la mayoría del lenguaje en uso hoy en día. Entonces, el hecho es que el lenguaje actual interpreta y compila su código. Algunos de estos idiomas tienen un compilador JIT adicional para convertir el bytecode a código nativo para su ejecución.

En mi opinión, deberíamos dejar de hablar de lenguajes interpretados y compilados porque ya no son categorías útiles para distinguir las complejidades de las implementaciones de lenguaje actuales.

Cuando pregunta sobre los méritos de los idiomas interpretados y compilados, probablemente quiere decir algo más. Tal vez se esté preguntando sobre el mérito de la tipificación estática / dinámica, los méritos de distribuir ejecutables nativos, las ventajas relativas de la compilación JIT y AOT. Todos estos son problemas que se combinan con la interpretación / compilación pero son problemas diferentes.

Winston Ewert
fuente
2

En primer lugar, un lenguaje de programación puede ser tanto interpretado como compilado. La interpretación y la compilación son solo métodos para generar código ejecutable a partir del código fuente. Con un intérprete, el código fuente está siendo leído e interpretado por un intérprete que luego ejecuta el código tal como lo interpreta. Por otro lado, un compilador lee el código fuente y genera un archivo binario ejecutable a partir del código fuente, de modo que el programa se puede ejecutar como un proceso separado de forma independiente.

Ahora, antes de que nadie se pregunte ... Sí, C / C ++ / C # / Java se puede interpretar, y sí, se pueden compilar los scripts JavaScript y Bash. Sin embargo, si hay intérpretes o compiladores en funcionamiento para estos idiomas es otra cuestión.

Ahora para responder realmente la pregunta cuando usaremos "lenguaje interpretado" sobre "lenguaje compilado". La pregunta en sí es algo confusa, pero supongo que significa cuándo preferir la interpretación sobre la compilación. Una de las desventajas de la compilación es que genera algo de sobrecarga debido al proceso de compilación: el código fuente debe compilarse en código máquina ejecutable, por lo que no es adecuado para tareas que requieren un retraso mínimo al invocar el código fuente para ejecutar un programa. Por otro lado, el código fuente compilado es casi siempre más rápido que el código fuente interpretado equivalente debido a la sobrecarga causada por la interpretación del código. Por otro lado, los intérpretes pueden invocar y ejecutar el código fuente. con muy poca sobrecarga de invocación, pero a expensas del rendimiento en tiempo de ejecución.

Al final, es casi imposible mencionar cualquier caso de uso definitivo sobre cuándo preferir uno tras otro, pero por ejemplo, uno (para mi comprensión muy poco realista) sería cuando el código fuente del programa cambia dinámicamente entre invocaciones del programa y la sobrecarga de compilación también lo es. alto para que sea una opción viable. En ese caso, probablemente sería deseable interpretar el código fuente en lugar de compilar.

Sin embargo, hay algo que puede considerarse un ejemplo del mundo real: ocultar el código fuente durante el despliegue. Con nativamentecódigo compilado, el desarrollador implementa el código ejecutable macine del programa y los datos. Con el código interpretado, se debe implementar el código fuente en sí mismo, que luego se puede inspeccionar y realizar ingeniería inversa con mucho menos esfuerzo que lo que es hacer ingeniería inversa del código de máquina nativo. Una excepción a esto son los lenguajes como C # y Java, que se compilan en lenguaje / bytecode inmediato (MSIL para C # y Java bytecode para Java) que luego se implementa y compila "justo a tiempo" en tiempo de ejecución, algo así como lo hace un intérprete. Sin embargo, existen los llamados descompiladores para MSIL y Java Bytecode que pueden reconstruir el código fuente original con una precisión relativamente buena y, como tal, la ingeniería inversa de dichos productos es mucho más trivial que los productos de ingeniería inversa que se implementan en el código de máquina nativo.

zxcdw
fuente
1
Usted hace buenos puntos, pero siendo el pedante que soy, estoy en desacuerdo con algunas frases (ambas referidas al tercer párrafo): 1. Un intérprete no compila. 2. Es insondable (aunque estas condiciones son raras) que un mal compilador no optimizador sea superado por un intérprete altamente optimizado (especialmente basado en bytecode). Esto va doblemente si cuenta los compiladores JIT con intérpretes (lo cual prefiero no hacer, pero algunas personas lo hacen).
@delnan Tal vez está mal redactado, no soy un hablante nativo de inglés. Sin embargo, por lo que puedo decir, el tercer párrafo no implica que un intérprete compile. Para el segundo punto, hice hincapié en la palabra equivalente a la similitud de énfasis del código compilado e interpretado para excluir los casos de compilador deficiente versus intérprete de alto rendimiento, tal vez no estaba claro con eso, sin embargo, no lo veo razonable centrarse en explicar casos tan extremos, ya que no contribuye en nada al punto que se establece entre las diferencias de ejecutar el código fuente compilándolo o interpretándolo
zxcdw
Lo siento, no importa el primer punto, leí mal algo. Mea culpa. En cuanto al segundo punto: tomé "equivalente" para referirme al código que se interpreta o compila (y comparar un compilador e intérprete no tiene mucho sentido, ya que hacen cosas fundamentalmente diferentes). Creo que no hay que perder el tiempo que detalla los casos extravagantes como mi ejemplo, pero prefiero dejar caer el "siempre" a favor de una redacción que explica por qué se puede ser más rápido en el primer lugar: hay intérprete sobrecarga [el cual debe ser IMHO definido], y la oportunidad de realizar optimizaciones antes del tiempo de ejecución.
1

Puedo pensar en los siguientes escenarios cuando usarías un lenguaje interpretado :

  • Donde no existe un compilador, como los scripts de shell de Linux / Unix .
  • Scripts rápidos y sucios que resuelven un pequeño problema
  • Lenguajes que facilitan la escritura de páginas HTML dinámicas y generalmente se interpretan como JSP (Tomcat lo compila en un servidor previo a ejecutar), PHP, ASP, etc.

Puedo pensar en los siguientes escenarios cuando quieres compilar tu código:

  • Es necesario para distribuir binarios porque su aplicación es de código cerrado y no quieren dar a conocer su código fuente.
  • Velocidad, como sistemas embebidos y similares.
  • Necesita un nivel de seguridad de tipo de código que solo puede proporcionarle un compilador con un lenguaje estrictamente tipado. Los compiladores exponen errores tipográficos en cada rincón y grieta de su código fuente, mientras que en los programas interpretados los errores tipográficos pueden quedar sin descubrir en el código de producción.
  • Sistemas grandes y complejos: no puedo imaginar un sistema operativo o un traje de oficina como algo más que binarios compilados.
  • Desea eliminar todos los gastos generales y necesita una buena comunicación con los fragmentos de ensamblador (difícil con cualquier tipo de tiempo de ejecución, especialmente con un intérprete) (este punto fue provocado por un comentario de @delnam)
Tulains Córdova
fuente
3
Un intérprete de idiomas hace que el idioma no sea menos tipeado. Haskell está muy fuertemente tipado y puede usar GHCI para interpretarlo de manera efectiva. La escritura fuerte / débil son aspectos de un lenguaje, no aspectos de un compilador o intérprete.
Jimmy Hoffa
1
-1 En los pros de compilación: (1) El código de compilación no protege contra la ingeniería inversa, solo lo hace un poco más difícil. (2) La compilación (eliminación de la sobrecarga del intérprete, optimización automática del código de la aplicación) es solo una fuente de rendimiento, y es superada por las optimizaciones hechas a mano a gran escala por un experto humano. (3) La verificación de tipo, aunque generalmente se combina con la compilación, es independiente de ella. Un verificador de tipo es un pase de análisis estático; Puede suceder sin emitir código y antes de interpretar el código. (4) Parece bastante espurio. Usted "no puede imaginar" eso? ¿Por qué? ¿Cómo se requiere?
1
Existen otros idiomas interpretados siempre que haya un intérprete en otro programa. Cada vez que uno usa el patrón de intérprete , hay un lenguaje interpretado de cierta complejidad.
3
Los "guiones" no se interpretan necesariamente. Muchos lenguajes de "secuencias de comandos" se compilan en código de bytes para una máquina virtual que luego se ejecuta (ver lua, perl, python, ruby). No hay una diferencia real entre esto y Java aparte de cuando tiene lugar la compilación.
3
+1, creo que ese es el tipo de respuesta que realmente buscaba el OP, y aunque los puntos pueden no ser 100% verdaderos como se señaló, hay al menos un 95% de verdad para consideraciones prácticas.
Doc Brown
1

Al final, la gran compensación es entre la productividad (cuántas líneas de código tiene que escribir) y el rendimiento (qué tan rápido se ejecutará su programa).

Debido a que los lenguajes interpretados cuando se transforman en información de CPU tienen más información, pueden confiar en la reflexión y la escritura dinámica, lo que aumenta considerablemente la productividad . Otra ventaja de los lenguajes interpretados es que son independientes de la plataforma siempre que haya un intérprete para la plataforma.

Debido a que la CPU no debe transformar el código de idioma en código de máquina y ejecutar el código al mismo tiempo, como en el caso interpretado, los idiomas compilados producen programas más rápidos. Además, un sistema construido en un lenguaje compilado es más seguro ya que puede detectar problemas en el momento de la compilación, lo que básicamente significa que ve un error al escribirlo (con IDEs modernos) en lugar de verlo solo cuando realmente ejecuta el programa (por supuesto , esto no corrige errores lógicos).

Sabiendo esto, los idiomas interpretados son adecuados para:

  1. Desarrollo productivo: desarrollo web rápido (PHP, Javascript) o para creación de prototipos.
  2. Multiplataforma; por ejemplo, JavaScript es compatible con todos los navegadores (incluidos los navegadores móviles).

Y los idiomas compilados son adecuados cuando:

  1. El rendimiento es crítico (sistemas operativos) o los recursos son escasos (microcontroladores).
  2. Los sistemas a construir son complejos; cuando se compilan sistemas grandes (sistemas empresariales), los lenguajes compilados son esenciales para manejar muchos posibles errores que pueden aparecer en los idiomas interpretados; También los programas complejos requieren muchos recursos y el equilibrio también tiende a compilar idiomas.
m3th0dman
fuente
-1 porque implica que todos los idiomas interpretados se escriben dinámicamente y todos los idiomas compilados se escriben estáticamente, lo cual es completamente falso.
Daniel Pryden
@DanielPryden Debe ser pura coincidencia, el hecho de que casi todos los idiomas interpretados se escriben dinámicamente y los compilados se escriben estáticamente. ¿Es una coincidencia que el modelo de tipo dinámico sea adecuado para idiomas interpretados?
m3th0dman el
Por varias razones, existe una correlación, pero no es un requisito. En realidad, esto se ha preguntado en StackOverflow: ¿por qué los langs interpretados son en su mayoría de tipo duck mientras que los compilados tienen un tipeo fuerte?
Daniel Pryden
1
Erlang se compila y se escribe dinámicamente. Haskell está escrito de forma estática y se puede compilar o interpretar
Zachary K
1
@ZacharyK Erlang tiene un sistema de tiempo de ejecución; Haskell se compila en la mayoría de los casos (programas escritos).
m3th0dman el
1

Además de las razones que los otros han mencionado, hay un caso de uso particularmente importante para elegir una interpretación ad hoc sobre cualquier forma de compilación o cualquier enfoque híbrido.

En caso de que se use un lenguaje de programación como protocolo de comunicación , y cuando la latencia de la respuesta sea importante, tiene más sentido evitar perder el tiempo en la compilación y cualquier posible preprocesamiento.

Esto se aplica a los idiomas del agente, por ejemplo, o la forma en que, por ejemplo, se usa normalmente Tcl / Tk.

Otra posible razón para apegarse a la interpretación es cuando se utiliza un intérprete de lenguaje para bootstrapping en sí mismo o un lenguaje más elaborado y de nivel superior, y su simplicidad es más importante que el rendimiento del proceso de bootstrap.

Para casi cualquier otro caso de uso posible, la compilación (o un enfoque híbrido) es una mejor opción.

SK-logic
fuente