¿Cuáles son los pros y los contras de Coffeescript? [cerrado]

48

Por supuesto, un gran profesional es la cantidad de azúcar sintáctica que conduce a un código más corto en muchos casos. En http://jashkenas.github.com/coffee-script/ hay ejemplos impresionantes. Por otro lado, tengo dudas de que estos ejemplos representen códigos de aplicaciones complejas del mundo real. En mi código, por ejemplo, nunca agrego funciones a objetos desnudos, sino a sus prototipos. Además, la función del prototipo está oculta para el usuario, lo que sugiere una OOP clásica en lugar de un Javascript idiomático.

El ejemplo de comprensión de matriz se vería en mi código probablemente así:

cubes = $.map(list, math.cube); // which is 8 characters less using jQuery...
Philip
fuente
77
Eso no es comprensión de la matriz. Eso es JQuery.map ().
Rein Henrichs
1
Claro, por lo tanto, no me estoy refiriendo a la "comprensión de matriz" en sí, sino al "ejemplo de comprensión de matriz [en el sitio web]".
Philip
Lo suficientemente justo. Mi punto era solo que foldl (mapa) es de alguna manera un caso degenerado de comprensión de listas (que generalmente es más poderoso).
Rein Henrichs
Bueno, básicamente estoy haciendo esta pregunta porque me pregunto si es una decisión estúpida usar Javascript en lugar de Coffeescript. Estoy de acuerdo, la comprensión de la matriz es mucho más poderosa, por otro lado, nadie diría que Python es más poderosa que Ruby debido a la comprensión de la matriz y al marcado de bloques por sangría en lugar de comenzar / terminar.
Philip
Rails hizo que el script de café fuera una joya predeterminada. Provocó "discusión" github.com/rails/rails/commit/…
generalhenry

Respuestas:

53

Soy el autor de un próximo libro sobre CoffeeScript:
http://pragprog.com/titles/tbcoffee/coffeescript

Estaba convencido de que valía la pena usar CoffeeScript después de una semana de jugar con él, a pesar de que el lenguaje tenía solo unos pocos meses en ese momento y tenía muchos más asperezas que ahora. El sitio oficial hace un gran trabajo al enumerar (la mayoría de) las características del idioma, por lo que no las repetiré aquí. Más bien, solo diré que los pros del lenguaje son:

  1. Fomenta el uso de buenos patrones de JavaScript
  2. Desalienta los antipatrones de JavaScript
  3. Hace que incluso el código JavaScript sea más corto y más legible

El número 3 recibe mucha más atención que los dos primeros (incluso en mi libro), pero cuanto más lo pienso, más me doy cuenta de que no hice el salto solo por la bonita sintaxis; Di el salto porque el lenguaje me empujó hacia un JavaScript mejor y menos propenso a errores. Para dar algunos ejemplos rápidos:

  • Debido a que las variables tienen un alcance automático, no puede sobrescribir accidentalmente los globales al omitir var, sombrear una variable con el mismo nombre (excepto con argumentos con nombre) o tener variables en diferentes archivos que interactúan (consulte https://stackoverflow.com/questions / 5211638 / pattern-for-coffeescript-modules / 5212449 ).
  • Porque ->es muchísimo más fácil de escribir que function(){}, es más fácil usar devoluciones de llamada. La sangría semántica deja en claro cuando las devoluciones de llamada están anidadas. Y =>hace que sea más fácil de preservar thiscuando sea apropiado.
  • Debido a que unless xes más fácil de analizar para los angloparlantes que if (!x), y if x?es más fácil que if (x != null), dar solo dos ejemplos, puede gastar menos ciclos cerebrales en la sintaxis lógica y más en la lógica misma.

Una gran biblioteca como Underscore.js puede solucionar algunos de estos problemas, pero no todos.

Ahora para los contras:

  1. La compilación puede ser un dolor. Los errores de sintaxis que arroja el compilador CoffeeScript a menudo son vagos. Espero que se avance en ese camino en el futuro. (En defensa del compilador, a menudo detecta cosas que, si las escribiera en JavaScript, no las descubriría como un error hasta que se ejecutara esa línea de código. Es mejor detectar esos errores más pronto que tarde).
  2. Relacionado, la depuración puede ser un dolor. Todavía no hay ninguna manera de hacer coincidir las líneas JS compiladas con el CoffeeScript original (aunque la gente de Firefox ha prometido que esto vendrá).
  3. Es propenso a cambiar. Su código puede ejecutarse de manera diferente o no ejecutarse en una versión futura de CoffeeScript. Por supuesto, este es el caso con la mayoría de los lenguajes (cambiar a una nueva versión de Ruby o Python es similar), pero no es el caso con JavaScript, donde puede esperar razonablemente que el código que se ejecuta correctamente en los principales navegadores de hoy se ejecute correctamente en los principales navegadores mientras exista la web tal como la conocemos.
  4. No es tan conocido. JavaScript es una lengua franca . CoffeeScript se ha vuelto muy popular en poco tiempo, pero es poco probable que alguna vez disfrute de una comunidad tan amplia como JavaScript.

Obviamente, creo que los profesionales superan los inconvenientes para mí personalmente, pero ese no será el caso para cada persona, equipo o proyecto. (Incluso Jeremy Ashkenas escribe mucho JavaScript). CoffeeScript se ve mejor como un excelente complemento para JavaScript, no como un reemplazo.

Trevor Burnham
fuente
2
Whoa whoa whoa, ¿cómo demonios me perdí =>en la documentación? Eso es impresionante . (Los otros puntos también fueron buenos, muy buena respuesta imparcial con una lista honesta de contras. :)
Michelle Tilley
Gracias por tu respuesta detallada. Aunque esperaré un poco para aceptarlo, sería interesante tener pros / contras considerando los diferentes enfoques de OOP.
Philip
2
Diría que el modelo de clase de CoffeeScript es más accesible para los recién llegados que el modelo prototipo de JavaScript y admite buenas prácticas (en particular, definir sus prototipos en un lugar en lugar de dispersar Foo.prototype.bar = ...líneas por todas partes, ¡lo cual es una locura!). Es una excelente manera de organizar el código limpiamente. Por otro lado, puede hacer que las personas usen OOP incluso cuando un enfoque funcional es mucho más elegante.
Trevor Burnham
Parte de la lógica de sangría no se comporta como se esperaba, debe mirar el JS subyacente para ver que se ha hecho algo que es totalmente extraño. Puede ser parte del conjunto de reglas tbh, pero no siempre es obvio frente a otros lenguajes sensibles a sangría como Py, y he descubierto que esto puede generar errores más sutiles que los que está destinado a prevenir. Sin embargo, todavía uso CoffeeScript
sa93
1
Los puntos 1 y 2 necesitan detalles. Creo que la respuesta de Andrew proporciona un buen ejemplo de # 3 como una bolsa mixta. No estoy de acuerdo con las viñetas: olvidar var es una tontería y no debería tener muchos vars globales con los que colisionar en primer lugar, 'función' no es difícil: métodos con nombre predefinidos, menos aún, 'if (! X ) 'es breve y dulce y' a menos que 'lo haga más detallado (ver su propia viñeta anterior y punto # 3) y la semejanza del lenguaje humano no es en realidad un objetivo de diseño que históricamente haya tenido mucho éxito en los lenguajes de programación. Necesitamos estar en contacto con humanos y máquinas.
Erik Reppen
30

Tenemos una base de código JavaScript algo grande y hace aproximadamente un mes decidimos probar CoffeeScript. Uno de nuestros desarrolladores comenzó migrando uno de nuestros módulos de JS a CS usando http://js2coffee.org/ . Esta herramienta fue bastante útil y tardó unas dos o tres horas en portar unas 1000 líneas de JavaScript. Algunas observaciones que hemos notado en ese punto:

  1. El código resultante de CoffeeScript era bastante legible.

  2. Lo compilamos de nuevo a JavaScript y fue bastante fácil de navegar y depurar. Mientras estábamos portando ese módulo, otro desarrollador de nuestro equipo encontró un error en él. Estos dos desarrolladores corrigieron ese error en nuestro antiguo código JavaScript y en el nuevo código JavaScript que salió del compilador CS. Trabajaron de forma independiente y les llevó aproximadamente la misma cantidad de tiempo (15-20 minutos).

  3. Debido al hecho de que era un puerto, el código resultante no usaba funciones específicas de Coffee que fueran apropiadas o deseables. Si escribiéramos en CoffeeScript desde cero, el código sería más idiomático. Debido a eso más tarde, decidimos que no portaremos el código existente.

  4. En general, la legibilidad de la función más corta y el objeto más pequeño aumentó en cierta medida. Sin embargo, para métodos más largos ese no era el caso en absoluto. Los mayores ahorros de hinchazón provienen ->y son explícitos return, pero aparte de eso, nuestro código no se había vuelto significativamente más corto o más simple. Algunas piezas de sintaxis parecían bastante confusas, especialmente los literales de objetos. CS omite llaves entre las definiciones de los miembros y combina con "todo es una expresión" e implícito returnque hizo que algunos bits de código fueran bastante difíciles de leer.

    Aquí está JavaScript:

    var rabbitGenerator = {
        makeRabbit: function(rabbitName, growCarrots) {
            if (growCarrots) {
                carrots.growMore(10);
            } else {
                carrots.ensureSupply();
            }
            return {
                name: rabbitName, 
                height: 0,
                actions: {
                    jump: function (height) {
                        this.height += height;
                    },
                    eatCarrot: function () {
                        // etc
                    }
                }
            };
        },
        // more members
    }
    

    Y así es como se vería el código correspondiente de CoffeeScript:

    rabbitGenerator = 
      makeRabbit: (rabbitName, growCarrots) ->
        if growCarrots
          carrots.growMore 10
        else
          carrots.ensureSupply()
        name: rabbitName // (*)
        height: 0
        actions: 
          jump: (height) ->
            @height += height
    
          eatCarrot: ->
    

    Como es ahora, es bastante difícil darse cuenta de que la declaración de retorno comienza en la (*)línea. En nuestro proyecto, dependemos en gran medida de los literales de objetos: los pasamos como parámetros de función y los devolvemos de otras funciones. En muchos casos, estos objetos tienden a ser bastante complejos: con miembros de diferentes tipos y varios niveles de anidamiento. En nuestro caso, la sensación general era que el código CoffeeScript era realmente más difícil de leer que el código JavaScript simple.

  5. Aunque la depuración de CoffeeScript resultó ser más fácil de lo que esperábamos, la experiencia de edición se ha degradado bastante. No pudimos encontrar un buen editor / IDE para este idioma. No hemos estandarizado el editor / IDE para el código del lado del cliente para nuestro proyecto y, de hecho, todos utilizamos diferentes herramientas. De hecho, todos en un equipo están de acuerdo en que cuando cambian a CoffeeScript obtienen un soporte bastante pobre de su herramienta. Los complementos IDE y editor están en una forma muy temprana y, en algunos casos, ni siquiera nos pueden dar un resaltado de sintaxis adecuado o soporte de sangría. No hablamos de fragmentos de código o refactorización. Usamos WebStorm, Eclipse, NetBeans, VisualStudio, Notepad ++ y SublimeText2.

  6. Hablando de herramientas, debo mencionar que el compilador CoffeScript viene como un paquete Node JS. Somos una tienda primaria de Java / .NET, por lo que todos están desarrollando en cajas de Windows. Hasta hace poco, el soporte de Windows era casi inexistente en Node. No pudimos hacer que el compilador CoffeeScript se ejecutara en Windows, así que por el momento decidimos seguir con las <script type="text/coffeescript">etiquetas y el compilador sobre la marcha basado en el navegador.

    El compilador es bastante rápido y no aumenta mucho el tiempo de inicio. La desventaja es que el JavaScript resultante se evaledita y es un poco difícil colocar puntos de interrupción en las herramientas de desarrollo de los navegadores (especialmente en IE8). Si tenemos dificultades con la depuración, precompilamos el código CoffeeScript con la misma herramienta de migración que mencioné anteriormente, pero aún así no es muy conveniente.

  7. Otras promesas de CoffeeScript, como la varinserción automática o la gestión semitransparente de thiscon el operador de flecha gruesa ( =>) resultaron no proporcionar tanta ganancia como esperábamos. Ya usamos JSLint como parte de nuestro proceso de compilación y escribimos código en un ES3 x ES5-Strictsubconjunto del lenguaje. De todos modos, el hecho de que Coffee produzca el mismo tipo de código "limpio" es algo bueno . ¡Ojalá todos los marcos del lado del servidor produjeran marcas válidas de HTML5 y CSS3 también!

    Dicho esto, no diría que CoffeeScript ahorra mucho tiempo al poner varpalabras clave para mí. Desaparecidos vars son fácilmente capturados por JSLint y son fácilmente corregibles. Además, una vez que te corrigen por un tiempo, de todas formas comienzas a escribir JavaScript correctamente . Por lo tanto, no diría que el café es realmente tan útil en este sentido.

Evaluamos CoffeeScript durante aproximadamente una semana. Todos los miembros del equipo escribían código en él y compartimos nuestras experiencias entre nosotros. Escribimos un código nuevo con él y portamos un código existente cuando lo creíamos conveniente. Nuestros sentimientos sobre el idioma fueron mixtos.

En general, diría que no aceleró nuestro desarrollo, pero tampoco nos ha frenado. Algunas ganancias de velocidad debido a menos tipeo y menos superficie de error fueron compensadas por ralentizaciones en otras áreas, principalmente soporte de herramientas. Después de una semana , decidimos que no exigiremos el uso de CoffeeScript, pero tampoco lo prohibiremos . Dada una libre elección, en la práctica nadie la usa, al menos por ahora. De vez en cuando pienso en crear prototipos de alguna característica nueva y luego convertir el código a JavaScript antes de integrarlo con el resto del proyecto para comenzar más rápido, pero aún no he probado ese enfoque.

Andrew Андрей Листочкин
fuente
10

Pros

ver la respuesta de Trevor Burnham .

Además, puedes pensar en ti mismo como un tipo moderno, que está haciendo cosas de moda, en lugar de jugar con la suciedad de JavaScript.

Contras

CoffeeScript no es más que azúcar sintáctica y gafas rosas.

Para cosas fáciles: CoffeeScript es redundante, porque hacer cosas fáciles es fácil en cualquier lenguaje. Y jQuery es probablemente incluso más simple que CoffeeScript.

Para cosas difíciles, debes entender tu medio. Y su medio es HTML, DOM y CSS, Javascript es simplemente una herramienta para interconectarlos, sin embargo, todas las API están escritas específicamente para Javascript. Usar otro lenguaje, que luego se compilaría en uno "real", es bastante arriesgado, ya sea Java (GWT), Dart o CoffeeScript.

Los antipatrones o la ignorancia banal de las reglas del lenguaje se pueden solucionar leyendo uno o dos buenos libros. Y estoy bastante seguro de que Coffeescript tiene sus propios antipatrones.

El soporte de IDE para Coffeescript es incluso peor que para JS.

c69
fuente
JavaScript es mucho más que una simple "herramienta para interconectarlos" en aplicaciones web altamente dinámicas y a gran escala. La cantidad de JS en bibliotecas como React o Angular, incluso jQuery, es un buen ejemplo.
Andy
6

El mayor profesional, en mi opinión es:

Coffescript directo se compila en el javascript que debería haber escrito, pero no lo hizo, porque no era sencillo.

Hay algunos rincones desagradables de javascript que solo se evitan con vigilancia, ejemplos fuera de mi cabeza:

  • configurar el prototipo correctamente
  • usando === en lugar de ==
  • comprobación de nulo
  • declarando todas las variables con var
  • envolviendo todo en una función anónima autoejecutable.

Si escribe coffeescript, todos esos se manejan automáticamente .

Los inconvenientes son, en mi opinión, en su mayoría menores:

  • La depuración es un dolor
  • Hay menos programadores de coffeescript
  • Tiene que traducir la documentación de javascript a coffeescript.
Sean McMillan
fuente
3

pros

  1. CoffeeScript me ha ayudado a aprender más sobre JavaScript
  2. es bastante fácil de leer, incluso para devoluciones de llamada anidadas complejas
  3. proporciona seguridad en torno a algunos de los problemas de idioma difíciles de rastrear de JavaScript

El ejemplo de trabajo anterior de Andrew que encontré es esclarecedor. Creo que la legibilidad de sus retornos literales de objetos existentes se mejoraría simplemente identificando manualmente el retorno

regreso

// objeto literal aquí

Las herramientas IDE se han mejorado, TextMate y Cloud9 son compatibles con CoffeeScript. Es cierto que el soporte de Windows se ha retrasado (¿no es cierto para el desarrollo web en general?

contras

El navegador interpretado por CoffeeScript puede ser difícil de depurar.

Es una capa adicional sobre JavaScript que requiere cierta comprensión y consideración por parte de los desarrolladores.

usuario38265
fuente
0

pros

  1. realmente optimizaron los casos comunes sintácticamente, de hecho, CoffeeScript es uno de, si no el lenguaje más conciso que se usa "comúnmente" http://redmonk.com/dberkholz/2013/03/25/programming-languages-ranked- por expresividad /
  2. oculta las partes malas de JavaScript (auto-coercion ==, globales implícitos, un sistema de clases más tradicional facilita las cosas comunes)
  3. extremadamente fácil de aprender para programadores de Python / Ruby
  4. funciones anónimas de varias líneas + sintaxis de espacios en blanco

contras

  1. la eliminación de var significa que no puede cambiar una variable de alcance externo dentro de un alcance interno sin usar un objeto, o `var fall_back_to_js;` piratea [por qué no otra declaración de asignación ': =' que solo reasigna un valor así que obj.naem: = 5 errores tipográficos más fáciles de depurar]
  2. debe informar a todas las herramientas al respecto, a menos que desee depurar JavaScript :(; por cierto: puede depurar CoffeeScript desde Chrome agregando soporte para mapas fuente; yeoman (npm install yeoman) puede ayudarlo a escribir un archivo de configuración Gulp o Grunt para CoffeeScript
  3. sin escritura estática opcional (hay que esperar al próximo estándar EcmaScript)
  4. todavía necesita bibliotecas de terceros para un sistema de módulos
  5. trampas de sintaxis a tener en cuenta: retornos implícitos, abgo significa a (b (g (o))) , fp, b: 2, c: 8 significa f (p, {b: 2, c: 8}) en lugar de f (p, {b: 2}, {c: 8})
  6. no cambia el sistema de tipo / número de JavaScript roto
aoeu256
fuente