https://d226lax1qjow5r.cloudfront.net/blog/blogposts/working-on-a-multi-language-team/multi-language-team-1-.png

Trabajar en un equipo multilingüe

Publicado el March 17, 2022

Tiempo de lectura: 8 minutos

Muchas veces, como desarrolladores que trabajamos en equipo, estamos acostumbrados a que todos los miembros del equipo dominen los mismos lenguajes, la misma tecnología y el mismo conjunto de herramientas. Dependiendo del contexto, esto puede implicar trabajar con más de un lenguaje de programación.

Si trabajas en el front-end, es probable que necesites "hablar" HTML, CSS y JavaScript. En un contexto de pila completa, también puede añadir uno de cualquier número de lenguajes de programación de back-end. Dejando a un lado cualquier especialización o enfoque en una parte concreta de la pila, los desarrolladores de un equipo de este tipo tendrán un vocabulario técnico común y un marco de referencia compartido definido por la pila tecnológica que utilicen. Sin embargo, desde que me incorporé al equipo de relaciones con los desarrolladores de Vonage, he tenido que acostumbrarme a una realidad bastante diferente a la que acabo de describir.

Para contextualizar un poco, uno de los principales objetivos de nuestro equipo es ayudar y respaldar a los desarrolladores en el uso de las numerosas API de comunicaciones de Vonage. Una de las formas en que lo hacemos es proporcionar SDK que eliminan parte de la complejidad de bajo nivel del uso de las API para integrarlas más fácilmente en una aplicación. Por supuesto, los desarrolladores que usan las API de Vonage lo hacen utilizando una amplia variedad de lenguajes de programación y pilas tecnológicas. Por lo tanto, ofrecemos SDK para muchas implementaciones de lenguajes y entornos diferentes: SDK de servidor para Ruby, PHP, Python, Java, Node y .net; SDK de cliente para JavaScript, iOS y Android.

Como Ruby Developer Advocate del equipo, parte de mi trabajo consiste en mantener y mejorar nuestros SDK de Ruby. Cuando necesito corregir un error o añadir una función, lo hago escribiendo código Ruby. Mis compañeros, sin embargo, no escriben Ruby. En su lugar, escriben PHP, Python o C#. Puede que estemos trabajando en la implementación de la misma función, pero en lenguajes completamente distintos.

Me gusta pensar que mis conocimientos de JavaScript son bastante buenos, pero no es mi lenguaje principal. He escrito algo de PHP en el pasado (aunque nuestro defensor de PHP, Jim, me asegura que el lenguaje ha cambiado mucho desde entonces) y sé un poco de Python, pero no me consideraría un experto en ninguno de esos lenguajes, y definitivamente me siento más cómodo cuando trabajo con código Ruby.

Pero si quiero ser un buen miembro del equipo y ayudar a mis compañeros en su trabajo, tengo que salir de vez en cuando de mi zona de confort de Ruby.

Durante los aproximadamente siete meses desde que me uní al equipo, me he encontrado actuando como caja de resonancia o segundo par de ojos para colegas que trabajan en errores o características para sus SDKs (no Ruby). He ayudado a revisar pull requests para las librerías PHP, Python y .net. Incluso he enviado algunos pequeños commits a uno de los repos de Python.

Sentirse incómodo (a veces) es bueno, en realidad

Trabajar en un equipo multilingüe puede plantear algunos retos. Sin embargo, me gustaría sugerir que también aporta muchas ventajas.

Como desarrolladores, nos esforzamos por dominar nuestro oficio. Aumentamos nuestra experiencia hasta un nivel en el que nos sentimos cómodos en un ámbito de conocimiento concreto. Construir esa "zona de confort del conocimiento" tiene muchas ventajas: podemos trabajar con confianza, rapidez y eficacia sin tener que comprobar o buscar cosas todo el tiempo. Por otro lado, puede volvernos perezosos y propensos a hacer suposiciones. Cuando nos enfrentamos a un nuevo problema o situación, a veces recurrimos a patrones familiares y pensamos que ya conocemos la solución sin haber reflexionado claramente sobre el problema.

Hay un concepto en el budismo Zen llamado Shoshinque se traduce como "mente de principiante". En esencia, se refiere a la idea de estar abierto a las posibilidades y sin ideas preconcebidas al estudiar un tema o abordar un nuevo problema. Adquirir experiencia elimina la "mente de principiante", pero salir de vez en cuando de la zona de confort lingüística puede ayudar a restablecerla.

Por ejemplo, si estoy trabajando en una funcionalidad para una de las bibliotecas Ruby y pienso en ella en un contexto puramente Ruby, puedo caer en el mal hábito de centrarme únicamente en la solución y no pensar claramente en el problema. Si, por el contrario, estoy discutiendo esa misma funcionalidad con colegas en un contexto PHP o Python, me veo obligado a deshacerme de cualquier suposición específica de Ruby sobre la solución y centrarme en el problema.

Además de eliminar ideas preconcebidas, trabajar día a día con desarrolladores de otros lenguajes puede ampliar tus horizontes de otras maneras. Te abre a diferentes enfoques y formas de hacer las cosas y, en definitiva, a diferentes formas de pensar.

Existe una teoría lingüística conocida como relatividad lingüística o hipótesis Sapir-Whorf. Esta teoría sugiere que la estructura de una lengua puede influir en cómo pensamos y cómo vemos el mundo. La teoría se desarrolló pensando en las lenguas humanas y no en los lenguajes de programación. Sin embargo, dado que los lenguajes de programación están diseñados por humanos, puede aplicarse la misma teoría.

El diseño de los lenguajes de programación puede crear ciertas ortodoxias sobre cómo debe escribirse el software. Los lenguajes pueden ser de tipado fuerte o débil. Algunos lenguajes se prestan a un enfoque imperativo, otros a uno declarativo. Estas características de los lenguajes pueden hacer que se piense de una determinada manera al escribir código.

Si lo único que has experimentado es una determinada forma de pensar, puedes caer en la trampa de creer que esa forma es la correcta. Experimentar distintos lenguajes y enfoques te abre a las distintas formas de pensar que sugiere el diseño de esos lenguajes. Puede mostrarte que no hay necesariamente una forma "correcta", sino diferentes "formas", cada una con sus propias ventajas y desventajas.

Por ejemplo, aunque Ruby siempre ha sido (y sigue siendo por defecto) un lenguaje tipado dinámicamente, ahora tenemos la opción de introducir comprobación de tipos estática en nuestros programas Ruby. Bibliotecas como Sorbet existen desde hace unos años, y más recientemente con Ruby 3 se ha introducido esta opción de forma nativa. Pensando en de una manera estáticamente tipada probablemente aún se sienta un poco extraño para la mayoría de los desarrolladores Ruby, y podemos aprender mucho mirando código en un lenguaje estáticamente tipado como C#.

private static void ValidSmsResponse(SendSmsResponse smsResponse)

Cuando miramos la firma de un método en un lenguaje desconocido como éste, no tenemos ideas preconcebidas sobre el lenguaje. Para entender lo que hace el código, tenemos que preguntarnos para qué cada elemento de la firma y por qué se ha escrito así. Podemos aprender de este proceso, y llevar ese aprendizaje a nuestro código Ruby.

Puntos de aprendizaje y consejos

Durante los últimos meses, he aprendido algunos enfoques útiles para trabajar en un equipo multilingüe, y quería compartir algunos de ellos aquí.

Alejar el zoom para establecer el contexto

Hace unos meses, Jim estaba trabajando en la eliminación de varios Traits de una de las librerías PHP, y quería que alguien le explicara los cambios que estaba haciendo en el código base. Durante el inicio de nuestra conversación, me perdí en la maleza de la sintaxis específica de PHP. Lo que realmente ayudó en esa situación fue alejarme y discutir los cambios a un nivel más alto de abstracción. En lugar de pensar en lo que hacía una línea de código concreta, era más fácil entender el contexto de los cambios preguntando cosas como "¿cuál es el propósito de este Trait?", "¿cuál es la relación entre estas clases?", etcétera. Una vez que se ha establecido un contexto claro para lo que está haciendo un código desconocido, es mucho más fácil volver al detalle de la implementación.

Reutilizar modelos mentales

Otra cosa que puede resultar útil cuando se pisa terreno desconocido es reutilizar o reutilizar los modelos mentales existentes. Durante nuestro aprendizaje como programadores, todos hemos dedicado mucho tiempo a establecer modelos mentales sólidos para los numerosos conceptos técnicos con los que trabajamos. La buena noticia es que muchos de ellos pueden reutilizarse o reutilizarse en el contexto de otros lenguajes de programación.

Un ejemplo podría ser intentar explicar algo como los bloques de Ruby a un desarrollador que no sea de Ruby. Sintácticamente, los bloques son muy particulares del lenguaje Ruby, pero si tengo que explicar lo que son, por ejemplo, a un desarrollador de JavaScript, puedo decir algo así como "funcionan como funciones de devolución de llamada". Claro, si profundizas en los detalles de la implementación del lenguaje no son lo mismo, pero como modelo mental general para explicar lo que hacen y cómo se usan, probablemente se acerque lo suficiente.

Conceptualmente, pasar un bloque a map en Ruby:

[1, 2, 3].map do |num|
  num + 1
end

no es muy diferente de pasar una función de devolución de llamada a map en JavaScript:

[1, 2, 3].map(function(num) {
  return num + 1;
});

Dependiendo de nuestras elecciones sintácticas en ambos idiomas, podrían incluso parecer bastante similares:

# Ruby
[1, 2, 3].map { |num| num + 1 }
// JavaScript
[1, 2, 3].map(num => num + 1)

Identificar las similitudes para comprender las diferencias

Siguiendo con este tema, otra cosa que hay que hacer es buscar las similitudes entre los distintos lenguajes y pilas tecnológicas. Antes he mencionado las ventajas de explorar y estar abierto a los distintos enfoques que pueden adoptar los lenguajes de programación. Sin embargo, en última instancia, esos lenguajes y las herramientas creadas en torno a ellos suelen tener como objetivo resolver el mismo conjunto de problemas.

Por ejemplo, existen bibliotecas de pruebas para la mayoría de los lenguajes de programación. La sintaxis que utilizan difiere de un lenguaje a otro; algunas, como RSpec, pueden incluso utilizar su propio DSL. Sin embargo, en última instancia, todas las bibliotecas de pruebas resuelven el mismo problema. A nivel general, todas utilizarán aserciones de alguna manera.

Minitest y PyTest son bibliotecas de pruebas, una para Ruby y la otra para Python. Identificar esas similitudes entre ellas puede proporcionar un contexto de base que luego puede ayudar a sacar a la superficie las diferencias interesantes en cómo funcionan o cómo se han implementado.

Un mundo más allá de Rubí

Supongo que lo que estoy tratando de decir con todo esto, es que si bien puede ser tentador quedarse en su zona de confort, y se adhieren a lo que estás acostumbrado, lo que he experimentado en los últimos meses me ha recordado que hay todo un amplio mundo de cosas vibrantes e interesantes pasando en lenguajes distintos de Ruby. Me encanta Ruby y, desde luego, no tengo intención de dejarlo como lenguaje principal, pero me entusiasma la idea de sumergirme y explorar más a fondo algunos de esos otros lenguajes.

Compartir:

https://a.storyblok.com/f/270183/373x376/e8d3211236/karl-lingiah.png
Karl LingiahDefensor del desarrollador Ruby

Karl es un defensor de los desarrolladores para Vonage, centrado en el mantenimiento de nuestros SDK de servidor Ruby y la mejora de la experiencia de los desarrolladores para nuestra comunidad. Le encanta aprender, hacer cosas, compartir conocimientos y, en general, todo lo relacionado con la tecnología web.