FdA #10 - Las teorías de Darwin y Dawkins aplicadas a los lenguajes de programación
Un enfoque diferente para dar valor a todos los lenguajes, incluso a esos a los que solemos denostar.
"La esencia más común de la vida es el cambio; la existencia más común es ir de lo que fue a lo que será." - Arthur Schopenhauer
La vida tiene una naturaleza cambiante y dinámica, Schopenhauer lo sabía muy bien, aunque también te digo que no está claro que podamos atribuir esta cita al filosofo alemán.
Lo importante aquí es que, el cambio constante no es una excepción. Quizá no siempre lo percibamos, pero está siempre latente. Saber navegar en este flujo temporal puede ser clave para adaptarse y evolucionar.
No te quedes estancado, muévete, haz algo nuevo, no te aburras, abúrrete.
Las teorías de la evolución, aplicadas a los lenguajes de programación
La evolución de las especies animales nos explica cómo cambian éstas a lo largo del tiempo. Tenemos muchos autores que han estudiado la evolución (centrada o no en humanos) con diversos focos: biología, psicología, sociología…
Dos de los científicos más destacados en estos derroteros son, por un lado, y como no podía ser menos, Charles Darwin, autor del famoso El Origen de las Especies publicado en 1859 después de toda una vida trabajando en la teoría de la evolución. Por otro lado, tenemos a Richard Dawkins, autor del excelso El Gen Egoísta publicado en 1976 y que complementa muy bien al primero.
Estas dos obras responden bastante bien a una de las mayores preguntas que se ha hecho el ser humano: ¿De dónde venimos? Y buena parte del marco teórico y empírico que nos aportan se puede aplicar a entender la evolución de los lenguajes de programación y a inferir por qué son como son.
Variación y Selección Natural
En la evolución biológica, la variedad de genes es esencial para la selección natural. En la evolución de los lenguajes de programación, el equivalente a la variación genética podría ser el conjunto de características que se van introduciendo en el lenguaje.
La selección natural se puede equiparar a la aceptación y popularidad de los lenguajes que ofrecen mejores funcionalidades, rendimiento y facilidad de uso.
Algunos ejemplos de esto en las últimas décadas:
Década de 1970: los lenguajes con más aceptación fueron Fortran, sobre todo en ámbitos científicos y de ingeniería; C, uno de los más destacados por su eficiencia y flexibilidad; y Pascal, siendo popular como lenguaje usado en la enseñanza.
Década de 1980: las reinas del baile fueron de nuevo C, continuando con su influencia; C++, que se desarrolló como una extensión de C introduciendo la programación orientada a objetos; y Ada, que se desarrolló y usó ampliamente para aplicaciones críticas para la defensa e ingeniería aeroespacial.
Década de 1990: la popularidad recayó en Java, debido a su uso en el desarrollo web; C++, muy relevante en aplicaciones a gran escala; y Python, que ya empezaba a destacar por su simplicidad y versatilidad.
Década del 2000: los reyes fueron Java, con mucha influencia en el desarrollo empresarial; C#, convirtiéndose en un competidor fuerte, mayormente en entornos Windows; Python, que empezaba a ser el rey en áreas como las ciencias de datos; PHP, que fue ampliamente usado para el desarrollo web dinámico.
Década del 2010: los más populares fueron JavaScript, convirtiéndose en parte esencial del desarrollo web; Python, ampliando su influencia en sectores relacionados con el aprendizaje automático e inteligencia artificial; Java y C#, que seguían siendo las opciones más usadas en desarrollo empresarial.
Década del 2020: no hemos hecho más que empezar, pero por ahora vemos algo parecido a la década anterior, con algunas novedades como TypeScript, que ha ganado popularidad como extensión de JavaScript; Python se ha consolidado como lenguaje para la ciencia de datos y el machine learning; mientras que Java y C# se han seguido usando para aplicaciones empresariales, aunque empiezan a comerle la tostada lenguajes como Rust o Golang.
Adaptación y Supervivencia
Los organismos vivos en una época concreta son los que mejor se han adaptado al entorno en cada momento. Los que mejor han llevado el cambio constante de la vida.
Lo mismo sucede con los lenguajes de programación, solo sobreviven esos que se adaptan -o son adaptados, mejor dicho- a las necesidades presentes, piensa en la eficiencia, curva de aprendizaje, etc.
Piensa también en la cultura del esfuerzo por ejemplo. Si coincides conmigo en que décadas atrás era mucho más fuerte que en las generaciones más recientes, entonces posiblemente opines, al igual que yo, que es uno de los claros motivos por los que lenguajes más difíciles de aprender vayan desapareciendo y, por contra, vayan apareciendo lenguajes más sencillos o incluso aplicaciones low code que nos permiten obtener resultados programando poco o nada.
Otro motivo relacionado con todo ello es el cortoplacismo, mucho más marcado hoy que hace 30 o 40 años. Lo queremos todo y lo queremos ya. Esta es otra de las adaptaciones que necesitan los lenguajes que pretenden sobrevivir. La curva de aprendizaje se intenta allanar, o por lo menos nos hacen subir la cuesta con escaleras automáticas.
Competencia y Cooperación
En un contexto biológico, los organismos compiten por unos recursos limitados. De forma similar, los lenguajes compiten por las preferencias de las personas que programan y por los recursos de computación.
Por otro lado también hay cooperación: mientras que los seres vivos pueden agruparse para beneficiarse mutuamente, los diferentes lenguajes de programación suelen influenciarse entre ellos.
Fíjate cómo en la evolución de los lenguajes destacados en entorno empresarial, Java y C#, compiten y se influencian entre ellos.
Por un lado, se puede ver cómo compiten por sus diferencias más marcadas, como las plataformas de desarrollo o sus herramientas, pero por otro lado también se influencian, y lo podemos ver a través de sus similitudes, como en la sintaxis, el uso de máquinas virtuales para hacer el código portable o el gran énfasis de los dos en la orientación a objetos.
Gen Egoísta y Optimización
Podemos dotar a los genes de un cierto comportamiento egoísta, puesto que en cada espécimen se enfocan en maximizar la propia supervivencia. Algo parecido pasa con "los genes” de los lenguajes de programación.
Se ha comentado antes que los genes en un lenguaje serían sus características. Estas propiedades están siempre enfocadas a maximizar la utilidad -y por lo tanto la supervivencia- del propio lenguaje.
En biología, es habitual que una vez pase la edad de reproducción, venga un declive muy marcado, ya que ese individuo ya no aporta nada -evidentemente, el caso de la especie humana es diferente-. Entonces, una vez llegados a ese punto, las características del individuo ya no son útiles y desaparece, muere.
Algo parecido podemos ver por ejemplo con tecnologías que llegan a cierto punto de madurez y sus características ya no aportan demasiado valor, entonces desaparecen. Puedes ver multitud de ejemplos en Killed by Tech. También puedes ver esta breve historia de los predecesores de NumPy.
Herencia y Evolución Continua
Si en la biología la información genética se hereda a los descendientes, con los lenguajes de programación pasa lo mismo: los mejores genes/características se traspasan de una generación a otra.
Un ejemplo de esto lo podemos ver en el lenguaje Rust, que ha tomado características de multitud de predecesores: sintaxis y gestión de memoria propios de C y C++, verificación de límites y control de acceso a memoria característicos de Ada, tipado de datos influenciado por Haskell o la concurrencia inspirada, en parte, en Erlang.
Otro famoso caso es el de TypeScript, que es un superconjunto de JavaScript. A los más fanáticos de lenguajes basados en C les suele gustar la capa que añade a las características de JS. Incluso es posible que futuriblemente JavaScript se vea afectado y mejorado debido a TypeScript, aquí ya entraríamos en un bucle infinito de influencia mutua.
Extinción y Obsolescencia
Cuando una especie animal llega a su fin y se extingue completamente suele ser debido a un cambio brusco y rápido en su hábitat. Tan brusco y rápido que no ha dado tiempo a las continuas mutaciones genéticas a generar individuos que se puedan adaptar al entorno.
A los lenguajes de programación les puede pasar algo parecido. Pueden quedar obsoletos debido a una falta de apoyo, a una evolución tecnológica (que ya sabemos que suelen ser rápidas) o a la falta de relevancia en un momento dado.
El lenguaje COBOL, por ejemplo, que aunque se siga usando en código legado, lo podemos considerar extinto porque difícilmente va a usarse en ningún proyecto nuevo.
¿Qué le pasó a COBOL? Pues básicamente el cambio en las preferencias tecnológicas y la evolución del panorama informático.
Algunas de las características de este lenguaje hacían que quedara atrás comparado con otros lenguajes que lo mejoraban en muchos aspectos, esto provocó que su adopción disminuyera.
El enfoque de COBOL en el procesamiento de datos empresariales no era tan versátil como otros lenguajes que surgieron con capacidades más amplias. Algunas de estas características que lo dejaron obsoleto son:
elevada verbosidad que dificultan la legibilidad del código incluso en tareas simples
enfoque demasiado estrecho a algunas aplicaciones empresariales
la escasa orientación a objetos dificultaba el modelado de datos
resistencia al cambio y a la adaptabilidad
COBOL no se adaptó, se resistió al cambio. COBOL murió.
Reflexión final
Todos los lenguajes son o han sido útiles en algún momento. Es muy habitual el tribalismo y competencia entre desarrolladores de diferentes lenguajes, pero a veces caemos en la crítica sin sentido.
Todos sabemos que hay lenguajes que son odiados por buena parte de la comunidad developer, pero creo que eso es un error. Eso, es no querer ver las partes buenas que tienen todos los lenguajes. Sí, incluso COBOL.
Te gustará más o menos, pero todos tienen ventajas e inconvenientes. ¿No deberíamos estar preparados para poder afrontar diferentes retos con el lenguaje que mejor se adapte a ellos? Es sano que haya tanta diversidad en nuestro ecosistema de desarrollo, nos hace mejores a todos.
Te animo a que, la próxima vez que se te cruce un pensamiento de odio por la cabeza hacia un lenguaje de programación concreto, intentes reflexionar sobre por qué existe, qué utilidad tiene en el mercado y en qué contextos el lenguaje es útil.
Y, sobre todo, qué te ha llevado a pensar mal en un primer momento sobre ese lenguaje. Yo apuesto a que la culpa es más del contexto que rodea el lenguaje, que del lenguaje en si mismo.
Yo he llegado a odiar Java, pero con el tiempo me he dado cuenta que no odiaba el lenguaje en sí, sino el contexto donde lo aprendí -o me hicieron aprender-.
¿Alguna vez has odiado un lenguaje?
¿Por qué?
Mis recomendaciones
🧠 Comportamiento y psicología
En este interesantísimo post de Rob Henderson se desgranan las diferentes maneras en que descartamos o abrazamos nuevas ideas, opiniones, ideologías, pensamientos, etc. Es importante ser conscientes de qué manera se nos presenta la información, cuáles son nuestros sesgos en ese sentido y de qué forma nuestro instinto nos puede perjudicar.
Sergio San Juan nos deleita con este resumen de los 7 principios de persuasión de Cialdini, que son trucos que los vendedores conocen y que, si tu también te los sabes, posiblemente evites que te estafen.