Internos del compilador

Las decisiones de diseño clave que hacen a Perry rápido

01NaN-Boxing

Los valores se almacenan como floats de 64 bits con patrones de bits especiales para punteros, permitiendo tipos union sin overhead en runtime. Esto permite que (string | number)[] funcione eficientemente.

Al codificar la información de tipo directamente en los bits de payload NaN de IEEE 754, Perry evita la necesidad de tagged unions o valores encapsulados. Una sola palabra de 64 bits puede representar cualquier tipo de valor JavaScript — los números usan su representación natural, mientras que las cadenas, objetos y otros valores en el heap usan patrones de bits de puntero que caen dentro del rango NaN.

02Monomorphization

Los genéricos se especializan en tiempo de compilación, como en Rust. Cada instanciación de tipo genera código optimizado, eliminando el overhead de verificación de tipos en runtime.

Cuando escribes Array'<'number'>' y Array'<'string'>', Perry genera dos implementaciones separadas y completamente optimizadas. Esto significa que las operaciones de arrays sobre números usan aritmética de máquina directa — sin type guards, sin dispatch dinámico, sin boxing.

03Static Dispatch

Sin tablas virtuales. Las llamadas a métodos se resuelven en tiempo de compilación, permitiendo llamadas directas a funciones y optimizaciones de inlining.

Los runtimes OOP tradicionales usan vtables para la resolución de métodos, añadiendo una capa de indirección en cada llamada. Perry resuelve todas las llamadas a métodos estáticamente durante la compilación, convirtiendo las llamadas a métodos de interfaces en saltos directos. Esto también desbloquea un inlining agresivo — los métodos pequeños a menudo se integran directamente en sus sitios de llamada.

04Zero-Cost Abstractions

Las clases, interfaces y genéricos de TypeScript se compilan a código nativo eficiente sin overhead de representación en runtime.

El sistema de tipos de TypeScript existe solo en tiempo de compilación — y Perry lo toma literalmente. Las interfaces no producen código en runtime. Las jerarquías de clases se aplanan. Las restricciones genéricas se resuelven a tipos concretos. El binario compilado contiene solo la lógica real, sin la maquinaria de abstracción que los intérpretes típicamente cargan.