Evolución de Joss 2026: fases 0 y 1
Este documento registra decisiones ejecutables posteriores a la evaluación crítica. El código y las pruebas son la fuente de verdad.
1. Estado inicial
Baseline de main en 362c26a, antes de cambiar semántica:
go test ./...: correcto.go vet ./...: correcto.go build ./...: correcto.cataloggen --checkydocgen --check: correctos.- El parser daba mayor precedencia a
%que a*//, y trataba&&y||como equivalentes. ??recuperaba panics de lookup, tipos y otros fallos y los convertía en null.0.0y{}eran verdaderos, aunque0, decimal cero y[]eran falsos.int → floatyfloat → decimaleran asignables implícitamente.
2. Decisiones semánticas
Precedencia
La tabla canónica vive en pkg/parser/parser.go y se publica en
Sintaxis. De menor a mayor: asignación, ternario, coalescencia,
pipeline, OR, AND, igualdad, comparación, shifts, rango, suma, producto,
prefijos, llamada y acceso. *, / y % comparten nivel; && supera a ||.
Null coalescing
izquierda ?? derecha evalúa derecha únicamente cuando izquierda termina
normalmente con null. No captura excepciones, panics ni errores de programa.
La recuperación explícita pertenece a try/catch.
Truthiness
Se conserva truthiness porque ya forma parte de ternarios, guard, filtros y APIs existentes. La tabla es cerrada y se basa en categorías:
| Valor | Falso |
|---|---|
| Ausencia | null |
| Booleano | false |
| Número | cero en int, float o decimal |
| String | vacío |
| Colección | array o map vacío |
Los demás valores son verdaderos. "0" es verdadero por ser no vacío.
Seguridad numérica
La única promoción implícita entre clases numéricas es int → decimal, que es
exacta. int → float, float → decimal y operaciones mixtas que dependan de
ellas requieren conversión explícita. La división entera, cuyo resultado es
float, rechaza operandos que no puedan representarse exactamente. El código
estable es JOSS-ARITH-003.
const continúa significando binding inmutable. No promete inmutabilidad del
objeto, de una colección ni del grafo alcanzable.
3. Compatibilidad y migración
| Cambio | Clase | Migración automática | Acción |
|---|---|---|---|
| Precedencia convencional | breaking semántico | No en general | Agregar paréntesis para preservar el resultado anterior. |
?? sólo para null |
breaking y corrección de seguridad | No | Usar try/catch si la recuperación era intencional. |
| Truthiness uniforme | breaking para 0.0, {} y "0" |
No | Comparar explícitamente cuando el dominio use otra regla. |
| Conversiones numéricas estrictas | breaking estático | Parcial | Insertar floatval(...) o decimal(...) sólo con intención revisada. |
No se introduce una rama permanente de semántica legacy. Los proyectos que dependan de la conducta anterior deben hacer visible su intención mediante paréntesis, comparaciones o conversiones.
4. Bugs bloqueados por regresión
- Agrupación completa de aritmética, lógica, comparación, rango, shifts, pipeline, coalescencia y ternario.
- Propagación de división por cero e índice inválido a través de
??. - Igualdad conceptual de cero entre
int,floatydecimal. - Igualdad conceptual de vacío entre arrays y maps.
- Rechazo estático y defensa runtime de pérdidas de precisión conocidas.
5. Superficies preparadas para fase 2
La siguiente fase consolidará var, tipo explícito, mixed y const, con
deprecación finita de let y declaraciones implícitas. Antes de modificar el
parser deberá existir inventario de usos, diagnóstico específico y codemod que
sólo transforme casos semánticamente demostrables.
También quedan inventariados para fases posteriores: retornos obligatorios y
void, inferencia de closures, reducción de unknown, metadata nativa,
namespaces, constructor canónico, concurrencia estructurada y perfiles de
capacidades. Ninguno altera la FASE 1.
6. Riesgos abiertos
floatvalexpresa aceptación deliberada de aproximación; sus callers deben decidir si el dominio permite esa pérdida.- Fuentes externas pueden entregar floats ya aproximados antes de convertirlos
a decimal. El sufijo
mo texto decimal evita esa frontera. - La VM y los plugins tienen evaluadores propios. No se anunciará equivalencia hasta que las pruebas diferenciales cubran estas reglas.
- Agregaciones, JSON y drivers DB requieren ampliar pruebas de frontera sin alterar silenciosamente contratos externos.