Al explicar la diferencia entre la rigurosidad de los lenguajes y los paradigmas a un colega mío, terminé afirmando que:
Los lenguajes tolerantes, como los lenguajes dinámicos e interpretados, se utilizan mejor para prototipos y proyectos pequeños o aplicaciones web de tamaño mediano. Al elegir lenguajes dinámicos elegantes como Python o JavaScript con Node.js, los beneficios son:
Desarrollo rápido,
Código reducido repetitivo,
Capacidad para atraer a programadores jóvenes y creativos que huyen de "lenguajes corporativos" como Java.
Los idiomas compilados / tipados estáticamente son los mejores para aplicaciones que requieren una mayor rigurosidad, como aplicaciones críticas para el negocio o aplicaciones para aplicaciones de tamaño mediano a grande.
Paradigmas y patrones conocidos desarrollados durante décadas,
Facilidad de comprobación estática,
Capacidad para encontrar muchos desarrolladores profesionales con décadas de experiencia.
Lenguajes estrictos como Haskell, Ada o técnicas como los contratos de Código en C # son mejores para los sistemas que favorecen la seguridad sobre la flexibilidad (incluso si Haskell puede ser extremadamente flexible), como los sistemas críticos y los sistemas que se espera que sean extremadamente estables. Los beneficios son:
Capacidad para atrapar tantos errores como sea posible en tiempo de compilación,
Facilidad de comprobación estática,
Facilidad de pruebas formales.
Sin embargo, al observar los lenguajes y tecnologías utilizados para proyectos a gran escala por grandes corporaciones, parece que mi afirmación es incorrecta . Por ejemplo, Python se utiliza con éxito para sistemas grandes como YouTube u otras aplicaciones de Google que requieren una cantidad importante de rigor.
¿Existe todavía una correlación entre la escala del proyecto y la rigurosidad del lenguaje / paradigma que debe usarse?
¿Hay un tercer factor que he olvidado tener en cuenta?
Donde me equivoco
fuente
Respuestas:
Un estudio de caso interesante sobre los asuntos de proyectos de escala que usan lenguaje dinámico e interpretado se puede encontrar en Beginning Scala por David Pollak.
Como puede ver, los principales desafíos en el escalado de proyectos para el autor resultaron en el desarrollo de pruebas y la transferencia de conocimiento.
En particular, el autor entra en más detalles al explicar las diferencias en la escritura de pruebas entre los idiomas escritos dinámicamente y estáticamente en el Capítulo 7. En la sección "Conejos conmovedores conmovedores: escaleras de Dwemthy", el autor analiza el puerto de Scala de un ejemplo particular de Ruby:
Leer más arriba puede hacernos pensar que a medida que los proyectos crecen aún más, la redacción de pruebas puede volverse prohibitivamente engorrosa. Este razonamiento sería incorrecto, como lo demuestran los ejemplos de proyectos muy grandes exitosos mencionados en esta misma pregunta ("Python se usa con éxito para ... YouTube").
La cuestión es que la ampliación de los proyectos no es realmente sencilla. Los proyectos muy grandes y de larga duración pueden "permitirse" diferentes procesos de desarrollo de pruebas, con conjuntos de pruebas de calidad de producción, equipos de desarrollo de pruebas profesionales y otras cosas pesadas.
Las suites de prueba de Youtube o el Kit de compatibilidad de Java seguramente viven una vida diferente a las pruebas en un pequeño proyecto tutorial como Dwemthy's Array .
fuente
Tu afirmación no está mal. Solo necesitas cavar un poco más profundo.
En pocas palabras, los grandes sistemas usan múltiples idiomas, no solo un idioma. Puede haber partes que se crean con lenguajes "estrictos", y puede haber partes que se crean con lenguajes dinámicos.
En cuanto a su ejemplo de Google y YouTube, escuché que usan Python principalmente como "pegamento" entre varios sistemas. Solo Google sabe con qué están construidos esos sistemas, pero apuesto a que muchos de los sistemas críticos de Google están construidos usando lenguajes estrictos y "corporativos" como C ++ o Java, o tal vez algo que ellos mismos crearon como Go.
No es que no pueda usar lenguajes tolerantes para sistemas a gran escala. Muchas personas dicen que Facebook usa PHP, pero se olvidan de mencionar que Facebook tuvo que crear pautas de programación extremadamente estrictas para usarlo eficientemente a esta escala.
Entonces sí, se requiere cierto nivel de rigor para proyectos a gran escala. Esto puede provenir de la rigurosidad del lenguaje o el marco, o de pautas de programación y convenciones de código. No puede simplemente tomar algunos graduados universitarios, darles Python / Ruby / JavaScript y esperar que escriban software que se adapte a millones de usuarios.
fuente
Hay dos tipos de errores para verificar: errores de tipo (concatenar un entero + lista de flotantes) y errores de lógica de negocios (transferir dinero a una cuenta bancaria, verificar si la cuenta de origen tiene dinero).
La parte "dinámica" de un lenguaje de programación dinámico es el lugar donde tiene lugar la verificación de tipo. En un lenguaje de programación "tipado dinámicamente", la verificación de tipo se realiza mientras se ejecuta cada instrucción, mientras que en un lenguaje de "lenguaje tipado estáticamente" se realiza en el momento de la compilación. Y puede escribir un intérprete para un lenguaje de programación estático (como lo hace emscriptem ), y también puede escribir un compilador estático para un lenguaje de programación dinámico (como lo hace gcc-python o shed-skin ).
En un lenguaje de programación dinámico como Python y Javascript, debe escribir pruebas unitarias no solo para la lógica empresarial del programa, sino también para verificar si su programa no tiene errores de tipo o sintaxis. Por ejemplo, si agrega "+" un número entero a una lista de flotantes (que no tiene sentido y emitirá un error), en un lenguaje dinámico, el error se generará en tiempo de ejecución al intentar ejecutar la instrucción. En un lenguaje de programación estático como C ++, Haskell y Java, el compilador detectará este tipo de error de tipo.
Una base de código pequeña en un lenguaje de programación verificado dinámicamente es más fácil de buscar errores de tipo porque es más fácil tener una cobertura del 100% del código fuente. Eso es todo, ejecutas el código a mano varias veces con diferentes valores y listo. Tener una cobertura del 100% del código fuente le da una pista clara de que su programa puede no tener errores de tipo .
Con una gran base de código en un lenguaje de programación comprobado dinámicamente, es más difícil probar cada declaración con cada combinación de tipos posible, especialmente si es descuidado y escribe una función que puede devolver una cadena, una lista o un objeto personalizado dependiendo de sus argumentos.
En un lenguaje de programación comprobado estáticamente, el compilador detectará la mayoría de los errores de tipo en tiempo de compilación. Lo digo más porque un error de división por cero, o un error de matriz fuera de límites también son errores de tipo.
La mayoría de las veces, la verdadera discusión no se trata de lenguajes de programación sino de las personas que usan esos lenguajes. Y esto es cierto porque, por ejemplo, el lenguaje ensamblador es tan poderoso como cualquier otro lenguaje de programación, sin embargo, estamos escribiendo código en JavaScript. ¿Por qué? Porque somos humanos. Primero, todos cometemos errores y es más fácil y menos propenso a usar una herramienta dedicada especializada para una tarea específica. En segundo lugar, hay una restricción de recursos. Nuestro tiempo es limitado, y escribir páginas web en el ensamblaje llevaría años terminar.
fuente
Mi experiencia con los sistemas grandes es que se mantienen o caen no por elección de idioma, sino por cuestiones de diseño / arquitectura o cobertura de prueba . Prefiero tener un talentoso equipo de Python en mi gran proyecto empresarial, que uno mediocre de Java.
Habiendo dicho eso, cualquier lenguaje que le permita escribir significativamente menos código , debe valer la pena mirarlo (por ejemplo, Python vs Java). Quizás el futuro esté en lenguajes inteligentes, de tipo estático, con inferencia de tipos avanzada (por ejemplo, en el molde Scala). ¿O híbrido, como C # está intentando con su
dynamic
calificador ...?Y no olvidemos el "otro" beneficio de tipeo estático: completar el código IDE / intellisense correctamente, que en mi opinión es una característica esencial, no agradable de tener.
fuente
Otra consideración es quién detrás de escribir aplicaciones a gran escala. He trabajado en muchos lugares que desean usar Ruby o Python en algunos proyectos grandes de estilo empresarial, pero son constantemente "derribados" por los gerentes de TI y los equipos de seguridad corporativa precisamente por la naturaleza de código abierto de los proyectos.
Me han dicho: "No podemos usar Ruby on Rails porque es de código abierto y alguien podría poner piratas informáticos que roban información crítica o protegida". Lo siento, pero una vez que alguien tiene esa mentalidad de código abierto == mal, es casi imposible cambiarlo. Esa línea de pensamiento es una enfermedad corporativa.
C # y Java son de confianza idiomas con confianza plataformas. Ruby y Python no son lenguajes confiables.
fuente