Mojo 馃敟: un nuevo lenguaje de programaci贸n para Inteligencia Artificial

Mojo 馃敟: un nuevo lenguaje de programaci贸n para Inteligencia Artificial

Otra vez la misma historia. La inform谩tica vive en una especie de condena de S铆sifo, pues cada cierto tiempo se observa la misma historia, una especie de eterno retorno: el surgimiento de un nuevo lenguaje de programaci贸n, un nuevo framework, una nueva biblioteca, etc. y, en la mayor铆a de los casos, poco hay de nuevo.

En cambio, hay mucho de viejo: Una especie de disfraz para contentar a los ansiosos por nuevas herramientas: 芦S贸lo me interesa mantenerme actualizado禄 es el mantra com煤n. Pero no todo es negativo. En ese tsunami de tecnolog铆as que emergen, de vez en cuando, una se lleva las miradas, no tanto por lo que promete 鈥攖odos se ensalzan por marketing鈥 sino por qui茅n lo promete.

A principio de 2023 apareci贸 Mojo, un lenguaje de programaci贸n para Inteligencia Artificial (IA) creado por la empresa Modular, liderado por Chris Lattner, creador de Swift (Apple) y de LLVM (la principal herramienta para construir compiladores).

Mi primera impresi贸n fue dudar, pues cada cierto tiempo aparece un nuevo lenguaje que dice ser gran alternativa a los ya establecidos para IA (a saber: Python, R, C++ e incluso Julia). Aunque en esta ocasi贸n fue diferente, pues al ver el nombre de Lattner 鈥攓uien es un gran ingeniero鈥, al menos podemos estar seguros de algo: detr谩s de Mojo hay calidad.

En este art铆culo revisaremos cinco caracter铆sticas de Mojo que lo hacen merecedor de atenci贸n. Luego dar茅 algunas consideraciones personales con respecto al lenguaje y concluir茅 con algunas sugerencias.

Caracter铆sticas

Mojo 馃敟 se presenta como un superset de Python (es decir, mantiene sus mismas caracter铆sticas e incorpora nuevas), con un rendimiento similar a C.

A continuaci贸n, presentar茅 sus caracter铆sticas m谩s destacadas que, seg煤n sus autores, sostienen dicha afirmaci贸n.

Importante: al momento de que escribo este art铆culo (mayo de 2023), s贸lo es posible usar Mojo a trav茅s de una lista de espera, as铆 que debemos aguardar un tiempo para que est茅 disponible para todos.

Mojo tiene el eslogan de 芦a new programming language for all AI developers禄 (nuevo lenguaje de programaci贸n para todos los desarrolladores de IA). Con eso prevemos entonces que todas sus nuevas caracter铆sticas se centran en dar 茅nfasis a temas como el rendimiento y la paralelizaci贸n, fundamentales para crear sistemas de IA.

1) Compatibilidad total con Python

El roadmap de Mojo es usar CPython como base y que sea totalmente compatible con el c贸digo de Python. Algo similar a cuando apareci贸 C++, donde se incorporaron nuevas caracter铆sticas (clases) sin perder la compatibilidad con C.

Ahora bien, Mojo tiene las siguientes diferencias con Python.

  • A帽ade tipos. Mojo tiene struct est谩ticas, mientras que Python cuenta con class din谩micas. Adem谩s, las struct en Mojo le permiten ganar rendimiento. Dentro de este tipo es posible utilizar las palabras reservadas var y let, donde la primera define una variable mutable y la segunda inmutable.
  • Paralelismo nativo. A diferencia de Python, Mojo est谩 dise帽ado para hacer m谩s f谩cil trabajar con paralelismos, similar a lo que ocurre con otros lenguajes como Julia.

Las dem谩s caracter铆sticas las mostrar茅 a continuaci贸n.

2) Tipos progresivos

Este sistema de tipo le da la responsabilidad al programador sobre qu茅 expresiones dentro de su programa le a帽aden o no tipos, haciendo variar la garant铆a del sistema. En otras palabras, en los sistemas de tipos progresivos permiten a los programadores aprovechar las ventajas de los tipos din谩micos, as铆 como lo mejor de los sistemas est谩ticos donde ellos requieran.

Veamos un ejemplo:

def ordenamiento(v: ArraySlice[Int]):
  for i in range(len(v)):
    for j in range(len(v) - i - 1):
      if v[j] > v[j + 1]:
        swap(v[j], v[j + 1])

Aqu铆 se le asigna el tipo ArraySlice[Int] al argumento v de la funci贸n ordenamiento. En Python esto no es posible: lo m谩s similar es asignar un hint (anotaci贸n), pero en ning煤n caso este permite funcionar como un sistema de tipado est谩tico, como s铆 lo provee Mojo.

Sumado a esto, trae cuestiones m谩s profundas en la implementaci贸n del compilador, pues estos tipos progresivos aumentan sus garant铆as (correctitud) en las porciones del c贸digo donde el programador le indic贸 que lo haga mediante el uso de alg煤n tipo.

Esto se puede apreciar en c贸mo y d贸nde surgen los errores.

3) Abstracci贸n de costo cero

Significa que se pueden a帽adir funcionalidades de alto nivel como metaprogramaci贸n, inicializaci贸n de estructuras, algoritmos param茅tricos (siguiente caracter铆stica) o cualquier otra sofisticada abstracci贸n sin que sea penalizado en tiempo de compilaci贸n (de ah铆 el costo cero).

struct Par:
  var primero: Int
  var segundo: F32
  
  def __init__(self, primero: Int, segundo: F32):
    self.primero = primero
    self.segundo = segundo

En este ejemplo, la estructura Par tiene dos atributos primero y segundo, ambos con tipado est谩tico, que luego son inicializados en el constructor. Por ejemplo, Python no tiene abstracciones de costo cero, por tanto, la estructura Par como cualquier abstracci贸n tender铆a a aumentar el tiempo de compilaci贸n.

4) Algoritmos param茅tricos portables

Permite aprovechar la metaprogramaci贸n 鈥攓ue trabaja en tiempo de compilaci贸n鈥 para escribir algoritmos agn贸sticos al hardware y reducir, de esta forma, el c贸digo, a trav茅s de su tipo SIMD (Single Instruction, Multiple Data), que es un conjunto de instrucciones que representa un vector de bajo nivel en hardware.

Esto evita adaptar el c贸digo para operar con distintas arquitecturas de CPU como SSE, AVX-512, NEO, SVE, entre otras compatibles con SIMD.

def exp[dt: DType, elts: Int]
    (x: SIMD[dt, elts]) -> SIMD[dt, elts]:
  x = clamp(x, -88.3762626647, 88.37626266)
  k = floor(x * INV_LN2 + 0.5)
  r = k * NEG_LN2 + x
  return ldexp(_exp_taylor(r), k)

En la funci贸n exp se a帽ade el tipo SIMD como argumento de entrada y para su devoluci贸n. Este tipo de caracter铆stica es 煤til para quienes quieran aplicar optimizaciones de bajo nivel contra el hardware, aprovech谩ndolo de mayor manera y ganando rendimiento en sus sistemas de IA (algo que no suele ser simple en Python).

5) Autojuste integrado al lenguaje

Cuando se trabaja en bajo nivel, hay veces que para acelerar un algoritmo se debe encontrar el correcto ajuste en las dimensiones de los vectores que dependen de cada hardware. Entonces, en vez de buscar y luego evaluar cada posible valor, us茅 autotune, que hace internamente estas comprobaciones y le devuelve el valor 贸ptimo m谩s adecuado al hardware.

def exp_buffer[dt: DType](data: ArraySlice[dt]):

  # Busca el mejor tama帽o del vector desde varias posibilidades
  alias vector_len = autotune(1, 4, 8, 16, 32)
  
  # Lo usa para crear la vectorizaci贸n
  vectorize[exp[dt, vector_len]](data)

El ejemplo superior se dan cinco alternativas para inicializar las dimensiones de un vector. Sin una funci贸n que busque el mejor valor posible, ser铆a preciso realizar pruebas en cada caso, volvi茅ndose una labor tediosa.

Breves consideraciones

En el sitio web de Mojo se muestra una tabla que lo compara con Python 3.10.9, PyPy y Scalar C++ en la implementaci贸n del algoritmo Mandelbrot, en cuanto a tiempo de ejecuci贸n.

Imagen extra铆da: https://www.modular.com/mojo

Evidentemente, es sorprendente 鈥攃omo todas las comparaciones presentes en el sitio web de un nuevo lenguaje de programaci贸n鈥. Sin embargo, hay que ser cautelosos con este tipo de gr谩ficos, pues esconden la implementaci贸n de cada alternativa, algo crucial para hacer una comparaci贸n justa.

Otra consideraci贸n interesante de Mojo es con respecto a una decisi贸n que est谩 escrita en su repositorio:

Creemos que un grupo peque帽o y unido de ingenieros con una visi贸n compartida puede avanzar m谩s r谩pido que un esfuerzo comunitario, as铆 que seguiremos incub谩ndolo dentro de Modular hasta que est茅 m谩s completo.

Una de las ventajas de comenzar un proyecto en una comunidad es que se puede recibir retroalimentaci贸n de cualquier parte, pero tambi茅n no siempre es recomendable cuando se est谩 empezando porque es proclive a tomar malas decisiones de dise帽o que m谩s tarde no pueden modificarse.

As铆, pienso que es una buena decisi贸n dejar el coraz贸n de Mojo en manos de ingenieros especializados en dise帽o de lenguajes, al menos antes de abrirlo a todos. En este punto, es normal que surja la pregunta: 驴Alg煤n d铆a lo dejar谩n open source? Ya veremos.

Conclusi贸n

Mojo es acaso el primer lenguaje de programaci贸n que se propone la 鈥攁rdua鈥 tarea de tener compatibilidad total con Python y, entonces, a帽adir nuevas caracter铆sticas y funcionalidades que lo hagan tan eficiente como C.

Adem谩s, como se pudo ver en este art铆culo, Mojo est谩 dise帽ado para personas que no solo trabajen en el nivel superior de las aplicaciones de IA, sino tambi茅n para quienes necesitan mayor control a bajo nivel, donde optimizar el hardware es un deber. As铆, a帽ade una capa no presente en Python: caracter铆sticas de lenguajes de bajo nivel como C.

Y aunque puede parecer demasiado sorprendente teniendo de aval a Chris Lattner 鈥攓ue ya ha demostrado su val铆a creando Swift y LLVM鈥, lo mejor que podemos hacer es esperar para ver si nos vuelve a asombrar.


Algunas sugerencias para mantenerte al d铆a con el desarrollo del lenguaje:

  • Considera seguir el Twitter de la empresa Modular y el proyecto en GitHub.
  • Procura a帽adirte a la lista de espera en este enlace para ser de los primeros en usarlo.
  • Sigue la cuenta del autor principal detr谩s de Mojo: Chris Lattner.

Referencias

Notas

Los c贸digos fueron extra铆dos y adaptados desde la documentaci贸n oficial de Mojo.

馃挕
Las opiniones y comentarios emitidos en este art铆culo son propiedad 煤nica de su autor y no necesariamente representan el punto de vista de Listopro.

Listopro Community da la bienvenida a todas las razas, etnias, nacionalidades, credos, g茅neros, orientaciones, puntos de vista e ideolog铆as, siempre y cuando promuevan la diversidad, la equidad, la inclusi贸n y el crecimiento profesional de los profesionales en tecnolog铆a.