← Todos los articulos

Filosofía de la ingeniería: Bjarne Stroustrup, abstracción sin sobrecosto

Bjarne Stroustrup, creador del lenguaje de programación C++

Puntos clave

  • Abstracción sin sobrecosto. Stroustrup creó C++ para acabar con la falsa disyuntiva entre código claro y velocidad a nivel de hardware: la versión expresiva y la versión ajustada a mano deberían compilarse al mismo código máquina.
  • El principio de sobrecosto cero. “Lo que no usas, no lo pagas; lo que sí usas, no podrías programarlo mejor a mano” es la regla que toda función de C++ debe superar.
  • RAII lo vuelve concreto. Atar el ciclo de vida de un recurso a un objeto en la pila brinda una limpieza determinista y a prueba de excepciones, sin recolector de basura, un patrón que Rust adoptó después casi por completo.
  • No dejar espacio por debajo. C++ debe seguir siendo el lenguaje de más alto nivel sin nada entre él y el silicio salvo el ensamblador, o un lenguaje de más bajo nivel ocuparía su lugar.

El principio

“Lo que no usas, no lo pagas. Y además: lo que sí usas, no podrías programarlo mejor a mano.” – Bjarne Stroustrup, el principio de sobrecosto cero1

Esa frase es la más importante de la programación de sistemas, y encierra dos promesas. La primera mitad dice que una abstracción debe ser gratuita en el punto de su no uso: si tocas una función, te cuesta algo; si la ignoras, no te cuesta nada, ni un byte de memoria ni un ciclo de ejecución. La segunda mitad es la promesa más difícil: cuando usas la abstracción, el compilador debe producir un código máquina al menos tan bueno como el que un programador competente habría escrito a mano para esa tarea exacta. Un vector que en modo release no verifica límites. Un puntero inteligente que se compila a un puntero pelado. Un iterador que se desvanece dentro de un bucle crudo. La claridad sale gratis.

La mayoría de los lenguajes te obligan a un canje. Obtienes la versión expresiva y de alto nivel que es lenta, o bajas a la versión rápida y de bajo nivel que resulta ilegible, y todo el oficio se reduce a elegir qué dolor aceptar cada día. Toda la carrera de Stroustrup es un rechazo de ese canje. Lo había sufrido en carne propia: como estudiante de doctorado amaba las abstracciones de Simula, pero las hallaba demasiado lentas para el trabajo real, y amaba la velocidad de BCPL, pero lo encontraba demasiado de bajo nivel para construir algo grande.2 C++ existe porque decidió que no deberías tener que elegir. Eficiencia y abstracción no eran perillas opuestas que hubiera que equilibrar; debían llegar juntas, en la misma línea de código.

Esa convicción es la misma que subyace al argumento de que el rendimiento no es una función que agregas, sino una propiedad que dejas de perder. Una abstracción de sobrecosto cero no es algo rápido montado sobre un lenguaje lento. Es algo claro que el compilador vuelve a triturar hasta dejarlo exactamente igual a lo que habrías escrito a mano, de modo que nunca pagas por la claridad. “Me gusta que mi código sea elegante y eficiente”, ha dicho, y la palabra que importa es la y. Detesta tener que elegir entre ambas.3

Contexto

Bjarne Stroustrup nació el 30 de diciembre de 1950 en Aarhus, Dinamarca.4 Estudió matemáticas y ciencias de la computación en la Universidad de Aarhus, y luego viajó a Inglaterra para hacer un doctorado en el Computing Laboratory de la Universidad de Cambridge, que completó en 1979. Su tesis, “Communication and control in distributed computer systems”, trataba sobre cómo distribuir el trabajo de un sistema operativo a través de una red de computadoras.4

Para estudiar ese problema necesitaba construir un simulador, y escribió la primera versión en Simula, el lenguaje noruego (diseñado por Ole-Johan Dahl y Kristen Nygaard) que había presentado al mundo las clases y los objetos. A Stroustrup le encantó. Las abstracciones de clases de Simula le permitían organizar un programa grande e intrincado según cómo estaba organizado el problema, no según cómo estaba organizada la máquina, y el programa era un placer de escribir y de modificar. Luego intentó ejecutarlo a escala y las abstracciones se derrumbaron bajo su propio costo. La implementación era demasiado lenta para ser práctica. Reescribió el simulador en BCPL, un lenguaje de sistemas despojado, y recuperó la velocidad, pero BCPL era de tan bajo nivel que construir algo grande en él era una miseria.2 El latigazo fue la herida formativa. Había usado el lenguaje expresivo y lo pagó en rendimiento; luego usó el lenguaje rápido y lo pagó en todo lo demás. Ninguno era aceptable. Ambas mitades deberían haber sido posibles a la vez.

Llevó ese agravio a los Bell Labs, en Nueva Jersey, en 1979, donde de nuevo se enfrentó a un problema de sistemas distribuidos: analizar el tráfico del núcleo de UNIX a través de una red. Recordando Cambridge, se propuso añadir a C el poder organizador de Simula, un lenguaje ya rápido y cercano al hardware, el lenguaje de sistemas de UNIX, sin sacrificar un ápice de la velocidad de C.45 Llamó al resultado “C con Clases”. En 1983, su colega Rick Mascitti sugirió el nombre C++, el operador de incremento aplicado al propio C: el siguiente C, uno mejor, la misma máquina por debajo.5

Bjarne Stroustrup hablando

La obra

De C con Clases a C++: un C mejor que no cuesta nada

El movimiento original (1979-1983) fue deliberadamente modesto y exactamente correcto. Tomar C, ya rápido, ya mapeado directamente al hardware, ya el lenguaje de sistemas en el que la gente confiaba, y agregar las cosas que Simula le había enseñado a desear: clases, mejor verificación de tipos, abstracción de datos.5 Y, crucialmente, las agregó como una capa que los programadores de C no tenían que pagar. Un programa en C seguía siendo un programa válido en C++. Una struct que no usaba ninguna de las nuevas funciones se compilaba a los mismos bytes de siempre. El nuevo poder era opcional, y usarlo costaba solo lo que habría costado el C equivalente escrito a mano. Ese es el principio de sobrecosto cero en embrión, presente antes de que tuviera un nombre para él: no graves a quienes no usan la función, y no permitas que la función genere un código peor que el que ellos mismos habrían escrito.

Documentó y estabilizó el lenguaje en The C++ Programming Language (1985), el libro que lo puso al alcance del público general, y luego dedicó décadas a defender su núcleo a través del diseño de cada función posterior.4

El principio de sobrecosto cero

El principio de sobrecosto cero es la idea que sostiene todo, la regla contra la que se mide cada función de C++. Stroustrup lo enuncia en dos partes: “Lo que no usas, no lo pagas (en tiempo ni en espacio) y además: lo que sí usas, no podrías programarlo mejor a mano.”1 La primera cláusula es una política tributaria: ninguna función puede imponer un costo al código que no la usa. La segunda es una vara de calidad: una función que usas debe compilarse a un código no peor que el que un programador cuidadoso habría producido a mano para ese trabajo específico. Las plantillas, constexpr, la semántica de movimiento y los contenedores y algoritmos de la biblioteca estándar están todos diseñados para honrarlo; las dos excepciones famosas, la información de tipos en tiempo de ejecución y las excepciones, son justamente las dos funciones para las que los compiladores ofrecen interruptores que las desactivan, precisamente porque doblan la regla.6

La recompensa es eso que suena imposible hasta que ves el ensamblador: la forma expresiva y la forma ajustada a mano producen el mismo código máquina.

Bjarne Stroustrup

Esa identidad – lo expresivo y lo ajustado a mano colapsando en una sola salida – es la razón por la que el principio es tan moral como técnico. Le quita al ingeniero su excusa de siempre. Si la claridad fuera genuinamente cara, podrías justificar escribir la versión fea y rápida “porque tiene que ser rápida”. La apuesta de Stroustrup es que esa excusa suele ser una mentira: que una abstracción bien diseñada te permite tener la versión legible y la rápida, porque son la misma versión. El costo se pagó una vez, lo pagó el diseñador del lenguaje, para que nunca volviera a pagarlo el programador.

RAII y los recursos deterministas

El principio necesitaba un mecanismo para la parte más desordenada de la programación de sistemas: los recursos que deben adquirirse y luego liberarse de manera confiable – memoria, archivos, bloqueos, sockets. La recolección de basura responde a esto renunciando al determinismo: la limpieza ocurre en algún momento, según el calendario del recolector, lo cual es intolerable para un bloqueo o un descriptor de archivo. La respuesta de Stroustrup, a la que llamó RAII – Resource Acquisition Is Initialization (la adquisición de recursos es inicialización) – ata el ciclo de vida de un recurso al ciclo de vida de un objeto en la pila.7 Adquieres el recurso en un constructor; lo liberas en el destructor; y como C++ garantiza que el destructor de un objeto en la pila se ejecuta en el instante en que sale del alcance – normalmente o por una excepción, en orden inverso al de la construcción – el recurso se libera exactamente cuando debe, de forma determinista, sin recolector y sin un free manual que olvidar.7

RAII es el sobrecosto cero vuelto concreto. La llamada al destructor es código que de todos modos habrías tenido que escribir a mano; el lenguaje solo garantiza que no puedas olvidarlo. Obtienes una limpieza automática, a prueba de excepciones y determinista, y no pagas nada que no hubieras pagado de todos modos escribiendo tú mismo la limpieza. Es el patrón de C++ que lenguajes posteriores, Rust de forma destacada, adoptarían después casi por completo.

Estandarización y “no dejar espacio para un lenguaje de más bajo nivel”

Stroustrup no mantuvo C++ como un proyecto personal. Lo llevó al comité de estándares – ANSI desde 1989, ISO desde 1991 – y formó parte de él durante décadas, presidiendo el Evolution Working Group, para que C++ fuera un estándar estable y neutral respecto a los proveedores, y no el dialecto de una sola empresa.4 Y le dio al comité una regla constitucional, extraída de sus principios de diseño en The Design and Evolution of C++: “No dejar espacio para un lenguaje de más bajo nivel por debajo de C++ (salvo el ensamblador).”8 El razonamiento es exacto: si pudieras escribir código más eficiente en algún lenguaje entre C++ y el hardware desnudo, entonces ese lenguaje se convertiría en el lenguaje de sistemas preferido y C++ perdería su razón de ser.8 Para seguir siendo viable, C++ debe conservar el acceso directo al hardware de C, su control sobre la disposición de los datos y sus tipos primitivos que se mapean uno a uno con la máquina.8 Nada debería interponerse entre la abstracción y el silicio salvo el ensamblador. El principio de sobrecosto cero, enunciado como frontera competitiva: ser el lenguaje de más alto nivel que aun así no deja nada sobre la mesa.

El método

El método es una sola apuesta – claridad y velocidad son lo mismo si diseñas la abstracción correctamente – impuesta como un conjunto de reglas estrictas.

Medir cada función contra el sobrecosto cero. Ninguna función puede gravar al código que no la usa, y ninguna función puede generar un código peor que su equivalente escrito a mano. Esta es la prueba que toda adición a C++ ha tenido que superar durante cuarenta años.16

Confiar en el programador y mantenerse multiparadigma. C++ admite los estilos procedural, orientado a objetos, genérico y funcional porque Stroustrup se negó a decidir por ti cómo organizar tu problema. El lenguaje te da las herramientas y asume que conoces tu dominio mejor que el diseñador del lenguaje.6

Mapear directamente al hardware. Conservar la correspondencia uno a uno de C entre los tipos primitivos, la disposición de los datos y la máquina. La abstracción se asienta sobre el metal, no sobre un entorno de ejecución que lo oculta.8

Hacer la limpieza determinista, no eventual. RAII vincula el ciclo de vida del recurso al ciclo de vida del objeto, de modo que la liberación ocurre en un instante conocido, a prueba de excepciones, sin recolector de basura y sin nada que recordar liberar.7

Estabilizarlo en abierto. Entregar el lenguaje a un comité internacional de estándares en lugar de ser su dueño, para que C++ sea un estándar público duradero y ningún proveedor por sí solo pueda bifurcarlo.4

Cadena de influencia

Quiénes lo formaron

Ole-Johan Dahl y Kristen Nygaard, a través de Simula. Simula le enseñó a Stroustrup para qué sirve la abstracción – permitir que un programa se estructure según cómo está estructurado el problema – y su lentitud le enseñó la otra mitad de la lección: que la abstracción no vale nada si no puedes permitirte usarla. C++ es el intento de conservar el regalo de Simula sin pagar ninguno de sus costos. (Influencia directa y formativa)

BCPL y la cultura de la programación de sistemas en torno a C y UNIX. BCPL le dio el dolor contrario – velocidad pura sin forma de organizar nada grande – y C, el lenguaje de UNIX en los Bell Labs, le dio la base rápida y mapeada al hardware sobre la cual construir C++, encima de él en lugar de en su lugar.25 (Influencia directa)

Bell Labs. La misma institución que produjo C y UNIX le dio a Stroustrup el problema de sistemas distribuidos que dio inicio a “C con Clases” y la cultura de investigación que le permitió dedicar años a acertar con el lenguaje. (Influencia formativa)

A quiénes formó

La infraestructura del mundo corre sobre su lenguaje. Sistemas operativos, navegadores, bases de datos, motores de videojuegos, compiladores, sistemas de trading de alta frecuencia, el software de vuelo de los róvers de Marte: el núcleo crítico en rendimiento de la computación moderna es desproporcionadamente C++. El trabajo de pocos ingenieros sostiene tanto peso.

El movimiento de las abstracciones de costo cero. El principio de Stroustrup, rebautizado como “zero-cost abstractions”, se convirtió en un objetivo fundacional explícito de Rust, que adoptó RAII (como ownership y Drop), la destrucción determinista y la regla de que las construcciones de alto nivel deben compilarse a código máquina óptimo. Lenguajes como D y Carbon descienden del mismo linaje. La idea de que no deberías pagar por la claridad es hoy corriente, y es suya.6

El hilo conductor

John Carmack quiere que el bucle interno haga el mínimo trabajo que la física permite – “la velocidad de la luz es un asco”, la máquina gobernada por límites duros, cada ciclo desperdiciado es una elección. Stroustrup le entrega a Carmack las herramientas para escribir ese bucle de forma legible: una abstracción de sobrecosto cero es la promesa de que la versión clara y la más pegada al metal son el mismo código máquina, así que nunca tienes que escoger. Donde Barbara Liskov le dio a la abstracción su teoría – la abstracción de datos, el contrato que un tipo le debe a sus usuarios, el linaje de Simula a CLU de “deberías programar contra lo que algo hace, no contra cómo funciona” – Stroustrup le dio a esa teoría un cuerpo cuya ejecución no cuesta nada. Y donde Alan Kay imaginó los objetos como pequeñas computadoras que se pasan mensajes, una conversación de enlace tardío en tiempo de ejecución, Stroustrup tomó el camino opuesto hacia la misma palabra: sus objetos se resuelven en tiempo de compilación y se disuelven en código máquina desnudo, la POO como herramienta organizadora de sobrecosto cero en lugar de un bus de mensajes vivo. El mismo vocabulario, dos filosofías – una optimiza para la flexibilidad, la otra para la cuenta en tiempo de ejecución. (Puente de la serie)

Lo que me llevo de esto

La lección que conservo es que “expresivo o rápido” casi siempre es una falsa disyuntiva que un mal diseño te impone. Cuando me sorprendo escribiendo la versión fea “porque tiene que ser rápida”, el principio de Stroustrup es la acusación: eso no es una ley de la computación, es no haber dado con la abstracción que se compila por sí sola a la cosa rápida. El trabajo consiste en diseñar tan bien la versión clara que la máquina produzca a partir de ella el código óptimo – pagar el costo una vez, en el diseño, para no volver a pagarlo en cada línea que la usa. Esa es la misma vara que la calidad como única variable: la pregunta nunca es “¿puedo permitirme hacer esto claro?”, sino “¿por qué mi abstracción tiene tantas fugas que la claridad cuesta algo?”.

En el mundo en el que construyo ahora – agentes, bucles de herramientas, sistemas de IA – la tentación es lo opuesto al sobrecosto cero: apilar un envoltorio sobre otro, gastar una llamada al modelo para tapar un camino lento, dejar que cada abstracción conveniente sume en silencio una latencia que nadie mide. El movimiento de Stroustrup es exigir que la interfaz conveniente se compile hasta la eficiente – que la API limpia y el camino rápido sean el mismo camino, con el costo pagado en el diseño de la capa local en lugar de cobrarse a cada llamada que la atraviesa. Esa convicción – que el gusto es un sistema técnico contra el que puedes sostener una regla dura, no una vibra que afirmas – es el hilo conductor que va de un simulador de 1979 que corría demasiado lento a una capa local para agentes de 2026 que no debería.

Preguntas frecuentes

¿Cuál es la filosofía de ingeniería de Bjarne Stroustrup?

La convicción de Stroustrup es que nunca deberías tener que elegir entre código expresivo y de alto nivel y el rendimiento a nivel de hardware. Construyó C++ sobre el principio de sobrecosto cero: una función del lenguaje no debe costar nada cuando no la usas, y cuando sí la usas, debe compilarse a un código no peor que el que habrías escrito a mano para esa tarea.1 A esto sumó la confianza en el programador (C++ es deliberadamente multiparadigma), el mapeo directo al hardware, la gestión determinista de recursos mediante RAII y la estabilización del lenguaje como estándar ISO abierto en lugar de ser su dueño.467

¿Qué es el principio de sobrecosto cero?

Es la regla que Stroustrup enuncia en dos partes: “Lo que no usas, no lo pagas (en tiempo ni en espacio) y además: lo que sí usas, no podrías programarlo mejor a mano.”1 La primera mitad significa que una función no usada no impone ningún costo en tiempo de ejecución ni en memoria; la segunda, que una función que sí usas genera un código al menos tan bueno como el que un programador competente escribiría a mano. Es la prueba que toda función de C++ debe superar. Las dos funciones que la doblan – la información de tipos en tiempo de ejecución y las excepciones – son justamente las dos que la mayoría de los compiladores te dejan desactivar.6 El principio es la razón por la que una abstracción de C++ como un puntero inteligente o un iterador puede compilarse al mismo código máquina que la versión cruda y ajustada a mano.

¿Qué es RAII y por qué lo inventó Stroustrup?

RAII – Resource Acquisition Is Initialization (la adquisición de recursos es inicialización) – es el patrón de C++, bautizado por Stroustrup, que ata el ciclo de vida de un recurso al ciclo de vida de un objeto en la pila: adquieres el recurso en el constructor del objeto y lo liberas en su destructor.7 Como C++ garantiza que el destructor de un objeto en la pila se ejecuta en el momento en que sale del alcance – ya sea que la función retorne normalmente o que una excepción desenrolle la pila – recursos como la memoria, los archivos, los bloqueos y los sockets se liberan de forma determinista, en un instante conocido, sin recolector de basura y sin nada que liberar manualmente. Te da una limpieza automática, a prueba de excepciones y con sobrecosto cero, y Rust lo adoptó después casi por completo como ownership y Drop.7

¿Por qué creó Stroustrup C++ y de dónde surgió?

Mientras escribía en Cambridge su doctorado sobre sistemas distribuidos (completado en 1979), Stroustrup construyó un simulador en Simula y amó sus abstracciones de clases, pero lo encontró demasiado lento a escala; lo reescribió en BCPL, que era rápido pero de tan bajo nivel que no servía para construir nada grande.2 Ninguno de los dos canjes era aceptable, así que en los Bell Labs – enfrentado a un problema de análisis del núcleo de UNIX a través de una red – se propuso añadir a C el poder organizador de Simula sin perder la velocidad de C. Lo llamó “C con Clases” (1979); su colega Rick Mascitti sugirió el nombre C++ en 1983.45 En 2018, la National Academy of Engineering le otorgó el Charles Stark Draper Prize – la máxima distinción de ingeniería en Estados Unidos, un premio de 500.000 dólares que suele llamarse el Premio Nobel de la ingeniería – por su trabajo al diseñar e implementar el lenguaje de programación C++.9


Fuentes


  1. “What is the zero-overhead principle?” FAQ de la Standard C++ Foundation (isocpp.org), mantenida con Stroustrup. “What you don’t use, you don’t pay for (in time or space) and further: What you do use, you couldn’t hand code any better.” Véase también Bjarne Stroustrup, “C++ – an Invisible Foundation of Everything,” Overload (ACCU), 2021. 

  2. “C++,” Wikipedia. Mientras escribía su doctorado en Cambridge, Stroustrup usó Simula pero lo encontró demasiado lento a escala y reescribió su simulador en BCPL; concluyó que Simula tenía funciones útiles para el desarrollo de software de gran escala, pero era demasiado lento para uso práctico, mientras que BCPL era rápido pero de demasiado bajo nivel. Relato de primera mano: Bjarne Stroustrup, “A History of C++: 1979–1991,” HOPL-II (su propio artículo). 

  3. Bjarne Stroustrup, “Quotes,” stroustrup.com (su propio sitio). “I like my code to be elegant and efficient. The logic should be straightforward to make it hard for bugs to hide, the dependencies minimal to ease maintenance…” y “Code should [be] elegant and efficient; I hate to have to choose between those.” 

  4. “Bjarne Stroustrup,” Wikipedia. Nacido el 30 de diciembre de 1950 en Aarhus, Dinamarca; doctorado por la Universidad de Cambridge en 1979, con la tesis “Communication and control in distributed computer systems”; dirigió el departamento de Large-scale Programming Research en los Bell Labs; The C++ Programming Language (1985); miembro fundador del comité de estándares de C++ (ANSI desde 1989, ISO desde 1991), presidió el Evolution Working Group; más tarde Texas A&M (2002-2014), Morgan Stanley (2014-2022), profesor titular en Columbia (desde 2022). Véase también la biografía y FAQ de Stroustrup en stroustrup.com. 

  5. Bjarne Stroustrup, “Bjarne Stroustrup’s FAQ,” stroustrup.com. “I wanted to write efficient systems programs in the styles encouraged by Simula67… The specific tasks that caused me to start designing and implementing C++ (initially called ‘C with Classes’) had to do with distributing operating system facilities across a network.” Sobre el cambio de nombre de 1983 por Rick Mascitti: “C++,” Wikipedia. 

  6. “Zero-overhead principle,” cppreference.com. Enuncia el principio tal como lo definió Stroustrup y señala las dos funciones que no lo siguen – la identificación de tipos en tiempo de ejecución y las excepciones – y que los compiladores suelen incluir interruptores para desactivarlas. Sobre el diseño multiparadigma y la influencia en las “zero-cost abstractions” de Rust: “Zero-overhead principle” y la documentación de Rust sobre abstracciones de costo cero. 

  7. “Resource acquisition is initialization,” Wikipedia. El término RAII fue acuñado por Stroustrup; la técnica se desarrolló para la gestión de recursos a prueba de excepciones en C++ durante 1984-1989, principalmente por Stroustrup y Andrew Koenig, y se presentó en su libro de 1994 The Design and Evolution of C++. La liberación del recurso ocurre en el destructor; C++ garantiza que los objetos con duración de almacenamiento automática se destruyen al final del alcance que los contiene, en orden inverso al de la construcción, lo que brinda una limpieza determinista y a prueba de excepciones. 

  8. Bjarne Stroustrup, The Design and Evolution of C++ (1994), reglas de diseño, según se discuten en “(Re)affirm design principles for future C++ evolution,” artículo P3466R0 del comité ISO C++. “Leave no room for a lower-level language below C++ (except assembler)” – el razonamiento es que si pudiera escribirse código más eficiente en algún lenguaje de más bajo nivel, ese lenguaje se convertiría en el lenguaje de sistemas preferido; para seguir siendo viable, C++ debe conservar el acceso directo al hardware de C, su control sobre la disposición de los datos y sus tipos primitivos que se mapean uno a uno con el hardware. 

  9. “Bjarne Stroustrup receives Draper Prize, engineering’s top U.S. honor,” Standard C++, 2018: el Charles Stark Draper Prize de 2018, “un premio bianual de 500.000 dólares… considerado el Premio Nobel de la ingeniería”, otorgado a Stroustrup “por su trabajo al diseñar e implementar el lenguaje de programación C++”. La propia mención de la National Academy of Engineering lo expresa “por conceptualizar y desarrollar el lenguaje de programación C++” (NAE, “Computer Science Pioneer Bjarne Stroustrup to Receive the 2018 Charles Stark Draper Prize for Engineering,” vía EurekAlert, 2018). También recibió la IET Faraday Medal en 2017 por su trabajo pionero en C++. 

Artículos relacionados

Filosofía de la ingeniería: Barbara Liskov, el contrato es el tipo

Barbara Liskov convirtió la abstracción de datos en una primitiva de programación: un tipo es el contrato que cumple, y …

18 min de lectura

Filosofía de ingeniería: John Carmack, el rendimiento como oficio moral

John Carmack trata el rendimiento como una cuestión moral. Reduce todo al núcleo rápido y simple, comprende el problema …

14 min de lectura

The Shader Gallery That Lied: Debugging 216 WebGL Presets

A user said the shader playground looked broken. Pixel-readback testing found 30 dead presets, 11 that never compiled, a…

11 min de lectura