🕊️ Swift — 2014

⬅️ Atlas · 🗂️ Todas las fichas · 📚 Índice de clases

Swift es el sucesor de Objective-C, y su diseño se puede resumir en una frase: tomar todo lo que la investigación en lenguajes había demostrado y meterlo en un lenguaje que millones de personas iban a usar el mes siguiente. Tipos algebraicos, opcionales, inmutabilidad por defecto y concurrencia estructurada — con la interfaz gráfica de Apple detrás.

🎯 Por qué está en este programa

Swift es un primo de la familia móvil / moderno (Atlas), junto a Dart, y desciende directamente de Objective-C.

Aporta al programa la gestión de memoria por conteo automático de referencias sin recolector (clase 131), con el problema de los ciclos a la vista; y la concurrencia estructurada con actores integrados en el sistema de tipos (clases 133 y 136), que es de las implementaciones más completas que existen.

Año 2014; ABI estable en 2019; Swift 6 en 2024, con concurrencia estricta
Autoría Chris Lattner —creador de LLVM— y equipo, Apple
Familia Móvil / moderno; con Objective-C, Rust, Haskell y C# dentro
Paradigma Multiparadigma: OO por protocolos, funcional e imperativo
Tipado Estático, fuerte, con inferencia y opcionales en el tipo
Memoria ARC: conteo automático de referencias, sin recolector y sin pausas
Ejecución Compilado a nativo sobre LLVM
Estado 🟢 Dominante en el ecosistema Apple; creciendo en servidor y embebido

📜 Historia

Chris Lattner había creado LLVM como proyecto de máster y lo había llevado a Apple, donde se convirtió en la base de todas sus herramientas. En 2010 empezó Swift en secreto, y Apple lo presentó en la WWDC de 2014 sin previo aviso.

El encargo era difícil: sustituir a Objective-C —treinta años de marcos y de código— sin romper nada. La solución fue la interoperabilidad total: Swift y Objective-C conviven en el mismo proyecto, y Swift importa las APIs de Objective-C con tipos precisos gracias a las anotaciones de nulabilidad que Apple añadió a Objective-C precisamente para eso.

Los hitos:

Y desde 2015 es de código abierto, con versiones para Linux y Windows y un empuje serio hacia el servidor y los sistemas embebidos.

🏭 Dónde vive hoy

🧠 Lo que enseña: ARC y concurrencia en el tipo

Uno, el conteo automático de referencias (clase 131):

class Nodo {
    var siguiente: Nodo?          // referencia FUERTE: mantiene vivo
    weak var padre: Nodo?          // DÉBIL: no cuenta, y se pone a nil al morir
    unowned let dueño: Documento    // sin dueño: no cuenta y NO se pone a nil
}

El compilador inserta retain y release, así que no hay recolector y no hay pausas — lo que importa mucho en una animación a 120 fotogramas por segundo (clase 152).

Y el precio es el que la clase 131 explica: los ciclos no se recogen. Dos objetos que se apuntan mutuamente con referencias fuertes no se liberan nunca, y el programador tiene que romper el ciclo con weak o unowned.

Es el mismo modelo que Objective-C con ARC, que Rust con Rc/Weak y que el conteo de referencias de Python y PHP — con la diferencia de que estos dos últimos sí tienen un detector de ciclos adicional.

Dos, la concurrencia en el sistema de tipos (clase 136):

actor Banco {
    private var saldo = 0.0            // ← nadie puede tocarlo desde fuera sin await
    func depositar(_ x: Double) { saldo += x }
}

let b = Banco()
await b.depositar(100)                  // ← el await marca el cruce de frontera

Un actor aísla su estado: solo se accede desde dentro, y desde fuera hay que esperar. El compilador lo garantiza (clase 133).

Y Sendable es el otro lado: un tipo marcado como Sendable puede cruzar fronteras de concurrencia con seguridad, y el compilador comprueba que no se envía nada que no lo sea. Es exactamente el papel de Send/Sync en Rust, integrado en un lenguaje con ARC.

Y tres, los opcionales, que ya no sorprenden a nadie precisamente porque Swift ayudó a popularizarlos:

var nombre: String = "Ana"      // no puede ser nil
var apodo: String? = nil         // puede
if let a = apodo { ... }          // desempaquetado seguro
guard let a = apodo else { return }

🔄 Lo que se ha modernizado

⚙️ Cómo se ejecuta hoy

swift main.swift < entrada.txt        # ejecutar como guion
swiftc -O main.swift -o venta          # compilar optimizado

swift build && swift test               # con Swift Package Manager (clases 143 y 139)
swift package init --type executable

🧪 El programa de la clase 041 en Swift

Esta versión se escribe aquí y no está verificada en CI (clase 040).

import Foundation

guard let linea = readLine() else { exit(1) }
let v = linea.split(separator: " ").compactMap { Double($0) }
guard v.count == 3 else { exit(1) }

let total = v[0] * v[1] * (1 - v[2])
print(String(format: "Total: %.2f", total))

Lo que hay que ver.

📚 Fuentes y bibliografía


⏮️ Volver al Atlas · 🗂️ Todas las fichas · 🔗 Relacionadas: Objective-C · Rust · Kotlin · Dart · C++