¿Cuándo sería útil usar un lenguaje de script dentro de un programa más grande?

70

He escuchado sobre varias situaciones de personas que usan say, JavaScript o Python (o algo), dentro de un programa escrito en C #. ¿Cuándo sería mejor usar un lenguaje como JavaScript para hacer algo en un programa de C # que simplemente hacerlo en C #?

Persona de Toby
fuente
1
¿Por qué alguien rechazaría esta pregunta? En mi humilde opinión es una buena pregunta.
KK.
28
Es muy útil para crear piezas de software absurdamente complejas que requieren consultores costosos para mantenerlo, especialmente cuando el lenguaje de secuencias de comandos es terrible.
cuál es
2
No tengo una "respuesta", por decir, pero el Programador pragmático tiene un capítulo sobre esto (# 12 - Idiomas de dominio). Podría proporcionarle una idea.
Craige
1
Hay algunas buenas respuestas sobre una pregunta similar sobre Desarrollo de juegos: gamedev.stackexchange.com/questions/2913/…
celion
66
A veces, es incluso mejor tener un sistema grande dentro de un lenguaje de secuencias de comandos: se llama " modo Unix ". Puede unir numerosos subsistemas distintos mediante una pequeña capa de secuencias de comandos. Se sabe que esta arquitectura es muy robusta y escalable.
SK-logic

Respuestas:

66

Cuando tiene un comportamiento que no desea tener que volver a compilar el programa para cambiarlo. Esto es exactamente por qué tantos juegos usan Lua como lenguaje de secuencias de comandos / modding.

usuario16764
fuente
42
Y también es para que los usuarios puedan agregar funcionalidad ellos mismos. Lo has implicado, pero creo que es lo suficientemente importante como para merecer que se le haga más hincapié.
2
También sandboxing. Mira la integración de Python de Blender.
meawoppl
@meawoppl ... o para agregar funcionalidad a un programa. Mire la integración de IDA de Python (apodado IDAPython)
Cole Johnson
¿Por qué no hacerlo de modo que solo necesite recompilar una biblioteca (por ejemplo, con componentes lógicos de juego específicos)?
Den
Si observa otras herramientas, como AutoCAD, Sparx Enterprise Architect, MS Word, no tiene que volver a compilarlas para escribirlas en C #.
Pete Kirkham
28

Esta técnica se puede utilizar para implementar una lógica central que sea fácilmente portátil entre diferentes entornos de lenguaje. Por ejemplo, tengo un simulador de calculadora donde toda la lógica interna de la calculadora se implementa en 100% JavaScript. El código de la interfaz de usuario es, por supuesto, diferente para cada plataforma:

  • Navegador web (JavaScript)
  • iOS (Objetivo-C)
  • Windows (C ++ con Qt)
  • Mac OS X (C ++ con Qt)
  • Java Swing (Java)

Con este arreglo, hacer versiones de mi programa para diferentes entornos operativos, y especialmente mantenerlas actualizadas, es mucho más simple.

Greg Hewgill
fuente
18

En términos generales, hay dos situaciones en las que aplicaría este patrón:

  1. Esto se usa internamente para aprovechar la calidad del lenguaje incrustado.
  2. Esto se utiliza para proporcionar programabilidad externa.

Internamente

  • Por lo general, el lenguaje incrustado se interpreta y permite realizar cambios y probarlos rápidamente sin una nueva compilación.
  • El lenguaje incrustado puede ser más expresivo que el idioma en el que está escrita su aplicación principal, permitiendo nuevamente un desarrollo más rápido.
  • El idioma puede ser más adecuado para un dominio particular en comparación con un lenguaje de propósito general.
  • El lenguaje es utilizado por usuarios internos que necesitan un lenguaje / entorno de programación "más simple". Los programas cortos están escritos por personas que no son desarrolladores de software que utilizan una sintaxis / API relativamente simple.

Un ejemplo aquí sería Lua usado en Adobe Lightroom.

Entonces, lo que hacemos con Lua es esencialmente toda la lógica de la aplicación, desde ejecutar la interfaz de usuario hasta administrar lo que realmente hacemos en la base de datos. Casi todos los fragmentos de código de la aplicación que podrían describirse como tomar decisiones o implementar características están en Lua hasta llegar al procesamiento sin procesar, que está en C ++. ( Entrevista de Mark Hamburg: Adobe Photoshop Lightroom )

Externamente

  • Permita que los usuarios amplíen el comportamiento de su aplicación sin necesidad de herramientas especiales y / o bibliotecas y / o acceso a su código fuente.
  • Proporcione a esos usuarios una API bien definida y un entorno de espacio aislado. Esto también se puede hacer en el idioma de la aplicación, pero incrustar un intérprete puede facilitarlo.

IBM utilizó lenguajes de secuencias de comandos con mucho éxito en su sistema operativo mainframe VM-CMS . EXEC , EXEC / 2 y posteriores Rexx se utilizaron en todo el sistema tanto interna como externamente. Las diferentes aplicaciones (p. Ej., XEDIT ) se podían crear mediante secuencias de comandos utilizando esos mismos lenguajes y las aplicaciones / utilidades internas (por ejemplo, correo electrónico) se escribieron en el lenguaje de secuencias de comandos y aprovecharon la estrecha integración con el sistema operativo y otras herramientas. Los clientes crearon y compartieron muchas herramientas y aplicaciones con script. DEC también proporcionó DCL . Más tarde, Microsoft admitió VBscript como lenguaje de secuencias de comandos en la mayoría de sus aplicaciones y, más recientemente, PowerShell(también archivos por lotes MS / DOS ). Los shells de Unix también tienen secuencias de comandos .

La tendencia actual parece estar exponiendo las API de alguna manera y deja la elección del lenguaje de secuencias de comandos a los usuarios que pueden utilizar diferentes enlaces u otros medios para acceder a la API.

Guy Sirton
fuente
9

Los ejemplos del mundo real incluirían: -

  • La mayoría de los navegadores web que admitirán JavaScript incrustado.

  • Microsoft Office Suite - Excel Word, etc., todos admiten scripts VBA integrados.

  • Muchos enrutadores de red incluyen API de script, en una variedad de idiomas TCL, Perl, Lua.

Muchos dispositivos integrados se implementan utilizando un conjunto muy pequeño de funciones centrales de C que se unen mediante un lenguaje de secuencias de comandos como Lua. Por lo tanto, tiene un conjunto de funciones C pequeñas y rápidas que interactúan con el hardware y, la mayor parte de la lógica de control en un lenguaje de secuencias de comandos flexible y fácil de modificar.

James Anderson
fuente
@ antony.trupe. El nombre comúnmente usado para referirse a ECMAscript - en.wikipedia.org/wiki/ECMAScript
James Anderson
4

A veces, las secuencias de comandos están integradas en una aplicación porque es un medio para extender la aplicación host por otros desarrolladores. Con el fin de capturar una gama tan amplia de habilidades de lenguaje de programación como sea posible, el host podría admitir múltiples lenguajes de secuencias de comandos. Por ejemplo, en la JVM, puede incrustar una gran cantidad de lenguajes compatibles con JSR-223 , incluidos Python, Ruby, JavaScript, etc.

Otra razón no mencionada anteriormente es que el idioma incorporado tiene una o más características destacadas que el idioma del host no podría duplicar fácilmente. Un ejemplo de esto sería la funcionalidad de Parse o la creación sin esfuerzo de DSL (lenguaje / dialecto específico del dominio) que se puede encontrar en un idioma como Rebol.

Adrian
fuente
3

Hay una forma interesante de usar un lenguaje de secuencias de comandos dentro de una aplicación que aún no han sido mencionados por los demás.

Si su idioma anfitrión tiene un tiempo de ejecución rico y reflexivo, a menudo es útil incrustar un lenguaje simple con REPL en sus aplicaciones, conectarlo a un zócalo y darle acceso a todo el sistema.

Se puede utilizar para una depuración interactiva (y es, naturalmente, mucho más potente que su depurador habitual), parches de código activo, varios propósitos de monitoreo, incluso puertas traseras (si no está haciendo nada bueno).

SK-logic
fuente
¿Naturalmente mucho más poderoso que tu depurador habitual? ¿En qué manera? ¿Cómo puede un "lenguaje de scripting externo simple" sin conocimiento intrínseco de las expresiones idiomáticas, el modelo de memoria, el modelo de objetos, los tipos de datos básicos, etc. de su idioma de host posiblemente proporcionar alguna utilidad útil que un depurador diseñado para trabajar con el lenguaje no podría?
Mason Wheeler
@MasonWheeler, ¿puedes cambiar el código con un depurador habitual? ¿Puede realizar consultas programables complejas arbitrarias sobre el estado de su tiempo de ejecución? ¿Se pueden realizar experimentos controlados complicados? Y se equivoca al suponer que un lenguaje de secuencias de comandos no tiene "conocimiento intrínseco de las expresiones idiomáticas del lenguaje anfitrión, ...". Si tanto el lenguaje principal como el de secuencias de comandos se ejecutan en una misma VM (.NET, JVM, V8, lo que sea), hay un acceso completo a todas las agallas de su lenguaje de secuencias de comandos.
SK-logic
1

Mi situación específica, cuando uso un lenguaje de script interpretado en una aplicación principal:

Hay un dispositivo externo que realiza varias funciones. Mediciones, control, lecturas. Es bastante "tonto" y requiere un control preciso, paso a paso, que incluye muchos estados de espera y toma de decisiones ad-hoc en el lado del mecanismo de control.

Se requieren diversas funcionalidades del dispositivo en varios puntos de la aplicación principal, en diferentes momentos, a menudo bajo demanda. La aplicación principal no permite estados de espera como tales, todo debe hacerse con máquinas de estados finitos.

Ahora, quien escribió una máquina de estados finitos sabe que implementar un estado de espera es efectivamente al menos dos, a menudo tres o cuatro estados internos de la máquina. Implementar veinte estados de espera para diversas funciones (y esperar sus respuestas y reaccionar en consecuencia) del dispositivo externo sería una experiencia muy, muy frustrante.

Entonces, en cambio, hay estados de "ejecutar una función sin espera", "ejecutar una función de bloqueo", "ejecutar una función de ramificación / condicional / salto" en la máquina de estados finitos, tal vez seis estados en total. Y hay scripts de control que se programan para su ejecución, luego los ejecuta el intérprete que controla el dispositivo externo y sus resultados se colocan donde se requieren.

En resumen, la aplicación: en un RTOS, el uso de un lenguaje de script interpretado interno puede reducir enormemente la complejidad de realizar tareas abundantes en estados de espera (funciones de bloqueo).

SF.
fuente
1

Desde mi experiencia, una vez desarrollamos una gran aplicación que reescribe el código fuente de una lengua "antigua" para que sea compatible con Unicode. El fue hecho en C #. Terminé escribiendo solo el motor (que crea un modelo de datos y proporciona los medios para realizar los pasos necesarios para el proceso de reescritura) en C #: el "código de pegamento" para ejecutar realmente las cosas se realiza en IronPython.

El punto más importante para el IronPython integrado: supongamos que cargó un modelo de big data (aproximadamente una hora de carga). Luego, desea -manualmente- recopilar información y buscar cosas. Hacer esto con un script de Python desde una consola interactiva es mucho mejor que hacer clic en el modelo de datos con el depurador (además, se puede volver a reproducir).

usuario82229
fuente
-2

Hay un par de razones.

  • Curva de aprendizaje. Prácticamente todos pueden aprender y escribir en JavaScript.
  • Seguridad. Es difícil controlar el contexto de seguridad del código de script en C # o Java. Javascript es perfecto para eso. El autor del script nunca podrá acceder al disco ni a ningún otro lugar si no lo permite. Core javascript engine es solo una calculadora avanzada.
  • Calidad. Pones un límite muy grueso al código de secuencias de comandos. Los niveles de "código de espagueti" son muy diferentes para Javascript o C # / Java. (Lo que te impide abrir las puertas del infierno)
  • Tipo de seguridad. C # / Java son entornos de tipo seguro, en su mayoría no lo prefiere en un entorno de secuencias de comandos. Expresiones como "12" + 3 dan "123" en javascript pero C # / Java ni siquiera se compilará. Los escritores de guiones en su mayoría ni siquiera saben qué es "tipo"
  • Dinámica. Cualquier objeto puede contener cualquier propiedad / método y puede cambiar su tipo a tiempo. Por ejemplo, podría proporcionar un objeto proxy C # para el entorno de secuencias de comandos que expone los nodos XML como propiedades.
  • Productividad. Por lo general, escribir script es mucho más fácil que C # / Java. No se requiere compilación ni "registro de complemento". Puede editar directamente el contenido del script dentro de la aplicación con resultados inmediatos.
  • Gerente. El uso de C # / Java requiere que un SDK sea un enlace en complementos que exponga las clases internas al mundo. Esta arquitectura de complemento requiere la "compatibilidad con versiones anteriores" para las versiones antiguas de SDK. Esta arquitectura lo obliga a crear objetos de dominio "virtuales" que proporcionan un mecanismo interno de aplicación en el contexto del dominio. Es más manejable / flexible que exponer una API.
Ertan
fuente
3
Esto pierde el punto de la cuestión de incrustar scripts en un programa más grande. Por ejemplo, ¿por qué elegiría un desarrollador agregar script-fu al gimp? O tener modding de Civ V con lua : ¿por qué un desarrollador elegiría agregar secuencias de comandos a una aplicación?
-3

¿Cuando? Entre 1948 y 2008, los lenguajes inicialmente compilados tomaron un tiempo considerable para compilar y vincular, por lo que era común crear un lenguaje de secuencias de comandos para permitir la personalización y configuración del usuario. Si nos fijamos en el historial de AutoLisp, la respuesta es que inicialmente AutoCAD se entrega con un lenguaje de script dentro de él, pero esto se eliminó gradualmente a favor de exponer una interfaz de script a VBA y luego a .net.

Con CLR, habilitar un programa C # o una llamada de programa Lua en un sistema existente no es significativamente diferente en costo de desarrollo, y el tiempo de ejecución .net se entrega con las herramientas para generar y compilar sobre la marcha.

Ya no necesita tener un lenguaje de scripting dentro del programa más grande, sino que expone el programa más grande a las facilidades de scripting del tiempo de ejecución.

En entornos que no ofrecen la generación y compilación de código sobre la marcha, y se considera deseable ofrecer un lenguaje de automatización de uso general en lugar de un lenguaje específico de dominio, aún obtendrá secuencias de comandos Lua o Python. Para las herramientas que ofrecen una interfaz COM, ese lenguaje de script será C # o VB.net (MS Office, Sparx Enterprise Architect). Por lo tanto, es innecesario tener un lenguaje de script para un programa escrito en un lenguaje que sea lo suficientemente simple como para ser un lenguaje de script.

Pete Kirkham
fuente
Una búsqueda en Google de juegos XNA con scripts de Lua no arroja cero resultados.
user16764
@ user16764 y una búsqueda en google de bicicletas hechas de merengue arroja seis millones.
Pete Kirkham