Changelog vivo de V++, el lenguaje de México. Cada hito se verifica con la suite completa antes de anunciarse — nada se afirma sin prueba en vivo.
1 · AGO · 2026
El runtime portable pasa de 110 a 127 primitivas
V++ ya sostiene servicios con sesión, y seis más dejan Node
Hasta hoy V++ servía páginas muy bien y conversaba mal. Un servicio que necesitara hablar con otro tenía que rebanar la respuesta con indice y subcadena, y armar la suya pegando comillas a mano: las dos cosas se rompen en cuanto el texto de una persona trae una comilla o un salto de línea. Y ninguno podía leer una cookie, porque el manejador recibía ruta, método y cuerpo, y nada más. En la práctica eso significaba que ningún servicio con sesión podía ser V++.
Entran diecisiete primitivas en el runtime portable —el que sirve vpp.ceoo.world, el enjambre y el motor espacial—: json_analizar y json_texto para leer y escribir JSON con el escapado hecho por el runtime; booleano, porque V++ representa lo cierto con 1 y al serializar salía {"ok":1} —funciona por casualidad, pero no es el mismo documento que {"ok":true}, y un contrato de API se cumple al pie de la letra—; http_cabecera y peticion_cabecera para poner y leer cabeceras; tiempo_unix y un tope de espera por llamada, que es lo que necesita un cortacircuitos; y la firma de sesión del ecosistema.
Las cabeceras se guardan por hilo. El servidor atiende varias peticiones a la vez, y una lista compartida mezclaría la cookie de un visitante con la de otro: eso no es una molestia, es una fuga de sesión. Verificado con veinte peticiones concurrentes, cada una con su propia cookie: veinte de veinte recibieron la suya.
Sobre la firma: HUUN'AB-512 sigue siendo la primitiva soberana de CEOO para todo lo que nace aquí. Pero una cookie que ya circula por todos los subdominios tiene un formato dado, y cambiarlo cerraría de golpe todas las sesiones abiertas. Hablar el formato que ya existe no es renunciar a nada: es la condición para que un servicio con sesión pueda ser V++. Se comprobó contra el vector oficial del RFC 4231 —comprobar una implementación contra sí misma no prueba nada, solo que es consistente con su propio error— y contra el servicio real: V++ acuña un token idéntico al que acuñaba el servidor anterior, valida el que aquel emitió y rechaza uno alterado.
Con eso migraron seis servicios más: ÍKORA (el diario que responde), los tres del comparador de diseño, el borde de Final Vibe y OBSIDIANA, que es el primero con sesión escrito en V++. Ninguno se dio por bueno sin comparar contra el que sustituía: Final Vibe salió idéntico en 20 de 21 rutas —código, bytes, huella del cuerpo, tipo y cache— con la política de contenido igual letra por letra, porque un solo origen de menos en esa cabecera deja a gente real sin poder entrar. OBSIDIANA se probó además con sesión alterada y con sesión caducada: las dos denegadas, igual que antes. Un porte que aceptara cualquiera de las dos habría abierto el contenido reservado a cualquiera, y ninguna prueba de portada lo habría detectado.
Tres fallos encontrados por el camino, y los tres eran nuestros y del mismo día: la cabecera Content-Type pedida por el manejador se duplicaba en vez de sustituir a la del runtime, las cabeceras salían solo en el camino feliz —así que un 404 perdía la identificación del servicio— y .webmanifest no estaba en la tabla de tipos, de modo que el manifiesto de una aplicación instalable salía como binario genérico y el navegador podía ignorarlo. Los tres aparecieron al comparar contra el servidor que se estaba sustituyendo, que es exactamente para lo que sirve comparar.
Las guardas permanentes pasan de 21 a 29: doce en el compilador nativo, ocho en el runtime portable y nueve en el intérprete. Una de ellas detectó sola un cambio de formato hecho a propósito y sin anotar, que es justo su trabajo.
31 · JUL · 2026
Paquetes: el registro público pasa de 17 a 51
El comando vpp publica ahora publica de verdad
Al revisar el registro de paquetes apareció una diferencia incómoda: vpp.ceoo.world servía 17 paquetes mientras el registro local tenía 50. Treinta y tres paquetes llevaban tiempo dándose por publicados sin estar en línea. La causa era simple y poco honrosa: el comando regeneraba el registro local y luego imprimía una nota diciendo que el despliegue en línea lo hacía otro proceso. No lo hacía nadie.
Un comando que se llama publica tiene que publicar. Ahora copia el registro a la carpeta que sirve el sitio, únicamente los archivos que cambiaron, y avisa si no pudo escribir en lugar de callarse. Antes de poner los 33 en línea se comprobó que los 50 compilan — ninguno falla —, porque no se publica código roto. El registro público quedó en 51 paquetes.
El paquete 51 es temperatura, conversión entre grados Celsius, Fahrenheit y Kelvin, que trabaja en centésimas de grado para no depender de decimales. Sirvió además para probar las dos rutas del comando: crear lo pone en línea al momento, y actualizar propaga la versión hasta el índice público. Se verificó que funciona, no solo que compila: ocho casos, incluido el punto donde -40 °C = -40 °F.
31 · JUL · 2026
Módulos: un importa mal escrito ya no se ignora
Los errores de importación se ven donde ocurren, no tres archivos después
V++ tiene módulos desde hace tiempo —importa "archivo.vpp", con rutas relativas y detección de ciclos—, pero un nombre de archivo mal escrito no producía ningún error. El programa seguía adelante sin el módulo y reventaba mucho más tarde con un «función no definida» en otro archivo y con el número de línea equivocado, porque para entonces el import ya se había incorporado al texto.
Ahora se avisa en el momento, nombrando el archivo pedido y la ruta exacta donde se buscó. Es la clase de detalle que no se nota hasta que se empieza a repartir el código en módulos de verdad; entonces vale media hora de búsqueda cada vez.
31 · JUL · 2026
Entorno: sistema_entorno en todos los intérpretes
Leer una variable de entorno ya no depende de qué intérprete uses
La función existía en algunos intérpretes de V++ y faltaba en otros. La consecuencia práctica no era teórica: sin ella, un programa no puede averiguar cuál es la carpeta del usuario que lo ejecuta, así que termina con rutas escritas a mano en el código y solo funciona en el equipo donde se escribió.
Se añadió a los dos intérpretes que no la tenían, con la misma firma en todos: sistema_entorno(nombre), y un segundo argumento opcional con el valor por omisión si la variable no existe. La batería completa de pruebas da resultados idénticos antes y después del cambio.
19 · JUL · 2026
Robustez: convertir número a texto por sí solo
Programas mínimos como escribe numtexto(42) ya compilan a binario
Corrección de robustez encontrada barriendo patrones sencillos: una línea tan básica como escribe numtexto(42) (convertir un número a texto y mostrarlo), o mostrar las claves/valores de un diccionario por sí solos, fallaba al generar el binario cuando era lo único que hacía el programa. La razón era interna —esas operaciones escriben en la memoria de trabajo pero no avisaban que la necesitaban, así que faltaban unas piezas al ensamblar—; en cuanto la misma operación se combinaba con otra (como "total: " + numtexto(n)) sí funcionaba, por eso no se había notado.
Ahora cada una de esas operaciones declara correctamente lo que necesita y los programas mínimos compilan sin problema. Se fijó con una batería que compila, ensambla, enlaza y ejecuta cada caso suelto contra el intérprete de referencia. Un detalle pequeño, pero es justo el tipo de línea que escribe alguien que está aprendiendo el lenguaje: tenía que funcionar.
19 · JUL · 2026
Cierre de la familia: comparaciones dentro de cálculos
Usar una comparación dentro de una cuenta ya funciona — (a > b) + 1, 2 * (a == 5)
Cuarta y definitiva corrección de la familia: cuando una comparación o una condición lógica va entre paréntesis dentro de un cálculo —por ejemplo (a > b) + 1, que suma 1 si a es mayor que b, o 2 * (a == 5)—, el resultado (1 o 0) debe entrar en la operación. Antes se descartaba y el cálculo tomaba solo el primer valor; ahora se resuelve el paréntesis primero y su resultado alimenta correctamente la suma, resta o multiplicación. Es un patrón muy útil: contar cuántas condiciones se cumplen sumándolas, activar un factor solo si algo es cierto, etc.
Con esto queda cerrada por completo la familia de correcciones sobre «usar una comparación como un valor»: compararla directamente, combinarla con y/o/no, encadenarla en un rango, y —ahora— usarla dentro de un cálculo. Cuatro errores de raíz de la misma naturaleza, detectados y cerrados uno tras otro tirando del mismo hilo, cada uno blindado con cientos de programas al azar contra dos motores de referencia y cero resultados incorrectos. La solidez no se declara: se demuestra caso por caso.
19 · JUL · 2026
Y el tercero de la familia: comparaciones encadenadas
Rangos como 0 <= x < 10 ya se evalúan correctamente
Tercera y última corrección de la misma familia: las comparaciones encadenadas —escribir dos o más comparaciones seguidas, como 0 <= x < 10 para «¿está x en el rango?»— también se descartaban. Ahora se evalúan con la semántica exacta del lenguaje, verificada contra sus dos motores de referencia: V++ las resuelve de izquierda a derecha (cada comparación da verdadero/falso, que entra en la siguiente), y el binario nativo hace ahora exactamente lo mismo, tanto al usarlas como resultado como dentro de un «si» o un «mientras».
Para lograrlo se robusteció el analizador de comparaciones para que respete los paréntesis al separar los operandos —una mejora que endurece todo el manejo de condiciones, no solo este caso—. Se blindó con doscientas cincuenta cadenas de comparaciones al azar de dos a cuatro eslabones, en tres contextos distintos, contra dos motores independientes, con cero resultados incorrectos. Tres errores de raíz de la misma familia —comparar, combinar con y/o/no, y encadenar— detectados y cerrados uno tras otro: el rigor de tirar del hilo hasta el final.
19 · JUL · 2026
Y su hermano: la lógica «y / o / no» ya vale como resultado
Combinar condiciones como resultado ahora es correcto — regresa x > 0 y x < 10
Tirando del mismo hilo de la corrección anterior, se encontró y reparó el error hermano: los conectores lógicos «y», «o» y «no» usados como resultado —no dentro de un «si», sino como lo que una función devuelve o lo que se imprime— también se descartaban. Una función regresa x > 0 y x < 10 (¿está en el rango?) devolvía x en vez de verdadero/falso. Ahora combinar condiciones da correctamente 1 (verdadero) o 0 (falso), con la semántica exacta del lenguaje (verdad por «no es cero»), en todos los contextos: al devolverla, imprimirla o guardarla.
De paso se cerró una ambigüedad de interpretación: no (algo) se confundía con la llamada a una función llamada «no»; ahora se entiende siempre como la negación lógica que es. La corrección se blindó con trescientos programas al azar que anidan «y/o/no» con comparaciones y paréntesis de todas las formas, contrastados contra dos motores de referencia, con cero resultados incorrectos. Dos errores de raíz de la misma familia, cazados y cerrados en secuencia: así se construye un compilador en el que se puede confiar.
19 · JUL · 2026
Corrección de fondo: las comparaciones ya valen como resultado
Preguntar «¿es mayor?» ahora da la respuesta correcta como valor — regresa a > b, es_par = n % 2 == 0
Se detectó y corrigió un error de fondo importante en el compilador propio: usar una comparación como resultado —no dentro de un «si» o un «mientras», sino como el valor que una función devuelve o que se imprime— descartaba en silencio la comparación. Por ejemplo, una función regresa a > b devolvía a en vez de verdadero/falso; es_par = n % 2 == 0 devolvía n % 2. La pregunta se hacía, pero la respuesta se perdía. Ahora una comparación produce correctamente 1 (verdadero) o 0 (falso) en todos los contextos —al devolverla, imprimirla, guardarla en una variable, pasarla como argumento o meterla en una lista— y funciona con números enteros, decimales y texto.
La corrección se verificó con extremo rigor: trescientos programas al azar que usan comparaciones de todas las formas posibles, contrastados contra dos motores de referencia independientes, con cero resultados incorrectos. Y, como consecuencia directa, dos bibliotecas más cruzaron al binario propio —números aleatorios (con secuencia reproducible) y fechas—, elevando la biblioteca estándar que compila a binario idéntico al intérprete a 31 módulos. Corregir un error de raíz no solo repara: desbloquea.
19 · JUL · 2026
Listas de listas de palabras — ya se muestran completas
El binario nativo muestra listas anidadas de texto — [['hola', 'mundo'], ['x']]
El compilador propio completa el trío de listas dentro de listas: ya mostraba listas anidadas de números ([[1, 2], [3, 4]]) y de tipos combinados; ahora también las de palabras —[['hola', 'mundo'], ['x']]—, idéntico al intérprete. Es la forma natural de agrupar: filas de una tabla de texto, palabras separadas por frase, categorías con sus elementos. El binario recorre la estructura de dos niveles y escribe cada palabra entre comillas, en su lugar exacto.
Como siempre, la disciplina de seguridad primero: un caso límite —mezclar un grupo vacío con grupos de palabras— se detiene con un aviso claro en lugar de arriesgar una salida incorrecta, porque un grupo vacío es, en el momento de compilar, indistinguible de uno de números. Doscientas listas anidadas al azar verificadas, cero resultados incorrectos. Se prefiere siempre un error honesto a un dato equivocado.
19 · JUL · 2026
Diccionarios que mezclan texto y números — ya se guardan y se muestran
El binario nativo maneja diccionarios de valores combinados — {"nombre": "Ana", "edad": 30}
Nueva capacidad en el compilador propio: un diccionario (una tabla de clave → valor) donde unas entradas guardan texto y otras guardan números —por ejemplo {"nombre": "Ana", "edad": 30}— ahora se compila a binario y se muestra idéntico al intérprete. También se puede consultar un valor por su clave y obtener lo correcto según el caso (el texto o el número), e incluso pedir una clave que no existe y recibir 0, igual que la referencia. Es la estructura más común de la programación real: una ficha con campos de distintos tipos.
La clave técnica fue enseñarle al compilador a anticiparse: como el diccionario se arma entrada por entrada, primero revisa todo el diccionario para saber que va a mezclar tipos, y así guarda cada valor con una pequeña etiqueta que dice si es texto o número. Al mostrarlo, esa etiqueta le indica cómo escribir cada campo. Y se mantuvo la regla de oro: los casos que aún no soporta (llevar uno de estos valores a una variable suelta, o mezclar también decimales) se detienen con un aviso claro en lugar de arriesgar un resultado incorrecto. Se verificó con doscientos diccionarios mixtos al azar, cero resultados incorrectos. Con esto se levanta el primer obstáculo para compilar la biblioteca de JSON —el formato universal de intercambio de datos— a binario propio.
19 · JUL · 2026
Una biblioteca completa cruza al binario gracias a los datos flexibles
La biblioteca de conteo de frecuencias ya compila entera a binario propio — 29 de 29
Hito de fondo: por primera vez, el trabajo de datos flexibles (valores que llevan su tipo consigo) desbloquea una biblioteca real completa. La biblioteca de frecuencias —que cuenta cuántas veces aparece cada elemento en una lista, arma tablas de pares valor-conteo ordenadas, y halla el más frecuente— ahora se compila entera a binario nativo, produciendo resultados idénticos al intérprete. Su función central devuelve una tabla ([["a", 3], ["b", 2], ["c", 1]]) donde cada fila mezcla texto y número: exactamente la clase de estructura que el binario aprendió a manejar en los pasos previos.
La pieza que faltaba —y que se completó— era que una función pudiera devolver una de estas tablas y mostrarla. En el camino apareció un error sutil: al mostrar el resultado de una función, el compilador podía confundir el tipo del argumento con el tipo del resultado. Se corrigió y se verificó a fondo. Con esto, la biblioteca estándar de V++ que compila a binario idéntico al intérprete pasa a 29 de 29 módulos deterministas —el primero habilitado por el frente de datos flexibles—, demostrando que ese frente, abordado paso a paso y verificado en cada incremento, ya entrega piezas reales y útiles.
19 · JUL · 2026
Tablas: listas de filas con tipos combinados
El binario nativo arma y muestra tablas — listas de filas que mezclan texto y números, [["a", 3], ["b", 2]]
El binario nativo da otro paso en estructuras de datos: puede armar una lista de filas donde cada fila mezcla texto y números —una tabla, como [["a", 3], ["b", 2]]— agregando fila por fila y mostrándola completa, idéntico al intérprete. Es el patrón típico de un conteo de frecuencias (una palabra y cuántas veces aparece) o de pares clave-valor ordenados. El compilador reconoce que cada fila lleva tipos combinados y arma la representación correcta.
Lo más valioso de este avance es cómo se encontró un error. El banco de pruebas diferencial —que compara el compilador consigo mismo— dio luz verde; pero un segundo banco, que compara contra intérpretes independientes, detectó que ciertas tablas con filas de formatos mezclados se imprimían mal. La causa: el diferencial no lo veía porque el error también existía antes. Se corrigió de raíz —esas tablas mixtas ahora se detienen con un aviso claro en lugar de arriesgar una salida incorrecta— y quedó la lección: verificar contra referencias externas, no solo contra uno mismo. Cientos de tablas al azar, cero resultados incorrectos. La disciplina que sostiene un compilador propio confiable.
19 · JUL · 2026
Y leer cada elemento de una lista mixta
El binario nativo ya lee elementos individuales de una lista con tipos combinados
Completando la pieza anterior, el binario nativo ahora también puede leer un elemento suelto de una lista que mezcla texto y números —lo que antes se detenía con un aviso—. Al pedir obtener(lista, posición) sobre una lista como ["clave", 7], el binario reconoce en tiempo de ejecución si ese elemento es texto o número y lo entrega correctamente. Con esto, una lista mixta ya se puede construir, mostrar completa y recorrer elemento por elemento, tal como en el intérprete.
Como cada paso de este frente, se verificó con un banco de pruebas diferencial —comparando el compilador con y sin el cambio sobre cientos de programas que recorren listas mixtas en bucle—: 158 casos que antes no compilaban ahora funcionan, cero regresiones. El avance sigue su método: incrementos pequeños, cada uno probado a fondo, sin apuros.
19 · JUL · 2026
Listas que mezclan texto y números
El binario nativo ya maneja listas con tipos combinados — ["a", 5]
Un salto de fondo: el binario nativo puede ahora crear y mostrar listas que mezclan tipos —texto y números en la misma lista, como ["a", 5] o [1, "x", 2]—, imprimiéndolas idéntico al intérprete (texto entre comillas, números sin comillas). Hasta ahora el binario exigía que cada lista fuera homogénea (solo números, o solo texto); esta es la primera vez que un dato lleva su propio tipo consigo en tiempo de ejecución. Es la pieza fundacional del frente más ambicioso del compilador: los valores dinámicos, que abrirán las estructuras de datos mixtas y anidadas —diccionarios de valores variados, tablas heterogéneas— que hoy solo el intérprete maneja.
Se abordó justo como debe hacerse una pieza que toca el corazón de cómo se guardan los datos: por el camino seguro (solo se activa cuando hay certeza de que la lista es mixta; las listas de un solo tipo siguen por su ruta rápida de siempre) y con la verificación más estricta de todas —un banco de pruebas diferencial que comparó el compilador con y sin el cambio sobre cientos de programas: 174 casos que antes no compilaban ahora funcionan, y cero regresiones. Y con la honestidad de siempre: lo que aún falta (leer un elemento suelto de una lista mixta) se detiene con un aviso claro en vez de arriesgar un resultado equivocado. El frente avanza, paso a paso verificado, sin apuros.
19 · JUL · 2026
Mostrar una lista de listas (una matriz)
El binario nativo ya imprime listas dentro de listas — [[1, 2], [3, 4]]
El binario nativo aprendió a mostrar estructuras anidadas: una lista que contiene otras listas —lo que en la práctica es una matriz o una tabla—. Escribir [[1, 2], [3, 4]] ahora se imprime tal cual, igual que el intérprete de referencia, respetando sublistas vacías ([]) y números negativos. Antes, mostrar una estructura anidada se detenía con un aviso; ahora se recorre de forma recursiva y se dibuja completa. Es una operación cotidiana —listar filas de datos, coordenadas, tablas— que ahora se comporta igual en desarrollo y en el binario propio.
Es, además, el primer paso del lado de "lectura" del gran frente de estructuras mixtas y anidadas: la maquinaria de impresión recursiva que se reutilizará cuando lleguen las listas y diccionarios de tipos combinados. Se hizo por el lado seguro —solo lectura de datos, sin tocar cómo se guardan—, verificado con cientos de matrices generadas al azar comparadas byte a byte contra dos intérpretes independientes: cero discrepancias, y sin afectar ninguna de las impresiones ya existentes.
19 · JUL · 2026
Preguntar de qué tipo es un dato
El binario nativo ya responde de qué tipo es un dato — tipo(5) → "entero"
El binario nativo suma la introspección de tipos: preguntar si un dato es una lista, un diccionario, texto o un número, y obtener el nombre de su tipo. Funciones como tipo(v) —que devuelve "entero", "cadena", "lista", "mapa" o "real"— y es_lista, es_cadena, es_entero, es_mapa ya funcionan idéntico al intérprete. Y hay una elegancia de diseño detrás: como el compilador ya deduce el tipo de cada dato en tiempo de compilación, estas preguntas se resuelven de antemano —la respuesta queda fijada en el binario, sin costo alguno al ejecutar—. Gracias al motor de deducción de tipos construido en jornadas anteriores, esto funciona incluso dentro de funciones cuyo parámetro se infiere del uso.
Es el primer escalón de un frente mayor —los valores capaces de llevar su tipo consigo en tiempo de ejecución, que permitirán estructuras de datos mixtas y anidadas—, y se abordó como corresponde a una pieza de fondo: con su diseño escrito primero y verificado contra el intérprete. La introspección sobre datos de tipo aún no fijado se detiene, por ahora, con un aviso claro en lugar de arriesgar una respuesta equivocada — la disciplina de siempre.
19 · JUL · 2026
Y también los valores de un diccionario, en orden
El binario nativo entrega los valores de un diccionario, en el mismo orden que sus claves
Completando el trabajo con diccionarios, el binario nativo suma ahora la operación complementaria: obtener la lista de los valores, presentados en el mismo orden alfabético de sus claves —igual que el intérprete de referencia—. Junto con la obtención de claves ya disponible, esto cierra la tríada básica para recorrer un diccionario de forma predecible: claves, valores y tamaño. Funciona tanto si los valores son números como texto, y ese orden estable —independiente del azar interno— es lo que hace que los reportes y las pruebas den siempre el mismo resultado.
Verificado con exigencia: un banco de pruebas generó cientos de diccionarios al azar, pidió sus valores en orden y comparó byte a byte contra dos intérpretes independientes —cero discrepancias— sin afectar ninguna de las funciones ya existentes. Es la última pieza de recorrido de diccionarios que faltaba en el terreno de datos homogéneos; el siguiente paso, los diccionarios con valores de tipos mezclados, ya está diseñado como su propio frente.
19 · JUL · 2026
Recorrer las claves de un diccionario, en orden
El binario nativo ya entrega las claves de un diccionario, ordenadas alfabéticamente
El binario nativo suma una pieza esencial para trabajar con diccionarios (mapas de clave→valor): obtener la lista de sus claves, y además ordenadas alfabéticamente —igual que el intérprete de referencia—. Esto permite recorrer un diccionario de forma predecible: contar frecuencias, listar valores distintos, agrupar. Y ese orden estable es una ventaja de diseño de V++: a diferencia de otros lenguajes donde el orden de las claves depende del azar interno, aquí el resultado es siempre el mismo, ideal para reportes, pruebas y firmas. Con esta pieza, una biblioteca real de conteo de frecuencias ya compila a binario propio y produce resultados idénticos al intérprete.
Al construir esta función apareció —y se corrigió— un error de fondo relacionado: al copiar un texto de una variable a otra (b = a), el binario copiaba a dónde apunta el texto pero no su longitud, dejando a veces una cadena vacía. Ahora copia el dato completo. Todo verificado con exigencia: un banco de pruebas generó cientos de diccionarios al azar —con claves acentuadas incluidas— pidió sus claves ordenadas y comparó byte a byte contra dos intérpretes independientes. Cero discrepancias. Van así varias piezas de manejo de texto y datos añadidas o corregidas en una jornada de búsqueda activa de fallos, la disciplina que sostiene un compilador propio confiable.
19 · JUL · 2026
Ordenar una lista de palabras, en el binario
El binario nativo ordena alfabéticamente una lista de textos — ordenar(["pera","uva","kiwi"]) → ["kiwi","pera","uva"]
Sobre la base de la comparación alfabética recién añadida, el binario nativo ya sabe ordenar una lista completa de palabras. Antes, ordenar una lista de textos dejaba los elementos sin cambiar —el binario comparaba las direcciones internas de memoria en lugar del contenido—; ahora los ordena de verdad, de la A a la Z, respetando además el lugar correcto de acentos y eñes. La ordenación se apoya en la comparación byte a byte del formato UTF-8, que conserva el orden natural de los caracteres, así que el resultado coincide exactamente con el intérprete de referencia. Es una operación cotidiana —listar nombres, palabras o etiquetas en orden— que ahora funciona igual en desarrollo y en el binario propio.
Como es una pieza delicada (ordenar en el sitio, comparando textos de longitud variable), se verificó con especial cuidado: un banco de pruebas generó cientos de listas al azar —de cero a siete palabras, con y sin acentos— las ordenó y comparó byte a byte contra dos intérpretes independientes. Cero discrepancias. Y con la honestidad de siempre: las operaciones de máximo y mínimo sobre listas de texto, que aún no tienen su versión alfabética, se detienen con un aviso claro en vez de arriesgar un resultado incorrecto.
19 · JUL · 2026
Ordenar palabras alfabéticamente, en el binario
El binario nativo ya compara texto por orden alfabético — "casa" < "caza"
El binario nativo aprendió a comparar palabras por orden alfabético. Hasta ahora solo sabía decir si dos textos eran iguales o distintos; ahora entiende también menor que, mayor que y sus variantes —lo que hace falta para ordenar palabras, buscar en un rango o clasificar alfabéticamente—. Antes, un programa que escribía si "casa" < "caza" funcionaba en el intérprete pero no compilaba a binario; ahora sí, y da el mismo resultado. La comparación respeta el orden correcto incluso con acentos y eñes, gracias a que el formato interno del texto (UTF-8) conserva el orden natural de los caracteres. Con esto se cierra una diferencia entre el intérprete y el binario: un mismo programa válido ahora se comporta igual en los dos.
Verificado a fondo: un banco de pruebas generó cientos de comparaciones al azar con los seis operadores (igual, distinto, menor, mayor, menor-o-igual, mayor-o-igual), sobre palabras con y sin acento, en variables y literales, contrastando byte a byte contra dos intérpretes independientes. Cero discrepancias. Es una pieza que faltaba para procesar y ordenar texto con la misma fidelidad en desarrollo y en el binario propio.
19 · JUL · 2026
El código de una letra acentuada, correcto
El binario nativo devuelve el código Unicode correcto de letras con acento y eñes — código("é") = 233
Buscando fallos en el manejo de texto con acentos, apareció otro error real: la función código —que da el número Unicode de un carácter— devolvía un valor equivocado para letras que ocupan más de un byte, como las acentuadas y la eñe. Como la é se guarda internamente en dos bytes, el binario devolvía 195 (el primer byte) en lugar de 233 (el código real de la letra). La corrección enseña al binario a decodificar la secuencia completa del carácter —sea de uno, dos, tres o cuatro bytes— para entregar el número Unicode exacto: é → 233, ñ → 241, incluso el símbolo del euro € → 8364. Es una pieza clave para procesar texto en español letra por letra, y ahora el binario propio lo hace igual que el intérprete de referencia.
Verificado con casos de una, dos y tres unidades de byte, en variables, literales y dentro de bucles, comparando byte a byte contra el intérprete: idénticos. Y sin efectos colaterales: las bibliotecas que ya usaban esta función siguen funcionando igual. Van así tres errores de manejo de texto y números detectados y corregidos en una misma jornada de búsqueda activa de fallos —la disciplina que sostiene la confianza en un compilador propio.
19 · JUL · 2026
El resto (módulo) con decimales, exacto
El binario nativo calcula bien el resto de una división con decimales — 10.0 % 4.0 = 2.0
El fuzzing —generar programas al azar para provocar fallos— destapó un error real en el módulo con decimales (el "resto" de una división, operador %). El compilador nativo estaba ignorando el operador en expresiones con decimales: al escribir 10.0 % 4.0 devolvía 10 en lugar de 2. La causa era de raíz: el analizador de expresiones decimales no reconocía el símbolo % y lo descartaba en silencio. Se corrigió en dos capas: primero, que el operador se reconozca con su precedencia correcta (igual que la multiplicación y la división); y segundo —para que el resultado sea exacto hasta el último dígito— el binario ahora usa la función matemática del sistema para calcular el resto, en vez de una fórmula aproximada que difería del intérprete en la última cifra decimal. Es la primera vez que el binario propio se apoya en una función matemática del sistema operativo, un precedente útil para futuras operaciones que exijan precisión máxima.
Verificado con exigencia: un banco de pruebas generó cientos de expresiones decimales al azar —sumas, restas, multiplicaciones, divisiones y restos, con paréntesis y anidamiento— comparando byte a byte contra dos intérpretes independientes, tanto sueltas como dentro de funciones. Cero discrepancias en los casos bien definidos. Este hallazgo llegó de buscar activamente el error, no de esperar a que apareciera: la disciplina de fuzzing es la que mantiene sólido un compilador propio.
19 · JUL · 2026
Al reescribir un texto, su largo también se actualiza
El binario nativo actualiza bien el largo de un texto cuando se reasigna — 28 bibliotecas a binario
Se corrigió un error de fondo, sutil pero de amplio alcance: al reasignar una variable con el resultado de una función que devuelve texto —por ejemplo r = reemplazar(r, "á", "a") aplicado en cadena para quitar acentos—, el binario nativo actualizaba a dónde apunta el texto pero no su largo, que se quedaba con el valor anterior. El efecto: al reescribir "áéíóú" como "aeiou" el texto se acortaba a la mitad, pero el binario seguía creyendo que medía lo de antes e imprimía caracteres de sobra al final. Un texto en V++ se guarda como un par —dónde empieza y cuánto mide—; ahora la reasignación actualiza ambos, igual que ya hacía al crearlo. La corrección aplica a cualquier reasignación con el resultado de una función que devuelve texto, listas o diccionarios, no solo a los acentos. Con esto sube a 28 el número de módulos de la biblioteca estándar que compilan a binario idéntico al intérprete, incluida otra pieza de la biblioteca de texto.
Verificado con la exigencia de siempre: un banco de pruebas generó cientos de cadenas al azar y les aplicó reescrituras encadenadas —reemplazos, recortes, mayúsculas y minúsculas, incluyendo letras acentuadas y eñes que ocupan dos bytes— comparando byte a byte, y midiendo también el largo exacto, contra dos intérpretes independientes. Cero discrepancias. Es la clase de detalle invisible que, corregido a fondo, hace que el binario propio se comporte exactamente como el programa original.
19 · JUL · 2026
Condiciones con paréntesis, exactas
El binario nativo evalúa condiciones agrupadas como mientras a < n y (es espacio o es tabulación) igual que el intérprete — 27 bibliotecas a binario
Se corrigió una pieza delicada y muy usada: las condiciones lógicas con paréntesis. Cuando un programa escribe algo como mientras queden datos y (es espacio o es coma), el binario nativo ahora evalúa el grupo entre paréntesis exactamente como el intérprete de referencia. Antes, un grupo (A o B) dentro de una condición mayor se tomaba por error como una sola comparación —solo miraba la primera parte—, así que ciertos bucles se detenían antes de tiempo o ciertas decisiones salían al revés. También se afinó la precedencia: no X o Y significa (no X) o Y, y A o B y C significa A o (B y C), igual que en matemáticas y en los lenguajes maduros. El motor de condiciones se reescribió por dentro como un análisis recursivo que entiende cualquier nivel de anidamiento de y, o, no y paréntesis, con cortocircuito. Con esta corrección sube a 27 el número de módulos de la biblioteca estándar que compilan a binario idéntico al intérprete, incluida la biblioteca de texto.
Y como siempre, con verificación exhaustiva: un banco de pruebas generó 800 condiciones al azar —anidando paréntesis, y, o y no de todas las formas posibles— y las probó tanto en un si como en un mientras, comparando byte a byte la salida del binario contra dos intérpretes independientes. El resultado: cero discrepancias. Es la clase de detalle invisible que, cuando falla, hace que un mismo programa se comporte distinto en el binario que en desarrollo; corregirlo de raíz es lo que hace confiable a un compilador propio.
19 · JUL · 2026
El compilador deduce qué guarda cada lista
El binario nativo sabe si una lista lleva texto o números — y así une, recorre y muestra sus elementos bien — 26 bibliotecas a binario
El compilador nativo dio un paso más de madurez: ahora no solo deduce que un parámetro es una lista, sino qué tipo de elementos lleva dentro. Cuando una función recibe una lista y la recorre —por ejemplo, una que une sus elementos con un guion—, el compilador mira desde dónde se la llaman: si en todos los sitios se le pasa una lista de texto, deduce que sus elementos son texto y genera el binario que los une correctamente (a-b-c) en vez de imprimir números internos sin sentido. Lo mismo cuando una lista viene de otra función —por ejemplo, la que parte un texto por comas—: el compilador arrastra ese conocimiento hasta quien la usa. Con esta pieza suben a 26 los módulos de la biblioteca estándar que compilan a binario nativo idéntico al intérprete, sumando el manejo de matrices y de archivos CSV.
Y, fiel a la disciplina de siempre, se hizo con la máxima exigencia. Primero, una guarda de seguridad: el compilador solo aprovecha este atajo cuando tiene certeza del tipo; ante la duda, se abstiene y prefiere un aviso claro antes que un resultado equivocado. Segundo —y más importante— este trabajo destapó un error preexistente: si una misma función se llamaba unas veces con listas de texto y otras con listas de números, el binario podía imprimir basura. En vez de dejarlo pasar, se corrigió de raíz: ahora esa situación imposible de resolver se detiene con un error claro, nunca con una salida incorrecta. Todo se validó con un banco de pruebas diferencial sobre cientos de programas generados al azar —incluidos los diseñados para engañar a la deducción—: cero casos en que un programa correcto pasara a incorrecto, cero errores convertidos en resultados equivocados, y decenas de programas que antes fallaban ahora funcionan. Así se construye un compilador propio en el que se puede confiar.
19 · JUL · 2026
El compilador sigue el rastro de los datos
Deducción de tipos siguiendo el flujo de los datos entre funciones — 21 bibliotecas a binario
El compilador nativo alcanza un nivel de inteligencia que antes se reservaba a lenguajes maduros: seguir el rastro de un dato a través del programa. Ahora, cuando una función recibe algo cuyo tipo no revela por sí misma —por ejemplo, mide su tamaño y nada más—, el compilador mira de dónde viene el dato que se le pasa: si esa variable se creó como una lista (o vino de una función que devuelve una lista), deduce que el parámetro es una lista y genera el binario correcto. Con esta pieza suben a 21 los módulos de la biblioteca estándar que compilan a binario nativo idéntico al intérprete, entre ellos colecciones y ordenamientos. Es la clase de análisis —seguir el origen de cada variable a través de las llamadas— que sostiene los sistemas de tipos de los lenguajes de sistemas. Y, como corresponde a una pieza tan delicada, se verificó con la máxima exigencia: un banco de pruebas diferencial comparó el compilador con y sin la mejora sobre cientos de programas generados al azar —incluidos casos con variables reasignadas a distintos tipos, diseñados para engañar a la deducción—. El veredicto: cero casos en que un programa correcto pasara a incorrecto, cero en que un error se volviera un resultado equivocado, y diecinueve programas que antes fallaban ahora funcionan. Cuando la deducción no puede probar el tipo con certeza, no adivina: se abstiene. Así se construye un compilador propio en el que se puede confiar.
19 · JUL · 2026
Listas y diccionarios se imprimen completos
El binario nativo imprime listas y diccionarios de números o de texto, igual que el intérprete
Se completa una pieza de ergonomía muy usada: mostrar estructuras de datos. El compilador nativo ya imprime, tal como lo hace el intérprete de referencia, listas de números ([1, 2, 3]), listas de texto (['hola', 'mundo']), diccionarios de números ({'a': 1, 'b': 2}) y diccionarios de texto ({'ciudad': 'Ñuñoa'}) —con sus corchetes, llaves, comillas y comas exactas, incluidos acentos y eñes, y reflejando los cambios al agregar o quitar elementos—. Antes, el binario no sabía imprimir estas estructuras directamente. Todo verificado byte a byte contra el intérprete. Y con la disciplina de siempre: el único caso que aún no genera —listas dentro de listas, que requiere un formato anidado— avisa con un error claro en vez de arriesgar una impresión incorrecta. Es un detalle pequeño y cotidiano, pero es justo la clase de fidelidad que hace que un mismo programa se comporte igual en desarrollo y en el binario propio.
19 · JUL · 2026
Imprimir una lista, tal cual
El binario nativo ya imprime listas de números como el intérprete: [1, 2, 3]
Un detalle cotidiano que faltaba: mostrar una lista de números. Ahora escribe mi_lista imprime [1, 2, 3] —con sus corchetes, comas y espacios, y también [] para la vacía o [-1, 2, -3] con negativos— exactamente igual que el intérprete de referencia, y refleja los cambios si se le agregan o quitan elementos. Antes, el compilador nativo no sabía imprimir una lista directamente. Y con el cuidado de siempre: si la lista contiene texto o listas anidadas —un formato más elaborado que aún no genera— el compilador avisa con un error claro en vez de arriesgar una impresión incorrecta. Es una pieza pequeña pero visible, y además habilita el siguiente paso de deducción de tipos con total seguridad.
19 · JUL · 2026
El compilador deduce por cómo se llama
Deducción de tipos a partir de la forma de llamar: 17 bibliotecas de la estándar a binario
El compilador nativo da un paso importante en su inteligencia: cuando una función no revela el tipo de un parámetro por su cuerpo —por ejemplo, una que repite un texto uniéndolo consigo mismo—, ahora mira cómo se la llama. Si en todos los sitios se le pasa un texto, deduce que el parámetro es texto y genera el binario correcto. Con esta pieza suben a 17 los módulos de la biblioteca estándar que compilan a binario nativo y coinciden byte a byte con el intérprete de referencia. Lo esencial no es solo la cobertura, sino cómo se verificó: para asegurar que esta deducción nunca produzca un resultado incorrecto, se construyó un banco de pruebas adversarial que compara el compilador con y sin la mejora sobre cientos de programas generados al azar —incluidos casos diseñados para engañarlo—. El veredicto fue tajante: cero casos en que un programa correcto pasara a incorrecto, cero en que un error se volviera un resultado equivocado, y ochenta programas que antes fallaban ahora funcionan. Además, el propio banco adversarial descubrió y permitió corregir un caso límite (comparar un texto con un número) antes de dar por buena la mejora. Así se construye una plataforma propia confiable: cada avance de inteligencia del compilador se somete a un intento honesto de romperlo, y solo se acepta si sobrevive.
19 · JUL · 2026
Anotaciones de tipo, también a binario
Escribe los tipos como prefieras: funcion f(n: entero) -> entero ya compila a binario
V++ deja escribir los tipos de dos maneras, y ahora ambas llegan a binario nativo. Además del estilo con espacio, el compilador nativo entiende la anotación con dos puntos y flecha —funcion doble(n: entero) -> entero:— familiar para quien viene de otros lenguajes tipados. Los parámetros pueden llevar su tipo (entero, cadena, real, lista, mapa) y la función su tipo de retorno, exactamente como ya lo aceptaban los intérpretes. Con esto sube a catorce el número de módulos de la biblioteca estándar que compilan a binario y coinciden byte a byte con el intérprete de referencia. Es libertad de estilo sin costo: se escribe como resulte natural y el resultado es el mismo binario propio que arranca al instante.
19 · JUL · 2026
El compilador también deduce el texto
Funciones de texto sin anotaciones ya compilan a binario: 13 bibliotecas de la estándar
El compilador nativo extiende su capacidad de deducir tipos por el uso: además de listas y diccionarios, ahora reconoce cuándo un parámetro es texto —porque la función lo recorre carácter por carácter, saca una subcadena o lo transforma— y genera el binario correcto sin que haga falta declararlo. Así, utilidades de texto escritas de forma natural (invertir una palabra, contar caracteres, formatear) compilan a binario nativo tal como están. Con esta pieza, ya son 13 módulos de la biblioteca estándar los que compilan a binario y dan el mismo resultado que el intérprete de referencia, entre ellos estadística y ordenamientos. Y con el rigor de siempre: al ampliar la deducción apareció un caso límite —un dato de lista escondido dentro de otra llamada dejaba de reconocerse— que la verificación adversarial detectó y se corrigió en el acto, con una prueba que lo blinda para el futuro. Cobertura honesta y creciente, medida programa por programa y verificada contra el intérprete.
19 · JUL · 2026
Más bibliotecas reales, a binario
Módulos de la biblioteca estándar compilan a binario nativo, tal como están escritos
Con las piezas recientes —entender importa, deducir los tipos de lista y diccionario, y ahora aceptar más formas naturales de escribir— varios módulos de la biblioteca estándar de V++ ya compilan a binario nativo sin retocarlos: números binarios, secuencias, listas, utilidades matemáticas, el calendario maya. Antes, ninguna de estas bibliotecas —escritas en varios archivos y sin anotaciones de tipo— llegaba a binario; hoy varias lo hacen y dan exactamente el mismo resultado que el intérprete de referencia. Dos ajustes de ergonomía lo destrabaron: imprimir directamente el resultado de una operación (por ejemplo escribe(a + b)) y aceptar los paréntesis de agrupación como es natural. Y con una regla de la casa: ante cualquier caso que el compilador aún no sepa resolver con certeza, avisa con un error claro en vez de arriesgar un resultado incorrecto. Es avance de cobertura honesto —no todo compila aún—, medido programa por programa: se dice cuántos entran y cuáles faltan, y cada uno se verifica contra el intérprete.
19 · JUL · 2026
Menos ceremonia: el compilador deduce
Funciones que reciben listas y diccionarios sin declararlo: el compilador lo deduce por el uso
El compilador nativo ahora es más inteligente al leer tu código. Antes, para compilar a binario una función que recibía una lista o un diccionario, había que declararlo explícitamente; el intérprete no lo exigía, así que muchas bibliotecas escritas de forma natural no llegaban a binario. Ya no hace falta: si una función usa un parámetro como lista —le agrega, consulta o quita elementos— o como diccionario —guarda y busca por clave—, el compilador lo deduce por el uso y genera el binario correcto. La deducción es prudente: solo concluye cuando la señal es inequívoca (una operación que solo tiene sentido sobre una lista, o sobre un diccionario); ante la duda no adivina, avisa. Con esto, bibliotecas reales escritas sin ceremonia —como el módulo de listas de la biblioteca estándar— compilan a binario nativo y dan el mismo resultado que el intérprete de referencia. Es la continuación natural de entender importa: primero reunir los módulos, y ahora compilarlos aunque no lleven anotaciones de tipo. Menos fricción para quien escribe, sin perder la exactitud.
19 · JUL · 2026
Programas en varios archivos, a binario
El compilador nativo ya entiende importa: programas repartidos en módulos compilan a binario
Hasta ahora, el compilador que produce binario nativo solo aceptaba programas de un único archivo. Ya no: entiende importa "modulo.vpp" y reúne los módulos antes de compilar, igual que lo hace el intérprete de referencia. Un programa repartido en varios archivos —una biblioteca de utilidades aquí, un módulo de datos allá, y el programa principal que los usa— se compila a un solo binario propio. Funciona con módulos que a su vez importan otros módulos, y si el mismo módulo llega por dos caminos distintos, se incluye una sola vez (sin duplicar ni chocar). Si falta un módulo, el error es claro y temprano, no un fallo oscuro. Está verificado de forma exigente: un programa modular compilado a binario da el mismo resultado que el intérprete de referencia, y su versión reunida en un archivo coincide en los tres motores. Es una pieza de fontanería imprescindible para lo que viene: llevar bibliotecas reales —no solo ejemplos de un archivo— a binario nativo que arranca al instante.
19 · JUL · 2026
Diccionarios genéricos en binario
Diccionarios reutilizables —una definición que guarda números o texto— compilados a binario nativo
Se completa la familia de estructuras de datos reutilizables del compilador nativo. Ya estaban la pila y el ordenamiento con contrato de tipo; ahora se suma el diccionario genérico: una tabla que asocia una clave (texto) con un valor, escrita una sola vez y válida para valores que son números o que son texto, cada versión compilada a binario propio. Guardar, consultar, preguntar si existe una clave y medir el tamaño funcionan igual pasando el diccionario entre funciones —incluida una función que crea y devuelve un diccionario nuevo y otra que lo llena, viendo el resultado desde donde se llamó—. El texto se maneja completo, con acentos y eñes (probado con “Ñuñoa” y “México”). Antes, un diccionario de texto pasado a otra función devolvía un valor equivocado al compilar; ahora el compilador rastrea el tipo del valor a través de las funciones y lo hace bien. La prueba, como siempre, no es de palabra: guardar y leer en números y en texto da exactamente el mismo resultado en los tres motores —compilador nativo e intérpretes—, byte por byte. Con esto, las tres estructuras de datos más usadas —listas, pilas y diccionarios— viven como binario nativo que arranca al instante, sin intérprete debajo.
18 · JUL · 2026
Blindaje: miles de programas al azar
Un generador de programas aleatorios blinda las estructuras de datos reutilizables y la impresión de texto
Cada capacidad nueva se blinda, no solo se anuncia. Se añadió un generador que crea cientos de programas al azar —cada uno usa contenedores de números o de texto, los pasa entre funciones, los modifica y los imprime de todas las formas posibles— y verifica que los tres motores de V++ dan exactamente el mismo resultado, comparando la salida tal cual, sin ninguna concesión (ni siquiera en los saltos de línea, justo donde se había escondido antes un fallo). Trescientos programas generados, cero divergencias. Así, lo que hoy funciona no depende de unos pocos ejemplos escritos a mano: queda protegido por prueba aleatoria y automática, de modo que cualquier regresión futura se detecta de inmediato. La confianza en una plataforma propia se construye con esta disciplina: demostrar y blindar, no afirmar.
18 · JUL · 2026
Contratos de tipo que compilan a binario
Un algoritmo genérico con requisito de tipo verificado —ordenar cualquier cosa comparable— compilado a binario nativo
El compilador nativo da un paso más en su historia de código reutilizable: ahora un algoritmo genérico puede exigir que el tipo con el que se use cumpla un contrato —al estilo de los “traits” de Rust o las “interfaces” de Go— y ese requisito se verifica antes de generar el binario. El ejemplo es un ordenamiento único que sirve para cualquier tipo que sepa compararse: se escribe una sola vez, declara “necesito que el tipo sea ordenable”, y a partir de ahí ordena números, puntos con clave o palabras de texto —cada versión compilada a un binario propio que arranca al instante. La comparación de cada tipo se resuelve en el momento de especializar, sin costo en ejecución. Lo importante es la garantía: si alguien intenta usar el algoritmo con un tipo que no cumple el contrato —le falta una de las operaciones exigidas—, la herramienta lo rechaza con evidencia y no genera código roto, en vez de fallar de forma oscura más tarde. Y no es solo para números: ordenar palabras —texto, con sus acentos— dentro del binario funciona igual, uniendo en una sola pieza los contenedores de texto y los contratos de tipo. La prueba, como siempre, no es de palabra: ordenar números y palabras da exactamente el mismo resultado en los tres motores —compilador nativo e intérpretes—, byte por byte, y el rechazo de un tipo que no cumple está verificado. Cuarenta baterías de pruebas en verde. Es la base de las bibliotecas reutilizables y seguras: escribir un algoritmo una vez, con su contrato explícito, y confiar en que el compilador impide usarlo mal.
18 · JUL · 2026
Genéricos que compilan a binario
Estructuras de datos reutilizables —una pila que sirve para números y para texto— compiladas a binario nativo
El compilador nativo ya produce binario propio a partir de estructuras de datos genéricas: se escribe una sola vez una pila —o una cola, o cualquier contenedor— y sirve por igual para números y para texto, sin reescribirla para cada tipo. Es lo que en otros lenguajes se llama “genéricos” o “plantillas”; en V++ una herramienta especializa la definición única en versiones concretas y cada una compila a un binario que arranca al instante, sin intérprete debajo. Faltaba el caso del texto: sacar una palabra guardada en un contenedor y usarla como cadena de pleno derecho ya funciona en el binario, con acentos y eñes correctos. Al verificar esto —intentando refutar el propio resultado antes de darlo por bueno, como manda la casa— apareció un fallo de solidez que llevaba tiempo oculto: al imprimir texto, el binario nativo no añadía el salto de línea que los dos intérpretes sí ponían; estaba enmascarado porque las pruebas comparaban ignorando precisamente los saltos de línea. Se corrigió de raíz y se añadió una prueba que compara la salida cruda, sin normalizar, para que no vuelva a esconderse. Resultado: una pila genérica de números y de texto da exactamente el mismo resultado en los tres motores, byte por byte, y la batería nativa completa —treinta y nueve baterías, incluido el compilador auto-compilándose— sigue en verde. La reutilización no cuesta rendimiento: la abstracción vive en el código fuente y desaparece en el binario.
18 · JUL · 2026
Números y texto, sin fricción
Números decimales en listas y diccionarios, y texto que se mezcla con números sin ceremonia
Dos mejoras de ergonomía llegan al compilador nativo, alineándolo con la forma natural de escribir. Primera: las listas y diccionarios ahora guardan números decimales —no solo enteros— y los devuelven intactos, incluso al sumarlos o recorrerlos; una tabla de precios o de mediciones se escribe sin rodeos. Segunda: al construir texto, los números se combinan con las cadenas directamente —"total: " + 42 produce total: 42, y lo mismo con decimales— sin necesidad de convertir a mano; funciona con variables, resultados de funciones y elementos de una lista, y en cualquier posición. Ambas cosas ya se comportaban así en los intérpretes; ahora el binario nativo propio hace exactamente lo mismo, byte por byte. La verificación no es de palabra: fuzzers diferenciales generan miles de programas que mezclan números, texto, listas y diccionarios, y comparan los tres motores en cada uno. Menos ceremonia para quien escribe, cero divergencia entre desarrollo y producción.
18 · JUL · 2026
Tres motores, un solo resultado
Tres motores de V++ que coinciden byte por byte — verificado por fuzzing diferencial
V++ corre en tres motores independientes —un compilador que produce binario nativo, y dos intérpretes escritos por separado— y ahora los tres dan exactamente el mismo resultado, byte por byte, en las áreas centrales del lenguaje: aritmética, texto con acentos y Unicode, listas y diccionarios (de números, texto y anidados), condicionales y bucles, funciones con recursión, y —lo más reciente— la impresión de números decimales. Esto último cerró la última diferencia: los decimales se imprimen en su forma más corta y exacta, idéntica en los tres motores, tal como lo haría cualquier lenguaje maduro. La garantía no se afirma, se demuestra y se blinda: seis generadores de programas aleatorios (“fuzzers diferenciales”) crean miles de casos y comparan los tres motores en cada uno, además de treinta y dos baterías de pruebas dirigidas. Que un mismo programa dé el mismo resultado sin importar cómo se ejecute es la base de la confianza en una plataforma propia: cero sorpresas entre desarrollo y producción.
18 · JUL · 2026
Estructuras de datos anidadas completas
Listas dentro de listas: estructuras de datos anidadas de cualquier tipo, compiladas a binario
El compilador nativo ya maneja listas que contienen otras listas —matrices, tablas, árboles de datos—: guardar una fila dentro de una tabla, recuperarla, medirla, recorrerla y modificarla de modo que el cambio se vea desde la estructura que la contiene. Con esto queda cerrado el modelo de datos genérico: listas y diccionarios pueden contener números, texto o más listas, todo compilado a un binario propio que arranca al instante, sin intérprete debajo. El acceso anidado directo —tomar un elemento de una fila de una tabla en un solo paso— funciona igual que en cualquier lenguaje maduro. La prueba: matrices, accesos encadenados y mutación por referencia dan exactamente el mismo resultado en los tres motores, byte a byte, y las listas de números simples no cuestan un solo cambio. Veinticuatro baterías de pruebas en verde.
18 · JUL · 2026
Diccionarios de texto + robustez de memoria
Diccionarios que guardan texto, y un fallo de memoria de raíz eliminado y blindado
Los diccionarios (pares clave→valor) del compilador nativo ya guardan texto como valor, no solo números: guardar(mapa, "ciudad", "Ñuñoa") y recuperarlo funciona igual que en el intérprete, con acentos y eñes correctos, e incluso combinando el valor con otras operaciones de texto en el mismo paso o alimentándolo desde una lista. Al construir esta pieza, una verificación adversarial destapó un fallo de memoria latente —presente desde antes— en la operación de reemplazo de texto: dejaba mal el contador interno de memoria, de modo que la siguiente operación podía escribir sobre datos vivos. Se localizó por bisección e inspección del binario generado, se corrigió de raíz y —más importante— se blindó el mecanismo para que esa clase de error sea imposible en el futuro (falla en tiempo de compilación en vez de corromper en silencio). Resultado: veintitrés baterías de pruebas y cientos de casos de fuzzing diferencial en verde, con los tres motores coincidiendo byte a byte. La solidez no se afirma: se demuestra y se protege.
18 · JUL · 2026
Listas de texto nativas
Listas de texto de primera clase: cada elemento se comporta como una cadena en cualquier operación
El compilador nativo ahora trata los elementos de una lista de textos como cadenas de pleno derecho. Tomar un texto de una lista y, en el mismo paso, ponerlo en mayúsculas o minúsculas, reemplazar dentro de él, recortarlo, medir su longitud, buscar dentro o concatenarlo —todo anidado, sin pasos intermedios— ya compila a binario. Antes había que copiar el elemento a una variable aparte para poder transformarlo; ahora mayusculas(elemento_de_la_lista) funciona directo, e incluso se puede construir una lista nueva a partir de los elementos transformados de otra. Todo con acentos y eñes correctos. La prueba: doce operaciones distintas sobre listas de texto dan exactamente el mismo resultado en los tres motores —compilador nativo, intérprete en Go e intérprete de referencia—, byte a byte. Las listas de números siguen intactas: la mejora no cuesta un solo cambio en lo que ya funcionaba, y la batería completa —incluido el compilador auto-compilándose— sigue en verde.
18 · JUL · 2026
Estructuras de datos nativas
Listas mutables con semántica de referencia — estructuras de datos genéricas compiladas a binario
El compilador nativo cerró la última pieza de su modelo de datos: las listas ahora son referencias, igual que en el intérprete. Cuando una función recibe una lista y la modifica —añadir, quitar o cambiar elementos—, el cambio es visible para quien la llamó. Antes, añadir un elemento dentro de una función se perdía al volver; ahora la longitud vive en una cabecera compartida en memoria, de modo que todas las vistas de la misma lista ven la misma realidad. La prueba: una función que hace append sobre la lista de quien la llama produce exactamente el mismo resultado en los tres motores —compilador nativo, intérprete en Go e intérprete de referencia—. La consecuencia es grande: estructuras de datos genéricas con mutación —pilas, colas, buffers que crecen, acumuladores compartidos entre funciones— ya compilan a un binario propio que arranca al instante, sin runtime debajo. Verificado sin una sola regresión: la batería completa (incluido el propio compilador auto-compilándose y el hash propio, que usan listas de forma intensiva) sigue en verde byte a byte.
18 · JUL · 2026
Texto nativo verificado
Texto y codificadores completos, correctos en Unicode, compilados a binario — y verificados por fuzzing diferencial
El compilador nativo ya baja a código máquina programas de texto reales y completos, no solo cadenas sueltas: búsqueda de subcadena (indice, contiene), reemplazo (reemplaza), corte y acceso por carácter (subcadena, caracter), longitud, mayúsculas y minúsculas, y concatenación —todo respetando Unicode (UTF-8): los índices y la longitud cuentan caracteres, no bytes, y el cambio de caso maneja los acentos del español (á é í ó ú ñ ü). La prueba de que funciona: un codificador Base64 completo —codificar y decodificar— escrito en V++ compila a un binario ARM64 y produce salida idéntica byte a byte al intérprete de referencia. Y la garantía es permanente: se construyó un banco de pruebas por fuzzing diferencial que genera cientos de programas de texto aleatorios con acentos y confirma que los tres motores —compilador nativo, intérprete en Go e intérprete de referencia— dan exactamente el mismo resultado. Ese banco no solo protege el presente: al construirlo aparecieron y se corrigieron varias diferencias sutiles de Unicode que ninguna prueba manual había cazado. La consecuencia: parsers, codificadores y utilidades de texto propias pueden distribuirse como binarios autónomos y auditables, correctos en español, sin ningún runtime de terceros.
18 · JUL · 2026
Criptografía propia
El hash criptográfico propio ahora compila a binario nativo — cero intérprete, cero Python
Un hash criptográfico de nivel producción, escrito íntegramente en V++ —esponja de 25 lanes de 64 bits, 24 rondas, con sus constantes y su caja de sustitución embebidas—, ahora compila a un binario nativo ARM64 (V++ → ensamblador → Mach-O) y produce exactamente el mismo resultado que el intérprete de referencia y que el intérprete en Go: el mismo digest de 512 bits, byte por byte, para cualquier entrada. Es la prueba de que V++ ya no es solo aritmética y servidores: el compilador nativo digiere programas de datos reales —listas dinámicas, tablas, índices calculados, funciones que devuelven colecciones, argumentos que son expresiones o llamadas anidadas— y los baja a código máquina que arranca al instante, sin ningún runtime debajo. Para llegar aquí se cerró una cadena de capacidades del compilador, cada una con una prueba que confirma resultado idéntico en los tres motores (compilador nativo, intérprete en Go e intérprete de referencia): operaciones de bits y de bytes de 64 bits, literales de lista de cualquier tamaño, conversión a hexadecimal en memoria, y evaluación correcta de argumentos complejos. La consecuencia propia: una primitiva de seguridad crítica puede distribuirse como un binario autónomo y auditable, sin depender de intérpretes de terceros. Verificable de punta a punta: se compila, se ejecuta y se compara contra la referencia en una batería de regresión.
18 · JUL · 2026
Servidor propio
Sesiones y cookies desde el binario nativo, chequeo de tipos más estricto y puerta de calidad en paralelo
El servidor web nativo cierra el ciclo de sesiones: además de leer cabeceras, V++ ahora escribe cookies. En el intérprete hay funciones de primera clase —cookie_set, cookie_set_seg (con Secure para HTTPS), cookie_borrar y cookie_leer— que emiten una cabecera Set-Cookie endurecida por defecto (HttpOnly, SameSite=Lax, Path=/); y un binario compilado a máquina abre sesión emitiendo esa misma cabecera, sin intérprete ni Python debajo. Junto con la lectura de Cookie, un binario propio ya hace login y estado de sesión completos —verificado de punta a punta en una batería de regresión 17/17 por curl. En paralelo, el chequeo de tipos se volvió más sólido con el operador +: cuando suma un número con un texto el resultado es texto, y ahora el verificador propaga ese tipo para atrapar un mal uso numérico posterior que antes se le escapaba —sin un solo falso positivo en los 881 módulos de la biblioteca. Y la puerta de calidad propia (verifica: 23 análisis de tipos, memoria, concurrencia y propiedades) ahora corre en paralelo: la misma salida exacta en una fracción del tiempo. Los operadores de bits (bit_y, bit_o, bit_xor, bit_no, desplazamientos) quedaron blindados con una prueba que confirma resultado idéntico en los tres motores. Todo verificable, todo ejecutable.
17 · JUL · 2026
Solidez verificada
Los tres motores de V++ ahora dan resultados idénticos — consistencia demostrada
V++ corre en tres motores —el compilador nativo (a binario ARM64), un intérprete en Go y un intérprete de referencia— y la promesa propia es que el mismo programa produzca el mismo resultado en cualquiera de ellos. Un barrido de solidez encontró y cerró cuatro puntos donde el intérprete de referencia se había desviado de los otros dos: la división entera de negativos (ahora trunca hacia cero, como C, Rust y Go, no como el redondeo hacia abajo de Python), el parseo de palabras contextuales (identificadores como registro que también son palabras clave), la aridad de operaciones de lista, y la concurrencia cooperativa (el bloque tarea: de procesos ligeros con canales, ahora idéntico y determinista en los tres). Resultado medido: la batería de documentación ejecutable de la biblioteca —más de 5 500 ejemplos verificados— pasó de decenas de discrepancias a total consistencia, y el fuzzing diferencial se endureció para generar casos con negativos que antes no cubría. No es una afirmación: es comportamiento que puedes ejecutar en los tres motores y comparar tú mismo.
17 · JUL · 2026
Hito CEOO
Un servidor web que compila a binario nativo — cero intérprete, cero Python
V++ cruzó la última frontera del andamiaje: el compilador nativo (V++ → ensamblador ARM64 → Mach-O) ahora incluye http_servidor(puerto, manejador). El servidor no corre sobre ningún intérprete —habla directo con los sockets del sistema operativo (Darwin ARM64) por llamadas de sistema— y arranca de forma instantánea, como un binario de C o Rust. Soporta desde una respuesta fija hasta un manejador dinámico con enrutamiento: peticion_ruta(), peticion_metodo() y peticion_cuerpo() leen la petición real, y el manejador construye la respuesta —incluida la concatenación de texto con llamadas embebidas directas (regresa "…" + peticion_ruta() + "…")— también compilada a instrucciones de máquina. Y ya sirve archivos reales del disco: el compilador nativo suma es_archivo(ruta) y leer_archivo(ruta), con lo que un servidor de archivos estáticos completo —con mapeo de raíz a index.html, 404, protección anti-path-traversal y Content-Type correcto por extensión (CSS, JS, imágenes servidas byte a byte)— compila a un solo binario. Y ahora lee las cabeceras de la petición: peticion_encabezado(nombre) devuelve el valor de cualquier cabecera —Cookie, Host, Authorization— sin distinguir mayúsculas, lo que habilita sesiones, cookies y autenticación desde el binario nativo, sin Python debajo. Verificado de punta a punta: cada ejemplo se compila a binario, se arranca y responde por curl en una batería de regresión 12/12, sin que se rompa el auto-hospedaje (el compilador que se compila a sí mismo) ni el fuzzing diferencial de tres motores. Es la pieza que permite servir plataformas CEOO como binarios propios autónomos, sin Python ni Node debajo.
16 · JUL · 2026
Solidez y cómputo
Más garantías estáticas, bits nativos y matemática real (v6.18 → v6.24)
Dos frentes maduraron a la vez. Solidez (verificación formal): la puerta propia vpp verifica suma cuatro verificadores sound nuevos —código muerto tras regresa, romper/continuar fuera de un bucle, y los primeros chequeos de tipos entre funciones: aritmética sobre una cadena devuelta por una función e inferencia bidireccional de parámetros (el cuerpo infiere la firma y cada llamada se verifica contra ella)—, todos con cero falsos positivos sobre los 875 módulos y probados también en los 47 programas V++ de producción. Cómputo: V++ gana operadores de bits nativos (bit_y, bit_o, bit_xor, bit_no, bit_izq, bit_der) —antes se emulaban con aritmética, ahora son una instrucción de máquina— y matemática de números reales completa: raíz real, trigonometría directa e inversa, hiperbólicas, exponencial/logaritmo, redondeo, distancia euclidiana y las constantes π y e (módulos bitnativo y mate_real). Todo en el intérprete y en la transpilación a JavaScript, sin romper nada. 872 módulos, 14 764 doctests en verde.
16 · JUL · 2026
Hito CEOO
De lenguaje a plataforma: V++ ya sirve la web full-stack, con base de datos propia
V++ dejó de ser solo un lenguaje: ahora es un runtime web y móvil propio. En una sola línea de avances (v6.06 → v6.17) suma un servidor HTTP nativo (servir_http, sin andamios), full-stack (formularios, cookies, sesiones, redirecciones, tipos de contenido, IP del cliente, reloj), una base de datos documental propia con altas, actualizaciones y un motor de consultas tipo SQL (WHERE, JOIN, ORDER BY, GROUP BY, agregados), estado en memoria para cachés, y todo lo necesario para apps móviles instalables (PWA). La prueba viva: rius.ceoo.world, una plataforma completa de gestión de obra pública —web y móvil, con autenticación, permisos por rol, auditoría en vivo y export a Excel— construida y servida 100% en V++, sin Node ni motor de base de datos externo. 870 módulos, 14 689 doctests en verde.
15 · JUL · 2026
Hito CEOO
Redes neuronales propias: de la matriz a la red que aprende lógica
El toolkit de IA nativa de V++ queda completo, en el propio lenguaje y sin frameworks. A la diferenciación automática y el gradiente se suman: matrices de punto flotante (matrizf, cuya multiplicación es el corazón de una capa), capas densas (capadensa) que se componen en redes multicapa (mlp, aproximadores universales), y —la prueba definitiva— un perceptrón que aprende funciones lógicas desde datos (aprende): entrenado sobre las tablas de verdad de AND y OR, clasifica todas sus entradas correctamente. Es aprendizaje automático real y verificado, propio de punta a punta. 820 módulos, 14 239 doctests en verde.
15 · JUL · 2026
Hito CEOO
Una neurona que aprende: entrenamiento por gradiente en V++ puro
Completando el camino de la IA privada, V++ ya entrena modelos que aprenden de datos, sin frameworks externos. Sobre la diferenciación automática (autodiff) llegan gradiente —el vector de derivadas parciales de una función de varias variables— y neurona, un modelo lineal que se ajusta a los datos por descenso de gradiente: entrenado sobre la relación y = 2x + 1, sus pesos convergen exactamente a 2 y 1. Es la red neuronal mínima propia, aprendiendo de verdad en el propio lenguaje. Todo en V++ puro y verificado: 14 207 doctests en verde, 814 módulos.
15 · JUL · 2026
Hito CEOO
Punto flotante y diferenciación automática nativa
El intérprete de V++ ahora entiende números decimales (punto flotante de doble precisión), lo que abre el cómputo numérico real: con la biblioteca numf se obtienen media, varianza y desviación estándar, y raíz cuadrada por Newton —raíz(2) da 1.414213562373095—. Y sobre eso, un diferenciador que ni Python ni Rust tienen en el núcleo del lenguaje: autodiff, diferenciación automática por números duales que calcula la derivada exacta de una función a la vez que su valor —la derivada de x²+2x en x=3 es exactamente 8—. Es el cimiento de la IA privada. Todo verificado sin una sola regresión: 14 196 doctests en verde, autohospedaje intacto. (El soporte se implementó, se detectó un bug de corrección en el optimizador por verificación adversarial, se corrigió su causa raíz, y solo entonces se integró.)
15 · JUL · 2026
Verificado
Datos y solidez: dataframe, validación en runtime, árbol binario y más chequeos
Cuatro piezas nuevas, tres construidas en paralelo por agentes propios. Dataframe (marco): análisis columnar estilo pandas —agregaciones, filtrado componible, transformación de columnas con funciones— a velocidad nativa. Validación por esquema en runtime (esquema): comprueba tipos y reglas al ejecutar, con garantías reales que TypeScript no da porque borra los tipos. Árbol binario de búsqueda persistente (arbol): estructura funcional inmutable. Y un nuevo chequeador, vpp duplicados, que detecta funciones redefinidas por accidente —silenciosas en Python/JS— con cero falsos positivos en toda la biblioteca. Verificado: 14 183 doctests en verde, 810 módulos.
15 · JUL · 2026
Verificado
Tipos algebraicos y match: modelar datos como en Haskell y Rust
Sobre las funciones de primera clase, V++ suma tipos algebraicos (tipos suma / uniones etiquetadas) con la biblioteca adt: se construye un valor como variante("Rect", lista(3, 4)) y se inspecciona por etiqueta y campo. Y el match exhaustivo con adtmatch: se despacha a un manejador por caso —los casos son funciones-valor— tal como el match de Rust o Haskell. Además hof añade utilidades de orden superior antes imposibles: ordenar por función clave, buscar y contar por predicado, combinar dos listas. Modelar figuras, árboles o expresiones queda seguro y legible. Verificado: 14 130 doctests en verde, 808 módulos.
15 · JUL · 2026
Hito CEOO
Funciones de primera clase: programación funcional en V++
V++ ahora trata las funciones como valores de primera clase —consistentemente en sus dos motores—: se pasan por nombre como argumento y se aplican. Eso habilita la programación funcional de orden superior al estilo de Haskell, con la nueva biblioteca funcional: mapea, filtra, pliega (fold), todos, alguno. Se componen con naturalidad —pliega(suma, 0, mapea(cuadrado, filtra(par, lista))) da 56— pero con sintaxis legible y velocidad nativa, sin la pereza obligatoria de Haskell. Es también el cimiento para callbacks, metaprogramación y el sistema de tipos. Verificado sin una sola regresión: 14 113 doctests en verde, autohospedaje intacto, ambos motores de acuerdo.
15 · JUL · 2026
Verificado
Chequeo de aridad + más rango: Malbolge, transpilador BF, S-expresiones, JSON y config
Nuevo vpp aridad: un chequeador que atrapa en compilación una llamada a una función con el número equivocado de argumentos —algo que Python y JavaScript no detectan hasta que revienta en ejecución— con cero falsos positivos sobre toda la biblioteca. Y más piezas de rango propio: un intérprete de Malbolge (el lenguaje diseñado para ser imposible) que ejecuta su Hello, world canónico; un transpilador de Brainfuck a V++; un lector de S-expresiones; extensiones de JSON (escapes correctos, pretty-print anidado); y un parser de configuración .env. Todo en V++ puro y verificado: la suite llega a 14 089 doctests en verde.
15 · JUL · 2026
Verificado
Cuatro paradigmas propios: Lisp, scripting seguro, consultas y HTML tipado
La biblioteca suma cuatro piezas que llevan a V++ a terrenos de otros lenguajes, con sus ventajas. Lisp: un evaluador núcleo con aritmética, if, lambda con cierres léxicos y let —((lambda (x) (* x x)) 5) da 25— demostrando metaprogramación (código como dato). Scripting: reemplazo de Bash con citado seguro por construcción (imposible la inyección de shell) y captura de código de salida. Consultas: un mini-motor SQL componible sobre tablas, sin cadenas frágiles ni inyección. HTML: construcción de markup con escape automático anti-XSS. Todo en V++ puro, con pruebas ejecutables verdes: la suite llega a 14 030 doctests.
15 · JUL · 2026
Verificado
Rango del lenguaje: intérprete de Brainfuck y motor de unificación (Prolog)
Dos piezas que muestran la amplitud de V++. Brainfuck: un intérprete completo de los ocho comandos del lenguaje esotérico, en V++ puro, que ejecuta el clásico Hello World! — prueba de que V++ abarca desde lo mínimo Turing-completo hasta lo expresivo de alto nivel. Unificación: el corazón de la programación lógica (estilo Prolog) —con parser de términos, occurs-check y sustitución— embebido como biblioteca propia: f(X, b) con f(a, Y) unifica en f(a, b). Ambos con pruebas ejecutables verdes; la suite llega a 14 010 doctests.
15 · JUL · 2026
Hito CEOO
Auto-vectorización NEON: sumar listas, dos números a la vez
El backend nativo propio da su primer paso de vectorización SIMD: los bucles que suman una lista de enteros ahora procesan dos valores por instrucción con registros vectoriales NEON (más una reducción final), en lugar de uno por uno. Es una transformación segura por construcción — lleva una verificación de tipo por vector y, ante cualquier valor que no sea entero, cae automáticamente al camino escalar exacto; la suma entera es asociativa, así que el resultado es idéntico. Verificado con cero miscompilaciones en 14 benchmarks (ruta de producción) más un fuzz diferencial de 24 programas, con una aceleración de ~1.25× sobre el ya optimizado camino escalar. Se apoya en el analizador vpp homogeneo que prueba cuándo una lista es de enteros. Toda la cadena escrita en el propio V++, sin compiladores externos.
15 · JUL · 2026
Verificado
Biblioteca de sistema: parseo de query strings y formularios
Junto a http_parse llega query, que completa el manejo de peticiones: separa una cadena a=1&b=2&c=hola+mundo en pares clave-valor, decodificando el porcentaje (%40 → @) y el + como espacio, tal como manda application/x-www-form-urlencoded. Con esto V++ ya lee una petición HTTP de principio a fin —línea, cabeceras, cuerpo, formulario— sin salir del lenguaje. La suite llega a 14 000 doctests en verde.
15 · JUL · 2026
Verificado
Biblioteca de sistema: parseo de HTTP/1.1 y decodificación chunked
La biblioteca estándar suma http_parse, el inverso de http_texto: en vez de armar mensajes HTTP, los lee. Funciones puras y verificadas para extraer método, ruta, código y frase de estado, el valor de cualquier cabecera (sin distinguir mayúsculas), el Content-Length, el cuerpo, y —lo más útil— decodificar Transfer-Encoding: chunked a bytes planos. Todo en V++ propio, sin dependencias, con sus pruebas ejecutables verdes. La suite crece a 13 992 doctests, todos en verde.
15 · JUL · 2026
Verificado
Tipos: prueba de listas homogéneas de enteros (vpp homogeneo)
Las listas de V++ pueden mezclar números y texto, así que el compilador coloca una verificación de tipo por elemento en cada suma. Para poder acelerar esos bucles de forma segura hace falta probar que una lista contiene sólo enteros. El nuevo analizador vpp homogeneo da exactamente esa prueba, de forma sólida y conservadora: infiere las variables enteras por punto fijo (resolviendo la auto-referencia de los contadores como i = i + 1), detecta cuándo una lista se escapa (se pasa a otra función o se comparte) y verifica cada valor agregado y cada inicializador. Rechaza —sin un solo falso positivo— listas mixtas, con texto, o alimentadas por funciones desconocidas; y reconoce las genuinamente enteras (contadores de bucle, literales, cribas, mallas A*). Es el cimiento de tipos que habilita la vectorización de datos sin arriesgar la corrección.
15 · JUL · 2026
Verificado
Backend: menos tráfico de memoria en bucles con acumulador
El backend nativo propio —toda su cadena de optimización escrita en el propio V++— ahora elimina el derrame redundante de operando a la pila cuando el registro que lo contiene queda intacto entre el guardado y su lectura. En bucles que acumulan sobre una lista, esto baja el ir y venir a memoria por cada elemento. Medido sobre una suma de 2 millones de elementos: de 10.4 ms a 8.5 ms (~1.2×), todo por la ruta 100% propia, sin compiladores externos. El pase es conservador —no toca el código si hay una llamada, anidamiento o escritura al registro en medio— y quedó verificado con cero miscompilaciones en 14 benchmarks (salida idéntica al intérprete de referencia). Un paso más para que la ruta propia alcance a C sin depender de nada externo.
11 · JUL · 2026
Verificado
Backend optimizador: el bucle aritmético alcanza 1.05× de C (paridad práctica)
El backend nativo de V++ —toda su cadena de optimización escrita en el propio V++— ya realiza asignación de registros (locales de bucles calientes, incluido el de nivel superior, a registros callee-saved) y reducción de fuerza por divisor constante: igual que cc -O2, reemplaza el módulo por constante con multiplicación mágica (Granlund-Montgomery) en vez de división de hardware —la constante mágica computada coincide byte a byte con la de C—. Con eso, más el colapso de la pila de operandos, la eliminación del spill de memoria, la fusión de ramas y la eliminación de código muerto, el bucle aritmético alcanza 1.00× de cc -O2 (paridad exacta), y el análisis de natividad flow-sensitive colapsa el despacho incluso en bucles de nivel superior, con cero miscompilaciones verificadas en 14 benchmarks. Incluso el conteo de primos (división de prueba) baja a 1.03× al colapsar el despacho de +/== que rodeaba a la sdiv; solo queda ~1.17× en división de ciclo muy corto (Euclides), límite del divisor que C también paga. Detalle en la comparación honesta.
9 · JUL · 2026
Verificado
V++ nativo, medido frente a C: mismo orden de magnitud
Con el compilador y los optimizadores 100% escritos en V++ (sin compiladores externos), medimos la ruta nativa propia contra C con optimización agresiva (-O2), en programas idénticos y salida verificada byte a byte: Fibonacci recursivo 1.8×, conteo de primos 1.55×, bucle aritmético 1.30× — V++ queda dentro del mismo orden de magnitud que C. Además, el operador de igualdad ahora se resuelve en línea (comparación nativa para números, sin llamada auxiliar). Y el roadmap completo ya está publicado.
9 · JUL · 2026
Verificado
La ruta nativa propia ya corre ~3.4× más rápido, sin compiladores externos
V++ ahora resuelve la suma en línea: cuando los operandos son números, emite la instrucción de suma nativa en vez de llamar a una función auxiliar; cuando son texto, concatena. Verificado en las 19 pruebas del dialecto con salida idéntica. Un programa recursivo intensivo (Fibonacci) pasó de 0.31 s a 0.09 s (~3.4×) respecto al código sin optimizar, todo por el camino 100% propio: el compilador de V++ y sus optimizadores están escritos en V++.
9 · JUL · 2026
Verificado
La ruta nativa propia ya corre ~2.75× más rápido, sin compiladores externos
El optimizador de V++ ahora elimina el guardar/restaurar de valores alrededor de operaciones intermedias cuando no cruza una llamada a función. Verificado en las 19 pruebas del dialecto autohospedado con salida idéntica: fib(35) pasó de 0.11 s a 0.04 s (~2.75×) respecto al código sin optimizar, todo por el camino 100% propio (compilador de V++ en V++ + optimizador en V++), sin usar ningún compilador de C.
9 · JUL · 2026
Verificado
La ruta nativa propia se acerca más a C
El optimizador de V++ ahora también colapsa el acceso a variables locales —tres instrucciones a una— además de limpiar el tráfico de pila. Verificado en las 19 pruebas del dialecto autohospedado y en programas variados, con salida idéntica: fib(35) pasó de 0.11 s a 0.06 s (~1.8×), todo por la ruta 100% propia, sin compiladores externos.
9 · JUL · 2026
Verificado
Compilación nativa propia, sin compiladores externos
V++ ya genera binarios ARM64 por una ruta 100% propia —el compilador de V++ escrito en V++ más un optimizador peephole también en V++— sin usar ningún compilador de C. El optimizador elimina el tráfico de pila redundante del código generado; en código recursivo intensivo el binario corre ~1.5× más rápido, con salida idéntica. Es el primer paso de un plan para que la ruta propia alcance la velocidad de C sin depender de nada externo.
9 · JUL · 2026
Verificado
Optimizador completo: eliminación de asignaciones muertas
El compilador ahora también descarta las asignaciones a variables que ya no se leen (con lado derecho sin efectos). Con esta pieza, el optimizador de V++ realiza la cadena clásica de un compilador de producción: expansión de funciones, propagación de constantes, plegado, eliminación de código muerto y de asignaciones muertas. a = 5; b = a + 1; devuelve b se reduce a devuelve 6, sin rastro de las variables.
9 · JUL · 2026
Verificado
Optimizador: expansión de funciones pequeñas (inlining)
El compilador ahora expande en el lugar las funciones cortas de una sola expresión, y combinado con la propagación, el plegado y la eliminación de código muerto, resuelve cadenas completas en compilación: sq(x)=x*x con sq(5)+sq(3) se convierte directamente en 34. La expansión es segura — un argumento con efectos se evalúa una sola vez — y el autohospedaje sigue byte-idéntico.
9 · JUL · 2026
Verificado
HUUN'"'"'AB-512: el hash propio, ahora escrito en V++
La huella criptográfica propia de CEOO —una esponja de 25 registros de 64 bits y 24 rondas con nombres en maya (K'"'"'AB'"'"', OOL, CHI'"'"', KUXAN, TZAB'"'"', WAXAK)— está ahora implementada en V++, sobre el motor del propio lenguaje. Coincide byte a byte con la referencia en todos los vectores de prueba (incluyendo texto acentuado y mensajes largos). Con esto, el sellado en la cadena BlockCEOO usa la huella propia calculada por V++, sin depender de nada externo.
9 · JUL · 2026
Verificado
Optimizador: propagación de constantes
El optimizador ahora sigue el rastro de las variables: si una toma un valor fijo, ese valor se propaga a donde se usa (a = 5; b = a + 1 se resuelve a 6 en compilación). El análisis es conservador y correcto — una variable que cambia dentro de un bucle o rama deja de tratarse como constante, mientras que las invariantes sí se propagan. Se combina con el plegado y la eliminación de código muerto, y el autohospedaje sigue byte-idéntico.
9 · JUL · 2026
Verificado
El sellado en BlockCEOO ahora también está escrito en V++
La trazabilidad propia —cada ejecución queda sellada en la cadena BlockCEOO con su huella, sin que el código salga nunca— se implementó en V++. Calcula la huella, la encola de forma durable (con o sin conexión) y la ancla en la cadena. En vivo, ancló 1037 sellos que estaban pendientes. Con esto, ejecutar, compilar, optimizar, validar, analizar y sellar V++ son ya tareas del propio lenguaje mexicano.
9 · JUL · 2026
Verificado
El optimizador ahora elimina código muerto
Además del plegado de constantes, V++ ahora descarta lo que nunca se ejecuta: una condición constante deja solo la rama viva (si 2>1 conserva únicamente el bloque verdadero), los bucles que nunca corren se eliminan, y el código posterior a un regresa desaparece. El binario que produce es más pequeño y directo, y el autohospedaje sigue byte-idéntico: la semántica se preserva exactamente.
9 · JUL · 2026
Verificado
Optimizador: V++ pliega constantes antes de ejecutar y de compilar
El motor incorpora un pase de plegado de constantes e identidades algebraicas: una expresión como 2*3+4 se convierte en 10 de una vez, y simplificaciones como x+0 o x*1 se eliminan. En el intérprete rinde 1.85× más rápido en código con constantes, y el código nativo que genera queda más limpio — todo preservando la semántica exacta (el autohospedaje sigue byte-idéntico).
9 · JUL · 2026
Verificado
El analizador estático de V++ ahora está escrito en V++
El linter —que detecta funciones no definidas y llamadas con número de argumentos incorrecto— está ahora escrito en V++ y corre sobre el motor nativo: 0 problemas en los 68 módulos de la biblioteca estándar, y en prueba adversarial detecta correctamente los errores inyectados. Ejecutar, compilar, validar y analizar V++ son ya tareas del propio lenguaje, sin intérpretes externos.
9 · JUL · 2026
Verificado
V++ ya valida su propia biblioteca — con una herramienta escrita en V++
El verificador de pruebas de la biblioteca estándar está ahora escrito en V++ y corre sobre el motor nativo del lenguaje: valida 999/999 ejemplos sin ningún intérprete externo. Se comprobó de forma adversarial que discrimina (detecta un resultado incorrecto, no solo cuenta). Ejecutar, compilar y validar V++ ya son tareas nativas del propio lenguaje.
9 · JUL · 2026
Verificado
Autohospedaje total — V++ se compila a sí mismo sin depender de nada externo
El compilador de V++ está escrito en V++, y ahora corre sobre el motor nativo del propio lenguaje: genera código máquina ARM64 idéntico, byte a byte, al del arranque original. La batería oficial de 19 casos (números con decimales, mapas, bucles, azúcar sintáctica, cortocircuito lógico) compila y ejecuta correctamente sin ningún intérprete externo. V++ ya no necesita andamios para construirse: se sostiene a sí mismo.
9 · JUL · 2026
Verificado
Toda la biblioteca estándar de V++ compila a máquina nativa
El compilador ahora también entiende listas y mapas, no solo números y texto. Con esto, los 62 módulos de la biblioteca estándar (todos los que tienen pruebas) compilan a binario nativo con salida idéntica al intérprete — ya no queda nada que dependa del intérprete. El compilador elige automáticamente la ruta rápida sin caja para lo numérico y una ruta con valores etiquetados para las colecciones.
9 · JUL · 2026
Verificado
El compilador de V++ ya lleva las cadenas a máquina nativa
El backend de compilación a código nativo ahora entiende texto, no solo números, con inferencia de tipos automática. 40 de los 68 módulos de la biblioteca estándar compilan a binario nativo con salida idéntica a la del intérprete. En texto (números romanos ×300) el binario compilado corre 15× más rápido que el intérprete; en cómputo numérico alcanza la velocidad de C.
8 · JUL · 2026
Verificado
Rendimiento: 22× sobre Python en el motor nativo, y velocidad de C al compilar
Mismo programa V++ (conteo de primos < 500 000, salida idéntica en las tres rutas): el motor nativo de V++ corre 22× más rápido que el intérprete, y compilado a código nativo por el backend de V++ llega a 223× más rápido — la velocidad de C. V++ ejecuta nativo y compila a máquina nativa.
8 · JUL · 2026
Verificado
Runtime nativo completo — V++ corre sin andamios
El motor nativo de V++ (intérprete propio, sin dependencias) ya implementa toda la biblioteca estándar con paridad exacta: cadenas, enteros, listas y sus operaciones. Los 68 módulos y sus 996 pruebas se ejecutan en el motor nativo sin ningún intérprete externo, con salida idéntica. Binarios para macOS (Apple Silicon e Intel), Linux y Windows, incluidos en el descargable.
8 · JUL · 2026
Verificado
Oleadas 12-19 — 8 módulos nuevos, todos sin andamios
gray, luhn, ip (IPv4↔entero), combinatoria (n!/nPr/nCr), hamming, paridad, temperatura y cesar. Se retiró el builtin concat (→ +): ahora toda la stdlib corre en el motor nativo de V++ sin Python. Doctests 996/996.
8 · JUL · 2026
Verificado
Oleadas 9-11 — ascii, endian, mate3 (paridad C, sin andamios)
Tres módulos que corren en el motor nativo de V++ sin Python: ascii (el ctype.h de C: es_digito/es_letra/mayúsculas…), endian (orden de bytes, htons/htonl) y mate3 (raíz entera, potencia entera, log2). Doctests 947/947. En el SDK descargable.
8 · JUL · 2026
Verificado
Oleada 8 — módulos autohospedados (sin andamios)
Los módulos de enteros y bits (enteros, enteros2, bits2) ahora corren en el motor nativo de V++ sin Python: se reemplazó el builtin potencia por un ayudante propio. V++ ejecuta su propia stdlib sin ningún andamio de otro lenguaje. Doctests 908/908, verificado en el binario nativo.
8 · JUL · 2026
Verificado
Oleada 7 — hashes de datos + linter con imports
Nuevo módulo hashdato (djb2, FNV-1a de 32 bits, checksums de suma y XOR) para tablas hash e integridad rápida. Y vpp lint ahora expande importa antes de analizar: cero falsos positivos con funciones importadas — usable en programas reales. Doctests 908/908.
8 · JUL · 2026
Verificado
Oleada 6 — módulo bases (hex / binario / octal)
Conversión entre enteros y su texto en otra base (2..16), como el 0x/0b de C y strtol/itoa: desde_hex("ff")=255, a_bin(10)="1010", con round-trip verificado. Doctests 895/895. Incluido en el SDK.
8 · JUL · 2026
Verificado
Oleada 5 — tipado estático: chequeo de tipo de retorno
vpp lint ahora verifica estáticamente que el valor devuelto sea compatible con el tipo de retorno anotado: funcion f() -> entero: regresa "x" se marca como error antes de ejecutar (solo literales, cero falsos positivos). Un paso de seguridad estática a la altura de C. Suite 2/2 en verificar_goal → 29/29 TODO VERDE.
8 · JUL · 2026
Verificado
Campaña “V++ superior” · oleadas 2-4 — paridad con C
Tres nuevos módulos de la stdlib que cierran brechas reales frente a C:
· enteros: enteros con tamaño y sin signo (u8…u64, i8…i64), envoltura de complemento a dos, desbordamiento, aritmética que envuelve, bytes y rotaciones.
· enteros2: aritmética saturante (DSP/gráficos), CLZ (conteo de ceros a la izquierda), bits necesarios, signo, valor absoluto.
· bits2: operadores lógicos de bits AND/OR/XOR/NOT (los & | ^ ~ de C) + poner/quitar/alternar bit.
Verificado: doctests 815 → 877/877, verificar_goal 28/28 TODO VERDE. Incluido en el SDK descargable.
8 · JUL · 2026
Verificado
Oleada de cierre — py2vpp (#132) y escritura atómica
Nuevo transpilador inverso py2vpp: convierte un subconjunto de Python a V++ (español), usando la indentación para cerrar bloques con fin. Verificado con prueba diferencial (la salida en Python es idéntica a la del V++ transpilado) e integrado a verificar_goal.sh: 26/26 secciones, TODO VERDE.
Además, archivo_escribir ahora es atómico (temporal + fsync + rename POSIX): elimina la corrupción cuando varios procesos escriben el mismo archivo. Beneficia a todo programa V++ que escriba archivos.
2 · JUL · 2026
Hito
Verificado
Oleadas 1-2 del ROADMAP 400 — SDK v5.0 publicado
Un solo día, dos oleadas del plan de 200 puntos, todo verificado con la suite completa:
· Diagnósticos de clase mundial: errores con línea, columna, carete ^, códigos VPP-NNN, sugerencias "¿quisiste decir X?" y catálogo ERRORES.md.
· Optimizador -O del compilador nativo: constant folding, peephole, dedup de literales, strength reduction y código muerto — punto fijo de autohospedaje intacto.
· Features v5 del intérprete: constante, contratos exige, pattern matching segun, multi-retorno e interpolación de cadenas (FEATURES_V5.md).
· Toolchain: test runner vpp prueba con afirma, generador vpp docs, LSP completo v1.1, vpp bind (interop C).
· Paquetes: vpp nuevo, manifiesto vpp.toml, lockfile y registro remoto vivo — índice público en /paquetes/indice.json.
· Integración: GUIA_IA.md (guía de integración) + corpus de 258 programas con salida esperada.
· Conformidad y norma: conformidad.vpp 100/100, ESPEC 1.0 (borrador), versionado semántico, RANGO_NUMERICO.md y benchmarks de 3 motores.
SDK v5.0 con todo lo anterior ya en /descargas (checksums SHA-256 publicados). Avance real por frente en /roadmap.
2 · JUL · 2026
Nuevo
Arranca el ROADMAP 400 — plan de 200 puntos
Inicia la siguiente etapa: 200 puntos en 10 frentes (A–J) para escalar, optimizar, potenciar y compatibilizar V++ hasta que humanos y herramientas puedan usarlo. Diagnósticos de clase mundial en español, optimizador del compilador nativo, paridad del autohospedado, toolchain unificada, estrategia de integración y apertura controlada.
Sigue el avance real en la página de Ruta.
28 · JUN · 2026
Hito CEOO
Verificado
PUNTO FIJO de autohospedaje — V++ se compila a sí mismo
El compilador vppc_self.vpp, escrito en V++, se compila a sí mismo y alcanza el punto fijo: gen2.s == gen3.s == gen4.s (diff = 0). A partir de la segunda generación no interviene Python — queda solo como bootstrap inicial, el estándar de la industria. V++ cruza el umbral que el 95% de los lenguajes jamás cruza.
27 · JUN · 2026
Publicación
SDK v4.4, playground y tutorial públicos
Descargas para Mac, Windows y Linux en /descargas, playground en el navegador (compilador V++→JS) y tutorial oficial de 12 secciones con katas de certificación Nivel 1. El sitio de V++ se sirve con un servidor escrito en V++.
JUN · 2026
Verificado
Roadmaps 100/200/300 completados
La suite de regresión creció de 28 a 236/236 casos verdes; el compilador nativo alcanzó ~312 builtins y soporte de flotantes con FP nativo. Fuzzing diferencial de 3 motores (nativo / Go / Python) encontró y cerró bugs reales. Autohospedaje 35/35, stdlib 49/49, Prueba de CEOO 5/5.
JUN · 2026
20/20 transpiladores a lenguajes comerciales
V++ se traduce a 20 lenguajes (JS, TypeScript, Python, Ruby, Perl, Lua, C, C++, Go, Rust, Swift, Java y más), 11 de ellos ejecutados y verificados. Binarios nativos ELF / PE32+ / Mach-O por cross-compile y backend WASM.
12 · JUN · 2026
V++ v4 — intérprete de producción
Operadores lógicos, lambdas, tuberías →, try/catch, primitivas mayas (Cuenta Larga, numerales) y la Prueba de CEOO 5/5: el test de conformidad propia que ningún lenguaje extranjero pasa.
MAY · 2026
V++ v3.0 — 25 componentes
Del lexer al WASM: LSP con diagnósticos, extensión VS Code, depurador, gestor de paquetes vpp instala, gramática formal EBNF v1.0, firma Ed25519 y gobernanza VEP.