La lucha duradera de la escritura est√°tica frente a la din√°mica: TypeScript no ayudar√°



Cuando mi amigo y yo est√°bamos en edad escolar y aspiramos a convertirnos en desarrolladores de software, so√Īamos con dise√Īar algunas cosas interesantes juntas, como un juego o una aplicaci√≥n mega √ļtil.

Elegí aprender C ++ y C #, eligió JavaScript. Terminamos la escuela, nos graduamos de nuestras universidades, servimos en el ejército y comenzamos nuestros trabajos. Tuvimos un tiempo bastante ocupado en ingeniería de software industrial, con muchos trabajos y puestos diferentes, y después de que todo comenzó a desgastarnos, recordamos dónde había comenzado todo.

Despu√©s de reunirnos finalmente como desarrolladores maduros, decidimos trabajar en nuestro propio proyecto: un videojuego en 2D. Como el dominio de mi amigo era front-end y yo era un desarrollador completo, nuestra elecci√≥n inmediata de plataforma de desarrollo fue un navegador de Internet. Como solo estaba acostumbrado a trabajar con TypeScript cuando dise√Īaba front-end, pensamos, ok, no hay problema, despu√©s de todo, TS es solo JavaScript a escala. Us√©moslo y las cosas saldr√°n bien. ¬°Si supiera lo equivocado que estaba! Cuando comenzamos a discutir el proyecto, nos encontramos con un gran abismo de malentendidos entre nosotros.

Aquí estaba mi visión del juego. Estaba como, ok, tenemos tipos como juego, herramienta, elemento, mapa, ubicación. Tengo una comprensión básica de cómo funcionan juntos, así que los describo, compilo el proyecto y funciona. Después de todo, el compilador ha verificado mi código, y lo hice bien. Luego, comienzo a escribir código que usa esos tipos. Me hacen la vida mucho más fácil. Mi IDE me da información sobre herramientas y comprueba cualquier error. Si se puede compilar un proyecto, probablemente funcione. Pasé algo de esfuerzo en la descripción del tipo y arrojó resultados. Ese es mi enfoque en pocas palabras.

Mi amigo tuvo la idea opuesta: saltar a la escritura de códigos de inmediato sin tomarse el tiempo para describir los tipos. No estaba listo para definir el problema como una familia de tipos. No estaba interesado en usarlo como base, ya que no veía el problema como un conjunto de clases, tipos, registros de nada por el estilo. Pensé que era inconcebible. Ambos teníamos un punto, es solo que nuestros puntos eran mutuamente excluyentes.

En serio, estuvimos hablando durante horas, pero cada uno dec√≠a lo suyo, como si estuvi√©ramos hablando idiomas diferentes. Eso s√≠, no podr√≠a culparnos de que estemos atrapados en nuestras viejas costumbres. Hace apenas un a√Īo, migr√© sin problemas del mundo de la programaci√≥n orientada a objetos al mundo de la programaci√≥n funcional y viceversa. Adem√°s, pas√© bastante tiempo aprendiendo JS, y √©l, aprendiendo varios idiomas est√°ticamente escritos.

Sin embargo, para cualquier desarrollador, la tecnolog√≠a que usaron para su primer trabajo real a menudo los define en la medida en que dos adultos experimentados simplemente carecen de la paciencia para escucharse mutuamente. Durante estos a√Īos de ingenier√≠a de software, nuestras visiones se formaron de maneras tan diferentes que nuestros enfoques para la resoluci√≥n de problemas simplemente no encajaban bien.

Al final abandonamos la idea de trabajar en equipo. Su primera respuesta podría ser que el problema estaba en nuestras personalidades. Puede que tengas razón, pero también vi que esto le sucedía a otros en la industria.

La diferencia fundamental e irreconciliable entre tipeo est√°tico y din√°mico


Mi código proporciona la solución al problema de cómo trabajar con él, mientras que el código de defensores de la escritura dinámica experimentada resuelve el problema de cómo funciona. Ambas mentalidades son legítimas y están respaldadas por las herramientas existentes, pero solo una puede tener la máxima prioridad en cualquier momento.

La escritura est√°tica es buena para proyectos a gran escala que involucran a cientos de desarrolladores que trabajan en ellos durante a√Īos, mientras que la escritura din√°mica es buena para equipos y proyectos m√°s peque√Īos que a menudo requieren c√≥digo de solo escritura. La escritura din√°mica le permite ahorrar tiempo y esfuerzos al comienzo del desarrollo, mientras que la escritura est√°tica le da un impulso al final.

La idea de poner los tipos primero ha afectado seriamente mi pensamiento como desarrollador. Después de haber elegido C # al comienzo de mi carrera, tengo una escritura estática codificada en mi mentalidad, y ahora estoy pagando el precio de esta inflexibilidad. Una vez que veo una tarea, trato de imaginar su solución como un conjunto de tipos y reglas de su relación. Cuando estoy desarrollando un módulo, mi primer paso es definir los tipos que opera y usa para interactuar con su entorno. Simplemente no recuerdo cómo solía resolver problemas antes de eso.

Todo el proceso de aprender a programar en Java se trata de aprender a dise√Īar y usar tipos. .NET CLR, el tiempo de ejecuci√≥n de C #, se basa en tipos y para tipos. La escritura est√°tica se encuentra en el n√ļcleo del paradigma de programaci√≥n orientada a objetos (hola, clases JS, decid√≠ darle un descanso). Las implementaciones can√≥nicas de la mayor√≠a de los patrones OOP est√°n saturadas con la palabra clave Interface, lo que no tiene ning√ļn sentido en un lenguaje de tipo din√°mico.

Los patrones de dise√Īo en s√≠ mismos son conceptos de lenguaje cruzado, pero ¬Ņalguien puede decirme por qu√© demonios necesitar√≠a el patr√≥n de estado en un lenguaje de tipo din√°mico? ¬ŅQu√© hay de Builder? Estos patrones no tienen nada que ver con el desarrollo, son principalmente sobre tipos. Los tipos y OOP tienen un v√≠nculo estrecho.

No puede construir su lógica de negocios en los tipos y, sin embargo, no sabe nada sobre ellos cuando comienza a escribir código. Es por eso que tenemos desarrolladores front-end que arman su código con una increíble cantidad de pruebas unitarias que verifican específicamente la base del código para detectar cualquier tipo de error.
Todos sabemos que la protección basada en la cobertura del código es una ilusión. Las pruebas se escriben manualmente y, por definición, son menos confiables que el sistema incorporado de verificación de tipos disponible en el idioma.

No significa que los idiomas escritos dinámicamente no tengan sentido (aunque confieso que creo que no). Significa que, al usarlos, debe alejarse de OOP como paradigma dominante. Toda esta unidad de datos y operaciones basadas en datos es para personas que tienen mecanografía estática.

Los desarrolladores con los que me he encontrado no creen que el tipeo estático afecte la forma de codificación en ninguna medida, por lo que simplemente escriben su código como si estuvieran usando un lenguaje dinámico, solo que agregan la verificación de tipo. Creo que esto es inherentemente incorrecto. Es especialmente obvio en el caso del front-end moderno.
Lo s√©, lo s√©, hay un tab√ļ para criticar a los desarrolladores front-end. Mi amigo y yo una vez armamos un robot de inteligencia artificial que controlaba a los usuarios de Twitter, y conseguimos que Brendan Eich lo atacara. En serio, el creador de JavaScript tuvo un intercambio de comentarios con nuestra red neuronal.



Por alguna razón, estos tipos simplemente no están listos para vivir en un mundo donde su visión tiene deficiencias tangibles. Es por eso que critico solo a aquellos de ellos que manipulan mi proyecto definitivamente tipado para reelaborarlo de una manera relajada, "De cualquier manera".

Seguir√≠amos viviendo en nuestros peque√Īos mundos, pero TypeScript nos uni√≥


T√≥meme por ejemplo: debido a las restricciones de tipo, mi c√≥digo es imposible de usar incorrectamente. Cuando estoy trabajando en un proyecto, conf√≠o en que otros tambi√©n usen tipos. Entonces mi c√≥digo funcionar√° tal como est√° dise√Īado. Por lo tanto, deliberadamente no cubro todos los casos en los que este c√≥digo se puede usar incorrectamente (porque escribir lo hace imposible). Pero luego un desarrollador de JS se une a mi proyecto, toma mi tipo, lo envuelve en Any y comienza a usarlo incorrectamente, lo que resulta en errores dif√≠ciles de replicar.

Los desarrolladores de JavaScript conf√≠an en que TypeScript es el mismo JS anterior, pero con una opci√≥n para agregar verificaciones de tipo est√°tico en caso de que las necesiten. Esto esta mal. TypeScript es cien veces m√°s poderoso, pero solo est√°n interesados ‚Äč‚Äčen una fracci√≥n de su potencial.

Su argumento asesino es que TypeScript es solo un superconjunto de JS. En la práctica, uno no puede ignorar el hecho de que TypeScript es un lenguaje independiente, incluso si uno es un maldito rey del front-end. Porque requiere un enfoque diferente: el de verificación estática, no dinámica.

El principal beneficio del tipeo est√°tico es que le brinda garant√≠as. Si lo usa en un m√≥dulo y elige no usarlo en otro, entonces solo pierde su tiempo y energ√≠a en describir y dise√Īar esos tipos, sin obtener ninguna garant√≠a.

Muchos piensan que TypeScript es un compromiso de los sistemas de tipos entre JS y Java. Bueno, no es un compromiso de ning√ļn tipo, tiene un sistema de tipo especial propio.

Lo peor de todo es que hoy en d√≠a uno de cada dos puestos frontales requiere dominio de TypeScript. Esto estimula a los desarrolladores de JS a echar un vistazo a las caracter√≠sticas de TypeScript e inmediatamente saltar a escribir c√≥digo en √©l, generando una proliferaci√≥n de pr√°cticas da√Īinas. Las situaciones ocurren cuando realmente no necesitan una verificaci√≥n de tipo est√°tico, pero se les impuso un poco, por lo que se metieron con eso. Necesitamos finalmente reconocer que los enfoques de programaci√≥n con tipeo est√°tico vs din√°mico est√°n en conflicto entre s√≠ y no se pueden mezclar.

Veo JavaScript como una gran herramienta para escribir código de pirateo rápido que proporciona soluciones sin resolver abstracciones innecesarias. El ejemplo más escandaloso aquí es el patrón Ice Factory. Puede alimentar sus instancias y las envolverá en la inmutabilidad de tiempo de ejecución. Si proceso mi objeto a través de dicha fábrica, devolverá su equivalente, pero si trato de cambiar una de sus propiedades, arrojará una excepción. WAT?!?

El patr√≥n surgi√≥ porque los desarrolladores front-end escucharon en alg√ļn lugar sobre la inmutabilidad genial, por lo que decidieron arrastrar esta mierda a su idioma, que lo necesita como un agujero en la cabeza. En TypeScript, puedo dise√Īar una f√°brica similar, pero con una restricci√≥n en el tiempo de compilaci√≥n de mutaciones y sin ninguna excepci√≥n.

Por otro lado, apenas necesito esto porque existe la programación funcional pura. Tomemos F #, Haskell, OCaml, Clojure, ReasonML, por ejemplo: tienen una prohibición de mutabilidad lista para usar. Pero algo me dice que si un desarrollador front-end pone sus manos en un lenguaje funcional, estará dispuesto a actualizarlo para que su comportamiento sea similar al de JavaScript.

Eso es porque elegir tu religión de mecanografía es un boleto de ida. Todas las soluciones intermedias proporcionan una ilusión de compromiso. O confías en los tipos o no. No sé si mi vida sería diferente si hubiera comenzado a aprender C # y JavaScript en paralelo. Hoy estoy tan desesperadamente identificándome con mi mentalidad que simplemente no veo ninguna ventaja de la escritura dinámica (y no deseo verlas). Existen, solo fuera de mi rango de visibilidad, por lo que todo lo que puedo hacer es cerrar los ojos ante ellos como lo hago ante cualquier fenómeno que tenga que soportar en este mundo. Sé que estoy equivocado, pero tengo que trabajar aquí y ahora, y no tengo el presupuesto para seguir sentado en la cerca.

Así que no quiero buscar compromisos, en su lugar lo aclararé. Si solo está dando sus primeros pasos en el desarrollo, ¡comience con la escritura estática!

Source: https://habr.com/ru/post/437844/


All Articles