- Un lenguaje evolutivo que hereda la sintaxis y la semántica de C mientras refuerza la seguridad y la facilidad de uso, manteniendo un entorno familiar para desarrolladores de C existentes
- Ofrece compatibilidad completa con el ABI de C, por lo que puede integrarse de inmediato en proyectos de C/C++; existe un caso donde parte del código de vkQuake fue convertida a C3 y compilada con el compilador c3c
- Sistema de módulos, sobrecarga de operadores, macros en tiempo de compilación y más para mejorar la estructura y la expresividad del código
- Incluye funciones modernas como programación por contratos (Gradual Contracts), manejo de errores sin sobrecarga, reflexión en tiempo de ejecución y en tiempo de compilación
- En modo debug, proporciona automáticamente verificaciones de seguridad y stack traces detallados, lo que favorece la detección de bugs y la estabilidad
Resumen de C3
- C3 es un lenguaje de programación desarrollado a partir de la sintaxis (syntax) y la semántica (semantics) del lenguaje C
- Su objetivo es evolucionar el lenguaje manteniendo una forma familiar para los programadores de C existentes
- Soporta sobrecarga de operadores precisa y orientada a objetivos
- Permite expresar de forma natural vectores, matrices y operaciones de punto fijo sin la estructura compleja de sobrecarga de C++
- Soporta programación por contratos, lo que permite declarar restricciones en tiempo de ejecución y en tiempo de compilación
- Refuerza la estabilidad del código y la consistencia de las especificaciones
- Combina las ventajas del manejo de errores basado en Result y las excepciones (exception)
- Ofrece una estructura de gestión de errores que se integra de forma natural con código C
- Soporta introspección de tipos (type introspection) tanto en tiempo de compilación como en tiempo de ejecución
- Ensamblador en línea: permite escribir ensamblador como si fuera código normal, sin cadenas ni restricciones complejas
- En modo debug, inserta automáticamente verificaciones de límites (bound checks) y verificaciones de valores (value checks) en tiempo de ejecución
- La biblioteca estándar de C3 ofrece por defecto stack traces detallados en builds de depuración
- Permite identificar la ubicación concreta del error en lugar de un simple “segmentation fault”
Ergonomía y seguridad
- Mediante Optionals, ofrece seguridad en el manejo de errores y de null
- Con la sintaxis defer, soporta automatización de limpieza de recursos
- Con slices y foreach, permite iteración segura
- Con contracts basados en comentarios, permite declarar restricciones del código
- En el contexto @pool, soporta liberación automática de memoria
Rendimiento por defecto
- Permite control a nivel de hardware escribiendo directamente vectores SIMD
- Soporta ajuste fino del rendimiento con varias opciones de asignadores de memoria
- Adopta un diseño de manejo de errores sin sobrecarga
- Aprovecha tiempos de compilación rápidos y optimización con backend LLVM
- Ofrece ensamblador en línea fácil de usar
Biblioteca estándar con todo incluido
- Proporciona estructuras de datos estándar, incluyendo contenedores dinámicos y cadenas
- Garantiza portabilidad entre plataformas mediante abstracciones multiplataforma
- Permite acceso nativo a la plataforma cuando es necesario
Aprovecha bibliotecas existentes de C o C++
- C3 es totalmente compatible con el ABI de C, por lo que no se necesitan “tipos compatibles con C” ni declaraciones de función separadas
- Es posible enlazar código C desde C3, y también enlazar código C3 desde C
Los módulos son simples
- Sistema de módulos simple e intuitivo
- La configuración predeterminada está organizada de forma razonable y no interrumpe el flujo de desarrollo
- Proporciona gestión de espacios de nombres mediante módulos
- Simplifica la estructura de encapsulación con control explícito
- Las interfaces permiten definir comportamiento compartido
- Ofrece la función de generic modules, que permite implementar la creación de tipos genéricos de forma simple y clara
- Soporta reutilización estructural mediante subtipado de structs
Macros sin un PhD
- Las macros en tiempo de compilación pueden escribirse con una forma similar a las funciones normales
- Soporta macros conscientes de tipos que entienden la información de tipo del código
- Ofrece generación de código más clara y potente que el preprocesador de C
4 comentarios
Están saliendo de muchas formas. LONG LIVE C-LANG !!!
Pero si después sale c4, ¿tendrá una popularidad verdaderamente explosiva...?
Como Zig trae cambios incompatibles cada año, aunque me gusta el lenguaje, ya no me dan ganas de usarlo. En cambio, viendo la introducción de C3, en general se siente como una mezcla de C + Go, así que parece cómodo de leer y escribir, y da la impresión de que habrá mucho menos estrés con las actualizaciones de versión.
También aportando un poco de apoyo... lo he estado usando recientemente y es divertido.
Me gusta porque da la sensación de que solo intenta mejorar los puntos incómodos de C.
La documentación oficial todavía se siente algo inmadura
(para averiguar una u otra función, muchas veces termina descrita en lugares totalmente inesperados...)
Opiniones de Hacker News
No impone un modelo de memoria nuevo ni intenta convertirse en C++
En especial, gracias a su compatibilidad ABI completa, puedes mezclar archivos de C3 directamente en sistemas de build de C ya existentes sin tener que escribir bindings
Aplaudo la visión de su mantenedor, que busca evolución en vez de revolución
Parece un lenguaje recomendable para aprender un fin de semana. Se siente más moderno que C99, pero familiar
La razón por la que no logro abandonar por completo C es por cstring y los punteros no liberados
C en sí no es tanto un lenguaje peligroso; lo peligroso son las implementaciones y la ABI
Si aplicas fat pointers, mejoras a varargs, UBSan, MTE, etc., queda bastante bien
Si el compilador no tiene que verificar necesariamente los contratos, y al violarlos puede producirse comportamiento indefinido, no sé bien cómo confiar en esto y usarlo
Es una función interesante, pero se ve algo riesgosa
Puedes ignorarlos, verificarlos en runtime, o asumir que siempre son ciertos y aprovecharlos para optimización
Por ejemplo, puedes validar la validez de un puntero y dejar una condición como “la entrada debe ser impar” solo como suposición
Los equipos grandes pueden hacerlos obligatorios, y herramientas como Visual Studio pueden solo mostrar advertencias y permitir un aprendizaje gradual
Es decir, puedes activarlos durante el desarrollo y desactivarlos al desplegar para que no afecten el rendimiento
Las condiciones que sí deben comprobarse obligatoriamente hay que manejarlas directamente con código dentro de la función
Entre sus diferencias con C están la ausencia de archivos de encabezado, namespaces basados en módulos, slices, sobrecarga de operadores, módulos genéricos, manejo de errores basado en Result y verificaciones en runtime en modo seguro
Personalmente, echo de menos la sobrecarga de funciones, parámetros por defecto y retorno de tuplas
ResultoExpectedse le llame OptionalNo debería significar “T o vacío”, sino “T o E”, así que el nombre parece incorrecto
Enlace a la documentación relacionada
Option<T>oResult<T, E>El tipo de error está limitado a un único código entero, lo que encaja muy bien con la filosofía de “evolución, no revolución”
La sintaxis
type?también es intuitivaEs un diseño que mantiene el significado de C mientras reduce la carga de los out param
Resultya tiene el significado común de valor de retorno, así que podría generar confusiónPlaylist de YouTube
Me impresionó que, más que competir entre sí, las tres lenguas mantienen una relación donde comparten y aprenden de sus trade-offs
En cambio, añade funciones como macros y reflexión
Ocupan memoria equivalente al tipo más grande y desplazan el flujo hacia verificaciones de tipo en runtime, con lo que se pierde la ventaja de un lenguaje con tipado estático
Me parece mejor implementarlas manualmente cuando hagan falta
He implementado por mi cuenta genéricos, slices y propagación de errores en C, pero hacer un compilador es demasiado complejo
Por eso alterno entre variantes de C y Go
La barrera de entrada es tan baja que incluso podrías hacer un prototipo en un solo día
Es la única forma de volver realidad un nuevo paradigma
Como un lenguaje tiene que coordinar sintaxis, biblioteca estándar, tooling y runtime, es difícil, pero por eso mismo su impacto en el futuro es grande
Gracias a LLVM pudo crear un compilador nuevo por sí mismo
Una variante de C usada en solitario está bien, pero para colaborar con otros o usar bibliotecas externas hace falta un lenguaje común
Y me parece simpático e ingenioso que a las excepciones las llame “Excuses”
En especial, que haya un enlace a Discord en la navegación refuerza esa impresión