19

¡Creo que Coffeescript es un lenguaje increíble! Estaba buscando algunos proyectos/problemas/características que agreguen Análisis Estático a Coffeescript. Sin embargo, después de buscar, encontré que el Coffeescript faq y this page sugieren que el análisis estático podría no ser viable.Análisis estático de Coffeescript/Comprobación estática de tipos: publicaciones simultáneas

Me preguntaba si hay un problema fundamental al implementar el análisis estático/comprobación de tipo estático en Coffeescript, debido a que algo de este tipo no existe en el compilador.

Además, ¿es algo que no es posible hacer para comprobaciones no triviales pero que podría funcionar solo para un análisis directo? Cuando digo directo me refiero a buscar elementos triviales como si el usuario ha definido una función dos veces con el mismo nombre (en una clase) o en el nivel superior (o tal vez en el nivel superior de una colección de archivos .coffee relacionados) .

Agradecería que alguien pudiera por favor señalar algunos ejemplos que muestran por qué la implementación de análisis estáticos/verificación de tipos no es directa/posible/vale la pena gastar tiempo en?

Muchas gracias!

+0

¿Qué tal si ejecuta jshint en los archivos JS generados? El café compila las herramientas JS y JS que hacen lo que estás buscando no son exactamente raras. –

Respuesta

13

Esta respuesta es un poco un vuelco del cerebro ya que estoy interesado en esto también. Espero eso ayude.

Utilizo Google Closure Compiler para analizar estáticamente el código que CoffeeScript genera. Tiene un analizador estático realmente bueno, y no estoy seguro de si hay una buena razón para reinventar la rueda aquí. La manera más fácil es simplemente escribir las anotaciones a mano:

###* 
    * @param {number} x 
    * @param {number} y 
    * @return {number} 
### 
adder = (x, y) -> x + y 

Es un poco prolijo, pero por otro lado se está pidiendo prestado las capacidades de análisis estático del compilador de cierre que es muy potente y es capaz de comprobar mucho. De hecho, escribo anotaciones de tipo de una manera un poco más concisa, luego tengo un guión para reescribir el archivo de café. Mi código termina pareciéndose a esto:

#! {number} x {number} y @return {number} 
adder = (x, y) -> x + y 

estoy seguro de que puede ver que la re-escritura es bastante sencillo.

Una nota rápida antes de continuar. Asegúrese de compilar su código con -b (vacío) si lo está ejecutando a través del compilador de cierre. El compilador de cierre es bastante bueno, pero no es lo suficientemente inteligente como para realizar análisis de flujo de datos. CoffeeScript ajusta su código en una función anónima de forma predeterminada, lo que hará que el compilador se desconecte.

Otra opción por el mismo camino (esto rompería la compatibilidad con CoffeeScript, pero sería un enfriador de mucho) sería tener el compilador de café compilar algo como esto:

adder = (number x, number y): number -> x + y 

en JS así:

que luego se podría alimentar al compilador de cierre en una compilación; si no hubiera errores, el compilador podría quitar todos los comentarios.

De hecho, this guy parecía estar haciendo exactamente esto. Lamentablemente, su trabajo parece estar en un estado incompleto.

En todos estos casos, diferimos el trabajo arduo (comprobación de tipo estático) del compilador de cierre. Si no quiere hacer esto, lo entendería, pero sería difícil convencerme de que vale la pena construir una nueva herramienta de análisis estático desde cero. :)

EDITAR un año después: Solo uso mecanografiado en estos días. :)

+4

Azúcar sintáctico para la tipificación de estadísticas opcional sería un asesino :) –

+0

@MikkoOhtamaa: Estoy de acuerdo. Lamentablemente, jashkenas, el creador de CoffeeScript, es bastante intenso al mantener CoffeeScript muy cerca de JavaScript, y las ramas del lenguaje tienden a languidecer en la oscuridad. Ojalá hubiera alguna forma de obtener lo mejor de ambos mundos. – thedayturns

8

No soy un experto en CoffeeScript, por lo que esta podría ser la respuesta completamente incorrecta, pero básicamente se reduce a esto: CoffeeScript es un lenguaje muy expresivo, con la mayoría de la semántica determinada dinámicamente) Esto contrasta mucho con lenguajes como el estándar ML, que tienen una semántica mucho más estrictamente definida. En general, hacer análisis estático en idiomas de orden superior se considera muy difícil. Es decir, el análisis estático en programas de orden superior reales (Haskell, ML, especialmente javascript debido a cosas como eval) es simplemente difícil porque el flujo de control es mucho más flexible. De hecho, las soluciones de análisis estático para lenguajes de orden superior realmente solo se han explorado en los últimos veinte años más o menos. (En particular, véase el artículo de Matt fuerza En a tutorial style description of CFA.)

Básicamente, las razones son esto:

  • Para ello análisis, tiene que lidiar con el problema de la semántica expresivos próximos forma el control de flujo obtienes funciones de orden superior.
  • Para hacer escribiendo, generalmente estos lenguajes tienen un conjunto mucho más rico de tipos que están disponibles. Por ejemplo, hay situaciones muy típicas en las que si intentas asignar un tipo estático a una variable en Ruby (como en C, Java, ML, etc.) obtienes un error, pero debido a que ciertas rutas de tu programa nunca son ejecutado, todo está bien. Junto con eso, los lenguajes como Ruby otros agregan una plétora de conversiones de tipo implícito que son realmente usado para hacer una programación genial. El trabajo notable en este área con el que estoy familiarizado (dynamic analysis of static types for Ruby) proviene de algunas de las personas con las que trabajo, pero sin duda hay otros ejemplos.
  • Básicamente, el lenguaje se utiliza de una forma mucho más dinámica manera, con un aspecto mucho más expresivos la semántica, y el razonamiento acerca de que estáticamente es mucho más difícil, y con tendencia a ser imprecisas. El frente básico de abordar esto (en estos días) está comenzando a parecer híbrido: puede analizar estáticamente parte de un programa, y ​​también requerir que el programador proporcione algunos casos de prueba para realizar algún tipo de análisis refinado.

espero que esto de alguna manera responde a sus preguntas, de nuevo, lo siento, no se refieren directamente a las preocupaciones directas de su pregunta que se aplica a CoffeeScript, pero hay mucho del trabajo que se realiza en el análisis de las cosas como JavaScript ahora mismo. Notaré que algunos de los problemas reales con Javascript provienen de su semántica extraña, la herencia prototípica es difícil de razonar, y especialmenteeval()! Por lo general, los análisis de programas para estos lenguajes imponen ciertas restricciones (por ejemplo, descartar completamente la evaluación) para hacer que el análisis sea más factible.

+0

Solo para una actualización en el campo de los lenguajes dinámicos "typechecking": supongo que ya conoce proyectos como Typescript y Flowjs. ¡Aclamaciones! –

Cuestiones relacionadas