Swift presenta una coexistencia peculiar: es un lenguaje en el que quien empieza a programar puede comenzar en Playgrounds con una sola línea, print("Hello"), mientras la biblioteca estándar del mismo lenguaje entrelaza genéricos y macros. Una app educativa de programación para primaria (Swift Playgrounds) y código de sistemas a nivel de compilador comparten la sintaxis.
Normalmente, los lenguajes eligen entre dos opciones: ser fáciles de aprender (tipo Python) o ser potentes (tipo C++). Swift declaró que tendría ambas cosas, y el principio de diseño que lo hace posible tiene un nombre: divulgación progresiva, Progressive Disclosure.
Este artículo es la segunda parte de la serie sobre la filosofía de Swift. Si Safe, Fast y Expressive, tratados en la primera parte, representan la filosofía de «qué construir», Progressive Disclosure representa la filosofía de «en qué orden mostrarlo».
Qué es la divulgación progresiva — Ocultarlo hasta que haga falta
Progressive Disclosure es originalmente un término de diseño de UI. Primero muestra solo las funciones más usadas y oculta las avanzadas detrás de «Más», para no abrumar a los principiantes. Como una app de cámara que muestra grande solo el botón de disparo y oculta ISO y la velocidad de obturación en el modo Pro.
El equipo de Swift aplicó este principio a la sintaxis del lenguaje. También es un objetivo declarado oficialmente. Chris Lattner ha descrito Swift en varias entrevistas como «un lenguaje con divulgación progresiva de la complejidad (progressive disclosure of complexity)». Incluso hoy, las revisiones de propuestas de Swift Evolution preguntan si una sintaxis perjudica la progressive disclosure.
Si reducimos el principio a una sola frase, es esta:
Un concepto que aún no se ha aprendido no debe aparecer en el código de quien todavía no lo conoce.
No se trata simplemente de que «también haya funciones fáciles». Es una exigencia mucho más fuerte: mientras se escribe código sencillo, los conceptos difíciles ni siquiera deben entrar en el campo de visión.
Comparación de Hello World — Contar los personajes
Basta con comparar Hello World para ver qué cambia realmente este principio.
// Java (11 anterior)
public class Main {
public static void main(String[] args) {
System.out.println("Hello, world!");
}
}
Para entender por completo estas cinco líneas hay que conocer las clases, el control de acceso, static, los métodos, los arrays y el objeto de salida estándar. En el código del primer día aparecen seis personajes. Lo único que puede decir el profesor es: «Memorízalo por ahora; ya lo explicaré después».
// Swift
print("Hello, world!")
Swift usa una sola línea. Puedes escribir código ejecutable directamente en el nivel superior del archivo, sin punto y coma ni import. Solo aparece un personaje: una llamada a función. No hace falta «memorízalo por ahora».
Ese es el punto clave. Swift también tiene clases, control de acceso y static. Simplemente no aparecen en este código. Los conceptos no faltan; son invisibles para quien todavía no los necesita.
Varias capas de una misma función — La sintaxis se abre por niveles
Al examinar la sintaxis de Swift, se descubre que una misma función se superpone en varias capas de dificultad. Veamos algunos ejemplos representativos.
Función → cierre → cierre abreviado. Para ordenar arrays, al principio basta con pasar una función con nombre.
func byLength(_ a: String, _ b: String) -> Bool {
a.count < b.count
}
names.sorted(by: byLength)
Cuando aprendes los cierres, puedes escribirlos inline.
names.sorted(by: { a, b in a.count < b.count })
Cuando dominas la sintaxis abreviada, puedes reducirlo así.
names.sorted { $0.count < $1.count }
Los tres códigos hacen exactamente lo mismo. Puedes ordenar desde el primer día sin conocer los cierres finales ni $0, y después escribir de forma más concisa cuando los aprendas. Aprender una nueva capa es una recompensa, no un requisito.
Inferencia de tipos → tipos explícitos. Se empieza con let age = 30, y las anotaciones de tipo aparecen solo cuando hacen falta, por ejemplo para especificar precisión o definir un límite de API. No se obliga a escribir let age: Int = 30 desde el principio.
init memberwise automático → init personalizado. En un struct, el compilador genera el inicializador aunque no escribas código de inicialización. Solo necesitas aprender la sintaxis de init cuando aparece la necesidad de lógica de inicialización.
Ignorar errores → try? → do-catch → throws tipificado. El manejo de errores también ofrece una escalera cuyos peldaños puedes elegir según tu nivel de interés.
Complejidad fuera del campo de visión — Lo que funciona sin verse
Más impresionante que la escalera sintáctica es la estructura en la que las funciones avanzadas sostienen el código para principiantes desde detrás.
La declaración real de ese print("Hello")print es la siguiente.
func print(
_ items: Any...,
separator: String = " ",
terminator: String = "\n"
)
Argumentos variables, parámetros predeterminados y el tipo Any. La declaración contiene tres conceptos que el principiante aún no conoce, pero quien llama no necesita saber ninguno. Gracias a la función avanzada de los parámetros predeterminados, el uso para principiantes puede ser sencillo. Las funciones avanzadas se utilizan para absorber complejidad, no para añadirla.
La interpolación de cadenas ("이름: \(name)") sigue la misma estructura. Para quien la usa, es sintaxis básica que se aprende en la primera semana, pero debajo se oculta toda una capa de personalización llamada protocolo ExpressibleByStringInterpolation. Gracias a esta capa, Text de SwiftUI acepta incluso imágenes y formato de fechas mediante interpolación de cadenas. El 99 % de los usuarios la utiliza bien durante toda su vida sin saber que existe el protocolo. Solo los autores de bibliotecas necesitan abrir esa puerta.
SwiftUI es la culminación de este principio.
struct ContentView: View {
var body: some View {
Text("Hello")
}
}
Bajo este código breve se encuentran los tipos opacos (some), resultBuilder y los tipos asociados de protocolos. Todos están entre las funciones más difíciles de Swift, pero quien crea una UI por primera vez puede mostrar una pantalla sin saber siquiera que existen. La pregunta «¿Qué es some View?» suele aparecer meses después; entonces es cuando toca aprenderlo.
El caso contrario — Qué ocurre sin este principio
El valor del principio se vuelve evidente al compararlo con lenguajes que no lo tienen.
Al aprender C++, conceptos de memoria como los punteros, las referencias y los constructores de copia quedan expuestos en la superficie de la sintaxis desde la primera semana. No están ocultos: son puertas inevitables. Rust exige por adelantado a todos los usuarios la propiedad y los tiempos de vida para garantizar la seguridad. Es un diseño excelente, pero según el criterio de «cuántos conceptos se necesitan para escribir el primer programa», está en el extremo opuesto.
Lo interesante es que otros lenguajes han avanzado en la misma dirección que Swift. Java introdujo en 21 clases implícitas que se ejecutan con solo void main() (JEP 445, una propuesta de mejora de Java), y C# añadió las instrucciones de nivel superior. Ambos persiguen lo mismo: eliminar la ceremonia del primer código de un principiante. Los lenguajes de generaciones anteriores han tardado una década en alcanzar lo que Swift estableció como valor predeterminado en 2014.
También hay críticas — Donde se rompe la escalera
Siendo justos, no todo el mundo considera que Swift haya seguido este principio a la perfección.
La principal crítica es que, a medida que crecía el lenguaje, los peldaños intermedios se hicieron más empinados. La introducción es fácil, pero al pasar al código de producción o de bibliotecas, las restricciones genéricas, la diferencia entre some y any y las anotaciones Sendable aparecen todas a la vez. En especial, se ha señalado que la strict concurrency de Swift 6 choca frontalmente con progressive disclosure porque «muestra errores de compilación en el código de alguien que aún no ha aprendido concurrencia». Incluso Chris Lattner ha comentado que Swift se ha vuelto más complejo.
El equipo de Swift también es consciente de esta tensión. Varias propuestas posteriores a Swift 6.1 (opciones de aislamiento predeterminado de actores, main sin nombre, entre otras) muestran que se están orientando a «evitar que el usuario encuentre conceptos de concurrencia hasta que los necesite». Lo más preciso es considerar el principio no como algo terminado, sino como un valor que el equipo aún lucha por preservar.
Lecciones para profesionales — Un criterio para diseñar API
Este principio no se aplica solo a los usuarios del lenguaje. Es un criterio de diseño que se aplica directamente a las funciones y módulos que creamos cada día.
Convertir los casos habituales en gratuitos mediante parámetros predeterminados. Como el separator de print, oculta tras valores predeterminados las opciones que al 90 % de quienes llaman no les importan. Compáralo con una API que exige un objeto de configuración completo.
Un único punto de entrada sencillo; las sobrecargas avanzadas, detrás. URLSession es un buen ejemplo. data(from: url) Puedes empezar con una sola línea, y quienes necesitan delegados y configuración tienen otra capa disponible.
Si conceptos desconocidos se filtran al punto de llamada, es una señal de diseño. Si para usar mi biblioteca tienes que leer una firma genérica, la complejidad que debería haberse absorbido se está filtrando. Al igual que print mantiene sencillo el punto de llamada aunque use argumentos variables, la complejidad debe ser asumida por la declaración.
En resumen, una buena API no es la que tiene pocas funciones, sino aquella en la que las funciones que aún no has aprendido permanecen invisibles.
Resumen
- Progressive Disclosure es el principio oficial de diseño de Swift: «hacer que los conceptos aún no aprendidos no aparezcan en el código».
- El Hello World de una sola línea con print, la inferencia de tipos, el init automático y la escalera de cierres abreviados son productos de este principio.
- Las funciones avanzadas (parámetros predeterminados, resultBuilder y el protocolo de interpolación de cadenas) están diseñadas para absorber la complejidad del código para principiantes.
- Hay puntos en los que el principio se ha tambaleado, como la concurrencia de Swift 6, y el equipo del lenguaje todavía está reparando la escalera.
- Podemos aplicar el mismo criterio a nuestras API: los usos habituales deben resolverse en una línea y las declaraciones deben absorber la complejidad.
La próxima parte será la tercera historia sobre filosofía. ¿Por qué la biblioteca estándar de Swift está hecha casi por completo de structs? Trataremos el principio de priorizar los tipos por valor.
Seguir leyendo
- [Filosofía de Swift #3] ¿Por qué Swift está hecho completamente de structs? Guía completa del principio de priorizar los tipos por valor
- [Filosofía de Swift #4] ¿Qué es SE-0296? Cómo nace la sintaxis de Swift: guía completa de Swift Evolution
- [Swift intermedio #1] Guía completa de Swift ARC: elige weak o unowned según la relación de tiempos de vida

![Imagen de portada de [Filosofía de Swift #2] ¿Qué es Progressive Disclosure?](/assets/images/posts/290b697a-f011-4cb7-8331-0a439b666fcd/1.jpg)