Chandler Carruth propuso en la CppNorth 2022 la evolución de C++ hacia Carbon. Según indicaba en su charla, Java fue mejorado por Kotlin, JavaScript por TypeScript y ahora C++ puede serlo con Carbon, ¿puede ser un digno sucesor?
Comenzaremos analizando quién es Chandler Carruth, según la página de la conferencia, es el líder técnico de fundamentos de lenguajes de programación y software de Google. Parece una apuesta fuerte por parte de Google que nos deja muchos interrogantes como, ¿afectará este desarrollo a Go? ¿por qué no elegir Go, Rust, Zig o cualquier otro en lugar de crear Carbon?
Carruth hizo una introducción mencionando la transición entre muchos lenguajes, de C a C++, de JavaScript a TypeScript, de Objetive-C a Swift, de Java a Kotlin, pero se preguntaba, ¿a qué evoluciona C++? ¿es un pokémon sin evolución?
Para poder vislumbrar un poco qué podría venir después de C++ tendríamos primero que ver para qué sirve o para qué es bueno C++. En 2019, Carruth habló hizo otra charla What is C++ Good For? (¿Para qué es bueno C++?) haciéndose estas preguntas junto con Titus Winters (también de Google) en una graciosa charla.
De esta última charla se desprenden algunas preocupaciones sobre C++ y algunas propuestas por prioridad:
Estas propuestas crearon una semilla que según la cuenta de Github de Carbon comenzó a germinar y el 27 de abril de 2020 tuvo su primer commit (solo la licencia, Apache License 2.0), el 28 de abril su segundo commit con el código de conducta, forma de contribución y mucha documentación acerca de la propuesta.
En su documentación, al momento de hacer su primera subida, definen el proyecto de la siguiente forma:
El proyecto del lenguaje Carbon es un experimento para explorar un posible y distante futuro para el lenguaje de programación C++. Está diseñado alrededor de un conjunto específico de objetivos y casos de uso:
- Software de rendimiento crítico.
- Evolución de tanto lenguaje como software.
- Código fácil de leer, de entender y escribir.
- Garantías prácticas de seguridad y mecanismos de pruebas.
- Desarrollo rápido y escalable.
- Arquitecturas de hardware actuales, plataformas de SO y entornos a medida que evolucionen.
- Interoperatividad con y migración para código C++ existente.
Vemos que las promesas y objetivos se alinean con las propuestas o solicitudes realizadas en la presentación de 2019 y en vista de no poder realizar esto dentro de C++, piden al nuevo lenguaje la interoperatividad necesaria para convivir en proyectos de C++ existentes y permitir la migración progresiva.
Pero entonces, ¿quiere esto decir que Go, Rust, Zig, Nim u otros lenguajes no consiguen estos fines? ¿Por qué Carbon resuelve mejor este problema?
Como menciona el último objetivo del proyecto Carbon, la interoperatividad es muy importante para ellos. Según indican en ese mismo documento inicial:
Otros lenguajes de programación no satisfacen actualmente estas necesidades eficientemente. Estos presentan desafíos en interoperatividad, migración y rendimiento que los hacen caros y potencialmente imposibles para migrar una base de código grande de C++.
Para empresas con proyectos enormes, no es una solución migrar a Rust o Go porque supone una reescritura demasiado costosa de la base de código fuente y un desafío importante para migrar porque al ser tan grande intervienen otros problemas específicos de las migraciones.
Aunque Google diseña, mantiene y usa Go, para ciertas bases de código que ellos mismos mantienen, el uso de Go es inviable por ese mismo problema. La transformación de todo el código a una base binaria completamente diferente supone el riesgo de no hacer la migración correctamente además de suponer un cambio enorme en un solo paso.
El empleo de Carbon supone un inicio sutil. Incorporar el lenguaje dentro de un proyecto grande e ir escribiendo código poco a poco, migrando solo pequeñas porciones cada vez hasta conseguir migrar todo el código.
La mayoría de gente piensa en lenguajes como Go o Rust como sucesores, pero realmente no se ven claros por los motivos anteriores y además porque para la mayoría de desarrollos en C++ el recolector de basura supone un despropósito. Volvemos al mismo punto de intentar mantener el mismo ecosistema.
El lenguaje sucesor tiene que:
Siendo los tres pilares del lenguaje:
La última pregunta y que muchos se realizan tras la presentación del proyecto, ¿es este lenguaje un competidor de Go? ¿cesará el desarrollo activo de Go al comenzar con Carbon?
En principio, el desarrollo de Carbon cubre otras necesidades diferentes a las que cubre Go. El lenguaje Go nació con unos objetivos a cumplir muy diferentes, enfocado en mantener una facilidad y rapidez importantes y cubrir desarrollos más enfocados en la concurrencia.
Go sigue siendo un lenguaje fuerte y cada vez más usado y al igual que Dart, se mantiene dentro de Google para los fines para los que se emplea que son diferentes a la motivación inicial y las necesidades a cubrir por Carbon.
Como hemos dicho anteriormente, la propuesta inicial de 2019 fue para mejorar el lenguaje C++. No obstante, un lenguaje que lleva con nosotros más de 30 años es difícil de arreglar, intentar mejorar su sistema se convierte en un tedioso y aburrido politiqueo con personas que pueden no querer cambiar el lenguaje o que simplemente tienen miedo de afectar a muchos haciendo esos cambios.
Parece que Google no estuvo por la labor de intentar convencer a la comunidad actual y al igual que pasó con Perl cuando surgió Raku, se optó por una salida tangencial, crear un nuevo lenguaje. Los motivos principales que les motivaron a tomar este camino fueron:
Veamos un ejemplo de código, ¿cómo es este lenguaje?
// This code is in the `Geometry` package (and root namespace).
package Geometry api;
// It imports the default library of the `Math` package.
import Math;
class Circle {
var r: f32;
}
fn ScaleAreaAndAppend(circle: Circle, log2_scale: i32,
results: Vector(f32)*) {
var area: f32 = Math.Pi * c.r * c.r;
// Compute the scale.
let scale: i32 = 1 << log2_scale;
// Apply the scale.
area *= scale;
// Append to in the provided container.
results->append(area);
}
Vemos el código con algunos elementos que no pertenecen a C++ como var
, let
o fn
pero que nos dejan claro qué realizan. Por un lado, var
está claro que define nuevas variables y a diferencia de Go y otros lenguajes, los tipos no son inferidos, deben indicarse. También tenemos let
que nos deja entrever su uso como una constante. Establece un valor pero este valor no cambiará. La palabra clave fn
también está clara, define una función al igual que empleamos class
para definir una clase.
La creación de los paquetes y su uso como podemos ver con Math
indica una mejor organización del código al identificar cada llamada a función con el módulo del que proviene y cada fichero con el módulo (o paquete, package
) que define.
Creo que este patrón propuesto por Carruth es una muy inteligente forma de evolucionar un código. En lugar de cambiar completamente o migrar un código de un lenguaje antiguo o difícil, creamos un nuevo lenguaje dentro del mismo ecosistema que permita una alta interoperatividad y así facilitar el cambio y la migración poco a poco.
¿No estaría bien conseguir esto mismo con otros entornos y lenguajes como COBOL?
¿Qué te parece Carbon? ¿y la iniciativa de Carruth? ¿qué situaciones de migraciones o cambios has experimentado? ¡Déjanos tu comentario!