Este post no es para tratar de convenceros de que os unais a las legiones de Javascript, sino para explicar mis razones para tomar ese camino de perdición. Antes que en javascript programé en tres o cuatro lenguajes, principalmente C y Java. Por supuesto en la universidad aprendí LISP, PROLOG, ADA, varios dialectos de ensamblador y alguna cosa más, pero como nos lo he vuelto a tocar desde entonces no los considero parte de mi «toolkit».
Yo empecé en esto de Javascript como la mayoría de vosotros, haciendo unos scripts güarrotes para validaciones y efectillos, en los tiempos del año 2000. Era un mal necesario con el que tenía que convivir al desarrollar mis preciosas aplicaciones thin-client en Java. Sin embargo sobre 2005, empecé a querer usar servicios REST sin sesión por temas de rendimiento, lo que me hizo repensar la arquitectura de mis sistemas. Fue entonces cuando descubrí AJAX, y me quede fascinado por las posibilidades. Desde entonces fue un camino sin retorno; cada vez que aprendía más, descubría nuevas tecnologías, y reflexionaba más sobre como diseñar mejor mis aplicaciones, más enganchado me quedaba con Javascript, y desde entonces hasta ahora.
Así que, ¿por qué Javascript?
Es ubíquo
Que yo sepa, es el lenguaje que en la actualidad está más extendido del mundo. Virtualmente en cada ordenador de cada casa se puede ejecutar una versión u otra de Javascript. ¿Qué ordenador no tiene un browser? ¿Al menos un IE6? Sí, algunas personas por motivos de accesibilidad o seguridad no lo tienen disponible, pero son una exigua minoría.
¿Y en servidor? Pues ya sabeis que tenéis el node.js, tenéis Rhino, etc. En concreto en node.js se está invirtiendo cantidades ingentes de dinero. Ya está soportado en algunas plataformas cloud, como Heroku/Cedar y Windows Azure.
¿Y en desktop? Pues desde hace tiempo existe la plataforma Mozilla, ¿en que creéis que se programa la mayor parte de Firefox y Thunderbird? En una mezcla de Javascript (y C para el bajo nivel). Además Windows 8 plantea usar a JavaScript como uno de los lenguajes de preferencia para hacer aplicaciones de escritorio (otorgándole el mismo rango que a C#).
El mismo lenguaje para cliente y servidor
A día de hoy Javascript es el único lenguaje en el que puedes desarrollar por completo una aplicación web de punta a punta, desde la UI hasta el acceso a BBDD. ¿Qué tiene esto de interesante?
- No necesitas dominar más de un lenguaje para hacer la aplicación web. Esto te permite no estar cambiando de contexto entre un lenguaje y otro, o simplemente no necesitar dos equipos de desarrollo especializado (uno de front-end y otro de server-side). Además de aumentar tu productividad, puede facilitar tener un equipo de proyecto más cohesionado.
- No necesitas recodificar la misma lógica tanto en Javascript como en el lenguaje que estés usando en tu server-side. ¿Modelos de negocio? ¿Validaciones? Todo eso es único y debería ser reutilizable tanto en tu front-end como en tu server-side. Si lo haces todo en Javascript, terminas teniendo un montón de código común en ambos lados, que antes tendrías que haber duplicado y mantenido en dos lenguajes diferentes. Eso sí, hay que diseñar tu arquitectura de la forma adecuada para que esto se pueda cumplir.
- Estándares de codificación y criterios de calidad unificados para todas las capas de tu sistema.
Tipado dinámico
Confieso que este punto es muy subjetivo. Ya sabeis que soy un fanático del TDD. Y si haces TDD como es debido, al final el compilador deja de ser tan valioso. Los errores de sintaxis o de tipos son muy sencillos de detectar y arreglar usando TDD, no necesitas un compilador para ello. En los lenguajes de tipado estático, el compilador detecta este tipo de errores, pero a cambio tienes que esperar a que éste se termine de ejecutar. Además normalmente tendrás que escribir más código, para añadir toda la información de tipado que el compilador necesita. Esto hace que el ciclo de TDD sea algo más lento que en un lenguaje de tipado dinámico. Ya que TDD me va a detectar esos errores de todas formas, no me resulta rentable el «trade-off» propuesto por el compilador.
Dicho esto, si no hacéis TDD, mucho cuidado con Javascript, puede ser un buen dolor de muelas de depurar, e incluso pequeños fallos de sintaxis te pueden llevar por el camino de la amargura. Para mi lo ideal del TDD es no tener que depurar, o si lo tengo que hacer, que sea sobre 4 o 5 líneas de código bien identificadas, y que están siendo ejercitadas por un test predecible. Desde este punto de vista Javascript no plantea ningún problema.
Paradigma mixto
Es un lenguaje que te permite hacer OO hasta de dos formas diferentes, con «extends» y sin «extends». Pero es que además también puedes hacer programación funcional con él. Esto te permite elegir el paradigma de programación que mejor se adapte al problema a resolver.
¿Tratamiento de colecciones? ¿Cálculos puros (validaciones, reglas de negocio)? ¿Programación asíncrona? Mejor el paradigma funcional
¿Modelado de negocio? ¿DDD? Mejor OO
Y por supuesto en una aplicación de verdad vas a tener que usar ambos paradigmas, y mezclarlos armoniosamente. Incluso a veces los puedes mezclar de tal forma que llegan a ser difícil de distinguir uno de otro.
Flexible
Es un lenguaje ideal para hacer DSLs internos, gracias a su gran flexibilidad. Puedes añadir y eliminar funciones al vuelo tanto en una instancia como un constructor. Esto no sólo te permite crear DSLs sino añadir nuevas capacidades al lenguaje, y realizar metaprogramación (aunque en Ruby y Groovy se puede llegar incluso más lejos).
Reconozco que esto puede ser una fuente de problemas, y es mejor evitar este tipo de funcionalidades. Por ello las últimas versiones de Javascript te permiten cerrar total o parcialmente un objeto, para evitar que se puede modificar en tiempo de ejecución. Sin embargo en algunos casos está justificado hacer este tipo de cosas. Aparte de los DSLs y quizás algunos ejemplos de metaprogración, el caso más importante es el de retrocompatibilidad. ¿Qué ocurre si estoy ejecutándome en una máquina virtual de Javascript que no soporta la API de colecciones de la última versión de Javascript? ¿Y si estoy en un navegador que no soporta alguna API de HTML5? ¡No hay problema! Con Javascript puedo detectar tal eventualidad y añadir la API que me falta de forma dinámica. Este tipo de capacidad ha permitido a Javascript sobrevivir en el infierno de incompatibilidades de los distintos browser por más de 10 años.
¿Y los WTF?
Sí, Javascript tiene algunos WTF. Sólo es cuestión de comprenderlos y saber que están ahí. Por ejemplo, los ámbitos de visibilidad no se señalan con ‘{‘ y ‘}’. En Javascript las llaves son prácticamente cosméticas y sólo sirven para agrupar el cuerpo de bucles y condicionales. Otra tema es el hoisting de variables, o el hecho de que en Javascript no existan los números enteros sino que sean todos en coma flotante. Personalmente el WTF que más me molesta es que Javascript tiende a ser «listillo». Esto significa que intenta no fallar nunca con excepción. De ahí el horroroso e infernal sistema de coerción de tipos o el abuso de null y NaN en mucha de las librerías del lenguaje. En esto sí es verdad que se sufre.
Sin embargo los WTF de Javascript no son tantos ni tan difíciles de aprender como la gente piensa. La mala fama de Javascript viene por causas totalmente ajenas al lenguaje, los WTF de los navegadores. Tradicionalmente la implementación de los navegadores de los estándares de manipulación de HTML y de los servicios estandarizados por W3C ha sido defectuosa. Eso ha causado multitud de quebraderos de cabeza a los desarrolladores. Realmente, en la mayor parte de los casos, cuando un desarrollador piensa en las heridas recibidas en acto de servicio por parte de Javascript, normalmente debería achacarle la culpa al navegador. Desgraciadamente hasta hace poco navegador y lenguaje han estado mezclados en las mentes de los desarrolladores.
El pero
No todo es bonito en el lenguaje. Hay varios problemas con Javascript. El primero, y más importante, son los WTF arriba mencionados. El segundo es la sintaxis tan fea que tiene. La verdad de que con esto de querer simular ser C o Java la pifiaron bien. Espero que en siguientes versiones del lenguaje arreglen todo esto. Si no de momento podemos usar «strict mode»; para desactivar la mayor parte de los WTF, o usar CoffeeScript. El caso de CoffeeScript es curioso, si sabes Javascript entonces CoffeeScript te parece un simple dialecto de Javascript. Si no conoces Javascript, te parecerá un lenguaje totalmente diferente. El caso es que CoffeeScript soluciona la mayor parte de los WTF de Javascript, y tiene una sintaxis mucho más elegante. Lo tengo en el punto de mira a ver como se desarrolla.
Estos son los problemas que reconozco con el lenguaje. Después hay problemas humanos. Ese programador de Java que intenta programar en Javascript como si fuera un hermano retardado de Java (me incluyo en los culpables). Claro, intentas que una manzana se parezca a un plátano, y después vas echando pestes de lo feas que son las manzanas. No critiquemos el lenguaje sólo porque tengamos un conocimiento superficial de este, y al intentar programar como lo hacemos en nuestro lenguaje server-side, las cosas no nos salgan bien. ¡Es como si yo ahora digo que Clojure es una mierda porque no me termino de acostumbrar a su sintaxis y no puedo hacer una asignación de variable de forma sencilla! (no sería mal post 😀 )
También hay que reconocer que no es un lenguaje sencillo de aprender. Primero tienes que aprender los WTF, para desarrollar instintivamente buenas prácticas que los eviten. Después tienes que ser capaz de dominar dos paradigmas de programación distintos, OO y funcional. Sólo así conseguirás sacarle toda la potencia a Javascript.
Conclusión
Desde mi punto de vista a día de hoy Javascript es el lenguaje más adecuado para desarrollar aplicaciones web. El problema es que no tiene competencia, ¿qué otro lenguaje tiene unas características similares a las anteriormente mencionadas? Yo no conozco ninguno. Ciertamente Ruby es bastante elegante, y me gusta bastante, ¡ pero sólo se ejecuta en servidor ! Java no está envejeciendo nada bien, y aunque C# es más avanzado está mucho menos extendido y tampoco se ejecute en servidor. Lo mismo puede decirse de Clojure, Scala o Groovy. Sí, podemos hacer como GWT o ClojureScript y compilar estos lenguajes en Javascript, pero, ¿con qué fin? La experiencia GWT ha resultado fallida.
En cualquier caso, a día de hoy, programes en el lenguaje que programes, si quieres hacer aplicaciones web modernas, te toparás con Javascript. Así que es mejor aprenderlo y dominarlo.
Tal vez en el futuro salga un nuevo lenguaje, con más ventajas que Javascript para hacer aplicaciones web. En ese momento tiraré Javascript a la basura y me pondré con el nuevo lenguaje, pero me temo que aun quedan 10 años para eso.
¡Espero que os hayan sentado bien las torrijas de Semana Santa!
Enrique, a qué te refieres con «La experiencia GWT ha resultado fallida.» ¿Tu experiencia personal o general de la gente?
Yo llevo más de dos años trabajando con GWT y no tengo la percepción de que sea una herramienta fallida. Otra cosa es que, como tu dices, Java no ha envejecido bien, pero para los javeros de pro resuelve perfectamente el tener un mismo lenguaje en la capa cliente y servidor, y reutilizar el códgo en lo dos lados.
Realmente no ha sido por experiencia personal, yo GWT no lo he usado nunca a nivel profesional. Varios compañeros javeros que han usado GWT en varios proyectos me comentaron que había sido un infierno. Para serte sincero me comentaron que era un dolor al hacer «diseño web fino» y hacía el ciclo de desarrollo más lento. ¡Pero yo no lo he usado en un proyecto real!
Mi opinión personal sobre el tema se resume en este post de William Shields. En mi opinión veo más razonable programar en Javascript la lógica que va en un browser, que hacerlo en otro lenguaje y compilarlo a javascript, con lo que añado una capa de abstracción innecesaria. Usar GWT, o un enfoque similar, es como decir «javascript es igual de bajo nivel y tan inmantenible como assembler y necesito un compilador por medio».
Buenas tocayo!
Muy buena reflexión…
Para la charla del miércoles estoy preparando unas estadísticas y unas tablas de los diferentes motores y versiones en navegadores para renderizar javascript… fortalece tu opinión del segundo párrafo.. 🙂
Es el futuro más inmediato. Ahora estamos viendo, probando y explotando todas las nuevas API´s de Javascript que se van implementado en los navegadores; son el pilar de las nuevas tecnologías de desarrollo web que se aglutinan bajo el emblema de HTML5, o no? Por lo menos yo lo veo así.
Yo no podré ir, pero me interesa el tema, ¿vais a colgar algo?
Publicaré la presentación para que la peña pueda tener acceso a todos los recursos, repositorios, demos… ;))
Veo, veo… miles y miles y miles de proyectos grandes web más o menos con filosofía desktop, con decenas de miles de líneas de código JavaScript cuyo coste de desarrollo a partir de la línea 1000 se disparará exponencialmente y el coste de mantenimiento y correción de bugs llegará a niveles extratosféricos.
Es entonces en donde la industria mirará de nuevo atrás (casi nunca lo hace por eso existe esa tendencia absurda a reinventar la rueda como es el caso de node.js que va por los años 90 con el multithread pre-emotive) y entonces pensará:
«qué narices estamos haciendo en un mundo en el que las redes son tremendamente rápidas para transportar un poco de HTML, en el que los costes de proceso de nuestros servidores son ridículamente baratos respecto al valor que ofrecen nuestros servicios»
Es entonces en donde probablemente se vuelva la vista de nuevo al servidor y se planteen alternativas más saludables:
1) La programación híbrida cliente/servidor:
Renderización parcial de trozos de página en el servidor y aplicación de dichos cambios con un simple innerHTML (con diferentes niveles de granularidad según el impacto del cambio).
Coste de proceso del HTML + transporte de dicho HTML => ridículo respecto al verdadero coste que son las operaciones persistentes.
Libertad de diseño: total.
Movimientos, cambios de visibilidad instántaneos o con animaciones… con JavaScript claro.
Lo practicamos en mi empresa con resultados espectaculares respecto a lo que sería hacer lo mismo con JavaScript puro.
2) Google GWT
3) Google Closure
No es que me entusiasme pero es un aceptable equilibrio.
https://developers.google.com/closure/templates/
Respecto a un mundo puramente JavaScript que Google Dart nos coja confesados 🙂
Es increible que las mejores ideas del mundo web las tenga Google, esta gente es la caña 🙂
Y no, antes de que alguien me diga que es que no conozco JavaScript… JavaScript es un muy viejo «amigo» (http://xpdom.sourceforge.net ) desde tiempos del Navigator 4.5
A mi personalmente me gustaría oir opiniones de programadores que hayan hecho más de 1000 líneas de JavaScript, es que en este tema tengo la sensación de que hay mucho entusiasmado con su primer animate() con jQuery pero que no ha pasado mucho más de ahí.
Joer le estoy cogiendo el gusto a ésto de llevarte la contraria 🙂
Ja, ja, ¡ya estabas tardando mucho en comentar! Bueno, yo mismo he hecho proyectos grandes en JS, de decenas de miles de líneas de código. Pero eso sí, el código que hice no era muy bueno, precisamente por desconocimiento y porque trataba de imitar a JAVA. De aquella aprendí bastante.
Sobre Dart ya veremos, aun está en un estado muy incipiente. De momento no me aporta nada, pero ya veremos.
Mi punto es que es igual de sencillo hacer software de calidad con Javascript que con Java. Igualmente es igual de sencillo hacerlo mal en ambos lenguajes. La única diferencia es saber ser un buen programador o no y conocer el lenguaje que usas o no. No me dirás que un programador que no conozca Java lo va a hacer bien con él. Aun recuerdo programadores de COBOL que esgrimían exactamente los mismos argumentos contra Java, que ahora oigo por parte de programadores Java contra Javascript.
Un punto omitido es el del hecho, generalmente aceptado, de que JavaScript es un lenguaje roto.
Todo modelado o diseño que se haga sobre este lenguaje deberá basarse en convenciones, ya que existen demasiadas maneras de reflejar una misma idea en JavaScript. Intentar ahondar en paradigmas que el lenguaje no soporta completamente tampoco ayuda.
Todos sabemos de proyectos JS realmente espectaculares, de miles de líneas -justificadas-, perfectamente organizadas. Pero ese trabajo debería haber ser sido el de un compilador: el número de apariciones de «this» da idea de la frágil naturaleza del lenguaje.
Por otra parte su expresividad no tiene apenas par, aún a costa de que a algunos no les haga gracia el tipado débil. Sobre todo destacaría como reutiliza elementos con los que muchos programadores ya están habituados, dándoles nuevos significados sin comprometer los anteriores. Esto para mí es arte.
if (some_number || some_object[«some_string»[3]])
Sobre Coffee: creo que lo último que necesita el mundo es otra sintaxis más. Es la hora de ClojureScript.
No entiendo porqué estás en contra de CoffeeScript y no de ClojureScript. Al fin y al cabo ambos son lenguajes que se compilan y generan Javascript. Quizás la semántica de CoffeeScript es casi idéntica a la de JavaScript y no es un salto de abstracción tan grande.
¿Javascript no es expresivo? ¿Sabes lo que piensan la inmensa mayoría de los programadores cuando se enfrentan a Clojure por primera vez? En cualquier caso no estaría mal un post con ejemplos de la misma lógica en distintos lenguajes. Sí, Javascript tiene WTF, como el nefasto sistema de conversión de tipos. Pero de ahí a que sea un leguaje roto…
El ejemplo de código que pones es horroroso, claramente no cumple las normas de legibilidad que debería respetar cualquier programador. Es culpa del programador, no del lenguaje. Seguro que si lo traduces a Clojure es igual de feo. ¿Serías tan amable de traducir literalmente ese trozo de código a Clojure? Y no me digas que en Clojure no se puede escribir, que sí se puede. En mi ignorancia imagino algo así como (if (or (not some_number nil) (….)) (…)) ) Yo no se Clojure, así que te dejo el ejercicio a ti.
Ya puestos, preferiría programar en HaskellScript, Haskell es muchísimo más elegante y expresivo que Clojure.
Qué tal Enrique.
Para empezar no he dicho que JavaScript no sea expresivo, más bien lo contrario, y que me gusta este aspecto hasta cierto punto. No lo he comparado con Clojure, ni he defendido una supuesta mayor elegancia de este último.
Clojure en particular no pone la concisión en un pedestal, aunque efectivamente a largo plazo la consiga mediante la eliminación de complejidades a nivel conceptual. De un lisp se espera un mayor poder por un lugar, y regularidad por otra parte.
Lisp se diferencia en poner el valor de las ideas sobre el de la sintaxis. Lenguajes viejos y nuevos como Ruby, Go, Rust, F#, Haskell o Erlang tienen todos grandes conceptos detrás, pero la cantidad de reglas a aprender hacen imposible versarse en todos. En este sentido Lisp tiene un enorme potencial unificador, que se está haciendo realidad gracias a Clojure.
Sí, tienes razón, la capacidad de un lenguaje para eliminar código redundante y complejidad es más importante que su sintaxis. Sin embargo el tema de la sintaxis es una barrera de entrada importante al lenguaje.
Si alguna vez ClojureScript se impone, pues no sería mala cosa, es un lenguaje relativamente potente con una sintaxis diferente, pero te terminas acostumbrando. Pero mi instinto me dice que eso no va a ocurrir, y que Javascript va a dominar por muchos años el tema de las aplicaciones web. Eso y desmitificar el lenguaje, explicando que no es tan horroroso como la gente piensa, y que se puede hacer código mantenible fácilmente con él, es lo que intento explicar en el post.
Javascript, C#, Dart, Ruby, Groovy y Fantom tienen una potencia similar a la hora de hacer código mantenible. Java queda un poquito por detrás ya que no soporta el paradigma funcional. Lo mismo digo de los lenguajes puramente funcionales, al no soportar directamente OO, en algunos tipos de problemas se quedan algo cortos.
El objetivo esencial de clojure (y clojurescript) ha sido ofrecer al programador la mayor potencia posible maximizando la simplicidad del lenguaje. Dejandole una relativa libertad aunque intentando conducirle por el buen camino
La sintaxis de lisp es la mas simple y homogenea posible en un lenguaje de programacion. Es lo mas parecido a no tener sintaxis. Eso tiene dos ventajas: hace la metaprogramacion estatica con macros mas *simple* y te limpia la mente de ruido sintactico, de reglas y excepciones. En el sentido de la elegancia como minimalismo y simplicidad no se puede ser mas elegante.
En cuanto a la expresividad, si la entendemos como «similar al lenguaje natura» no cuadra y esa es la barrera para muchos programadores que no quieren o no pueden salir de la zona de confort sintactica de c (y, ojo, hacen bien) Si entendemos expresividad como la eliminacion de cualquier elemento en el codigo que no exprese (o declare, de ahi lo de programacion declarativa) lo que estamos haciendo lisp y clojure tambien brillan.
Clojure soporta el paradigma oo o mas bien soporta todo lo que buscas en el paradigama oo sin la parte «mala»: polimorfismo, extensibilidad del codigo, representacion de conceptos de la logica de negocio. Echarle un ojo a los protocolos y los records (o los multimetodos).
Cual es la parte mala que clojure intentar evitar por defecto (aunque te deja si lo necesitas): la mutabilidad y la programacion concurrente de bajo nivel.
En cuanto a javascrip estoy mas o menos de acuerdo con tu defensa aunque otro de los putnos a favor es precisamente que es lo suficientemente flexible como para poder montar cosas como clojurescript o coffescript encima de el. No solo esos sino cientos de ellos mas. entre ellos hay uno que intentaplicar elementos de lenguajes como haskell u ocaml (tipado estatico estructural): Roy
Sinceramente, JS está bien para ciertas cosas pero no le veo futuro a NodeJS, y si lo tiene me dan ganas de temblar.
¡No tiembles! Simplemente ve aprendiendo Javascript en condiciones. Tienes que ser realista…
No soy un experto en JS pero ya he hecho bastantes cosas con él. En cada proyecto había un patrón de diseño distinto, una chapuza.
Eso sin contar que cada navegador lo interpreta como quiere.
JS es útil para ciertas cosas pero para otras creo que puede ser la ruina.
Bueno, la interpretación de JS por parte de los navegadores es bastante (pero no completamente) consistente. Nunca he tenido problemas en ese aspecto. El dolor viene cuando tratas de acceder al navegador, para por ejemplo manipular HTML. Pero eso no es culpa de JS.
En ambos casos existe la solución de usar una librería crossbrowser.
¿Qué pensarías si te digo que en cada proyecto Java donde he estado, no es que hubiera un patrón de diseño distinto, sino muchos patrones de diseño distintos? No lo veo un problema, y sí una oportunidad de aprender. Además usar patrones de diseño como pollos sin cabeza es la receta para el desastre. Los patrones hay que usarlos sólo cuando son pertinentes.
Buenas,
lo primero felicitarte por escribir este post y exponer tus ideas. Mis ‘two cents’ son los siguientes:
Por un lado pienso que esta corriente sobre Javascript que hay últimamente es buena. Cada vez que se plantean cosas en cualquier lenguaje siempre hay cierto grado de polinización con otros lenguajes.
En el caso de Javascript creo que, que se plantee un uniformidad entre cliente y servidor es algo cuanto menos interesante. Como bien comentas en el post que con un sólo lenguaje puedas llevar la parte cliente y servidora es algo a priori muy provechoso (que no sea necesario tener distinto grupos específicos de desarrollo para un proyecto por ejemplo).
También me gusta el hecho de poder aprovechar varios paradigmas de programación dentro del mismo lenguaje.
Ahora bien, hay cosas en las que no estoy tan de acuerdo. Para mí Javascript siendo un lenguaje muy potente, no es un lenguaje bien definido a nivel de su arquitectura. El tema de creación de objetos no me parece nada limpio, por no hablar de la encapsulación de los mismos (sí, se que se puede pero …).
Temas de TDD, bien me parece un gran avance, pero … . Alguien dijo que el TDD sustituirá a los compiladores. Desde el respeto, pensar que un TDD por muy bien hecho que esté va a resolver los problemas que se pudieran dar con tipos dinámicos y que no se dan en lenguajes fuertemente tipados con compiladores picados por gente con cabezas muy bien amuebladas, me parece bastante aventurado … . OJO, no estoy en contra de lenguajes con tipos dinámicos pero tampoco creo que sean la panacea.
@jmarranz: podías exponer en más detalle el tema de la programación hibrída servidor-cliente.
GWT me parece interesante, hay algún framework como Vaadin que lo complementa muy bien. Aun así no me termina de gustar mucho GWT, me parece que la parte cliente que te ofrece no es tan limpia como una ‘de toda la vida’.
Para finalizar, Javascript tiene cosas interesante y otras que no. En su estado actual no creo que sea un lenguaje definitivo (nada lo es) para la web, móvil, …
Ah, y de nuevo gracias por el artículo.
Uff, espero no enrollarme mucho (el tiempo no me sobra).
Para empezar yo no creo en los lenguajes no tipados para más allá de un 10% de cualquier aplicación, casi siempre se exponen razones de detección inmediata de errores, y es cierto, pero a mi me interesa más la enorme capacidad de gestión que ofrecen, a mi si me quitas el Find Usages de NetBeans y el References y la navegación de tipos y herencias en general de Eclipse la verdad es que me quitas el 70% de mi interés por los lenguajes tipados, estas herramientas, que son realmente bases de datos de código, no son nuevas, son tan antiguas como los lenguajes, yo las descubrí con el Visual C++ v1 (mira que ha llovido) y no puedo vivir sin ellas. Es posible refactorizar profundamente una aplicación Java sin un puñetero test… lo mismo en un lenguaje no tipado me costaría infinitamente más.
Los lenguajes no tipados son para equipos muy pequeños y gente macho-man tipo Alberto Vilches http://albertovilches.com 🙂
No es teoría, mis experiencias con JavaScript son duras, no hablo de un par de simpáticas llamadas con jQuery, hablo de miles de líneas de código utilizando todas las técnicas posibles que conozco: OOP, aspectos/mixins (o como se quiera llamar), bindings bajo demanda etc, salvo los prototipos que quizás sea por ignorancia nunca pude usarlos como a mi me interesaban. Siempre al final tenía la sensación de que el lenguaje no me ayudaba nada, era todo muy artificial, artesanal, todo ello unido a la ausencia de tipos en un entorno limitado y anémico (el navegador).
Por ejemplo las tripas de ItsNat tienen una complejidad brutal por la cantidad enorme de pequeños y grandes problemas de algunos navegadores, sobre todo móviles, que cometí el error de soportar (algunos eran una verdadera basura) y por la ambición de algunas funcionalidades de ItsNat. Esa complejidad era asumible con cierta elegancia en Java, pero la parte de JavaScript pese a ser más sencilla era un dolor, unido a que el código a enviar debía de ser razonablemente pequeño. El experimento de XPDOM fue también muy duro, siempre tengo recuerdos grises del mundo JavaScript, quizás porque cambias de perspectiva cuando pasas del umbral del «anda que curioso».
Cuando reflexiono sobre el tema me suelo preguntar ¿y si esto lo hubiera hecho cliente-céntrico a base de JavaScript? http://www.innowhere.com:8080/insites/ y es cuando revisas mentalmente cosas que has hecho y dices «ni de coña»
Y si a esto le añades la fuerte tendencia que ha existido en el mundo cliente a mezclar a lo bestia funcionalidad con visualización y la herencia envenenada que supone para alguien que no sea el autor de dicho código.
Los tiempos ahora son mejores, los navegadores son mucho mejores y hay herramientas JS más avanzadas (que si procesadores de plantillas, que si MVC, que si componentes avanzados) y GWT para el que quiera un enfoque céntrico en el cliente con Java.
Respecto a la programación híbrida.
Parto del extremo de todo en Java y HTML puro en servidor: ItsNat. En ItsNat es posible convertir cualquier web paginada a una web single page interface con relativa facilidad. Vale, ItsNat no es popular y su enfoque intensivo en el uso de la sesión puede no ser aceptable para muchos que sufren el síndrome Google (tenemos que servir a millones de usuarios) cuando realmente sus sistemas suelen estar aburridos e infrautilizados sirviendo a una decena de usuarios.
El otro extremo: todo JavaScript y servidor sólo sirviendo datos.
El punto medio es la programación híbrida: cambios parciales de página renderizados en el servidor. Renderiza el HTML en el servidor como si fuera carga normal de la página aunque realmente sean trozos de página, méte el HTML generado en cadenas JavaScript e inyéctalas con innerHTML, es decir el resultado del evento es JavaScript ejecutado en el cliente. La realidad es que la inmensa mayoría de los clicks que hace el usuario requieren carga de datos del servidor, la diferencia entre devolver un trozo de HTML o sólo los datos es ínfima y la simplificación del proceso es brutal.
Te pongo un ejemplo, en el trabajo hemos hecho nuestro propio calendario AJAX de esta forma con muy poco esfuerzo y exactamente como nos da la gana, sí ese componente que si no nos lo dan hecho en JavaScript nos morimos y que casi nunca encaja con lo que necesitas. El mismo código para la renderización parcial en un cambio de mes inyectado via innerHTML es el que utilizamos para generar el HTML inicial del mes inicial en tiempo de carga de la página, esto permite la compatibilidad SEO aunque en nuestro caso no lo hemos necesitado.
Por supuesto hay cabida a movimientos, cambios de visibilidad etc en JavaScript claro.
Es verdad, esta técnica huele a ItsNat aunque mucho más artesanal (pero también muy efectiva) y sin estado en el servidor.
Los chicos de Google tienen alguna idea similar con Google Closure, aunque en este caso lo que ellos buscan es renderizar de la misma manera tanto en cliente como en servidor, supongo que para poder reutilizar las plantillas en cliente y en servidor y tener compatibilidad SEO.
Gracias por la info!!.
Muchisimas gracias por la informacion!! 🙂
Un saludo
Solo por aportar un poco de visión sobre GWT.
GWT esta centrado 100% en cliente y te permite compartir clases java entre cliente y servidor de forma totalmente transparente. Esto lo diferencia a otras herramientas como JSF, ZK, Eclipse RAP o vaadin (vaadin utiliza GWT para renderizar la parte cliente ) que se basan en la gestión de eventos en el servidor.
Se puede integrar el sistema de logging estándar de java, la validación de JPA, Excepciones y otras características que facilitan la vida a cualquier desarrollador Java.
Es muy sencillo integrar una maquetacion html tradicional utilizando uibinder o incluso el nuevo framework de twitter bootstrap. Aunque también te permite desarrollar la interfaz de usuario utilizando la forma tradicional de las aplicaciones de escritorio basada en paneles y widgets.
Ademas integra una implementacion del patrón MVP + un eventbus que te proporciona una base muy potente para el desarrollo de aplicaciones grandes.
El único inconveniente que tiene GWT es el tiempo de compilación final para obtener el código javascript, el equipo de GWT esta trabajando en ello, aunque tampoco es mucho problema si se utiliza un sistema de integración continua que realice ese trabajo final de compilación y despliegue.
Saludos.
Mmm, lo que a mi me ocurre con GWT es que no lo necesito. ¿Qué problema me soluciona GWT? Ninguno. Es cierto que a un programador de JAVA al que no le apetece aprender JavaScript, HTML5 y CSS3, le parezca muy útil.
Como opinión puramente personal, pienso que es mejor aprender las tecnologías y estándares web, para poder trabajar con ellas, que estar anclado en JAVA y depender de cosas como GWT. Pero otras personas pueden tener otros gustos y opiniones, claro.
Salud !
Enrique el argumento «de un programador de JAVA al que no le apetece aprender JavaScript, HTML5 y CSS3, le parezca muy útil» es un argumento pésimo, yo llevo más de 10 años haciendo cosas en JavaScript y AYER MISMO codifiqué cosas en JavaScript y eso que me muevo ahora en aplicaciones 90% Android nativo y aún así tengo una opinión muy muy gris sobre el mismo y no soy el único, lo oigo decir a curtidos programadores que saben lo que supone hacer sistemas de millones de líneas de código, no juguetillos.
JavaScript es un lenguaje que fue concebido para validar formularios y algunos efectillos DHTML y que se mueve en un entorno anémico, la tendencia actual a programar a saco en JavaScript el navegador que no digo que esté mal, tiene mucho sentido común, el problema es la «herramienta» que con el tiempo va a dar en mi opinión muchos disgustos a algunos.
Como dice Anders Hejlsberg el padre de Typescript
http://en.wikipedia.org/wiki/Anders_Hejlsberg
«No, you can write large programs in JavaScript. You just can’t maintain them.»
http://css.dzone.com/articles/you-can-write-large-programs
El que todo el mundo esté haciendo lenguajes alternativos a JavaScript algunos de ellos ESTATICAMENTE TIPADOS y con orientación a objetos completa como Typescript y Dart, no la cosa rara que tenemos habitualmente que hacer para que no sea un todo un spagetti-function, pues es un signo de todo esto. Por no hablar que los futuros estándares de JavaScript empiezan a ser otra cosa.
Ahora bien estoy de acuerdo con lo de la pereza, la pereza NO debería ser la excusa, si merece la pena la tecnología X de turno, si convence… ¡¡pues a saco!!
No quiero calentar mucho la polémica. Ya se que a ti simplemente JS no te convence. Yo personalmente quitaría los WTF más hirientes de JS y le añadiría un par de cosas. Lamentablemente no se pueden quitar esos problemas por retrocompatibilidad. De ahí la importancia de conocerlos, saber evitarlos y usar el subconjunto bueno del lenguaje.
Otro tema es el de lenguajes de tipado estático contra los de tipado dinámico. Eso merece otro post. Resulta que JS es de tipado dinámico, y claro, a los que les gusta el tipado estático lo ven como un problema. Lamentablemente sólo encuentro que se esgrime este argumento contra JS, no he visto nunca a nadie decir que «en Ruby no se pueden mantener grandes bases de código porque no tiene tipado estático». No veo a nadie escribir transpiladores de lenguajes estáticos a Ruby, ni TypeRuby ni nada similar, ¿por qué?
Ya sabes que pienso que haciendo TDD no necesitas que un compilador te detecte errores de tipado estático, ya que TDD detecta éstos y encima detecta bastantes errores «semánticos» (si defines bien tus tests, claro), cosa que ningún compilador hace.
Mi opinión es que los lenguajes de tipado estático son muy beneficiosos para los fabricantes de herramientas de desarrollo de software y de máquinas virtuales: Microsoft, IBM, etc. ¿Para quién trabaja el inventor de TypeScript? ¿Y el de Dart?
Finalmente: «millones de lineas de código» Si tienes una aplicación con millones de lineas de código, seguramente esta sea tan inmantenible como Windows. Las aplicaciones mantenibles no tienen millones de lineas de código. Es más, dime algún sistema con millones de lineas de código que sea mantenible, aunque esté hecho en Haskell, JAVA, C#, Clojure o Scala. Seguro que no encuentras ninguna.
Creo que algunas cosas sobre Ruby estático ya las hemos hablado en Twitter
«no he visto nunca a nadie decir que “en Ruby no se pueden mantener grandes bases de código porque no tiene tipado estático”»
Probablemente porque un significativo porcentaje del «alguien» sólo haya programado en Ruby y porque la inmensa mayoría de los proyectos grandes son Java o C# o C++.
http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
(ojo tampoco hay que considerar Tiobe como una religión)
La frase «no puedes mantenerlo» es de Anders Hejlsberg no mia, yo soy de los que opina más bien, que sí puedes mantenerlo… pero muy malamente, con un esfuerzo inmenso y con una enorme disciplina de codificación para compensar la ausencia de gestores de código estático.
A mi la detección de errores por el tipado estático me importa poco aunque importa, a mi interesa infinitamente más:
1) La expresividad: soy un perro, soy un gato, soy comida de perro
La expresividad es impagable cuando la cosa se complica más y más y más y más aun si heredas código de otro.
2) Gestión de código: es decir control, control y control. El llamar a References (Eclipse) o Find Usages y mostrarte en 1 segundo todas las dependencias es impagable, el introducir un cambio en ese método y ser capaz en cascada de resolver decenas de implicaciones sin problema, en minutos, con seguridad, con fiabilidad… es impagable. Sin tener que ejecutar cientos de tests y a cada error introducir el cambio y otra vez ejecutar cientos de tests para detectar otro error y otro nuevo cambio etc, y si no tienes esos tests directamente estás muerto.