Ao escrever código em Swift, cedo ou tarde surgem perguntas: por que os opcionais são tão rigorosos? Por que os arrays são copiados? Por que existe guard? Ao investigar essas questões, chegamos aos três objetivos originais do Swift: Safe (seguro), Fast (rápido) e Expressive (expressivo).
O site oficial do Swift (swift.org) declara esses três objetivos no início da apresentação da linguagem. Eles não são apenas slogans de marketing. Quase todos os recursos adicionados ao Swift nos últimos dez anos passaram por esses três critérios. Este artigo resume como cada filosofia foi implementada na linguagem e qual lado o Swift escolheu quando elas entraram em conflito.
Este é o primeiro artigo da série sobre a filosofia do Swift. A origem do Swift—por que Chris Lattner abandonou o Objective-C—é tratada em outro artigo; aqui, o foco é em como ele cresceu depois de nascer e nos princípios que o moldaram.
Safe — O compilador impede bugs antecipadamente
A segurança é o valor de maior prioridade no design do Swift. Aqui, segurança significa “tornar erros difíceis”. Em vez de depender da boa intenção ou da concentração do programador, o Swift bloqueia os caminhos para erros no nível da linguagem.
O principal exemplo são os opcionais. No Objective-C, qualquer ponteiro podia ser nil, e enviar uma mensagem para nil era ignorado silenciosamente. Não havia crash, mas era difícil rastrear onde o bug começava. Em linguagens da família C, ocorria um crash. É famosa a descrição de Tony Hoare de referências null como “um erro de um bilhão de dólares”.
O Swift levou esse problema para o sistema de tipos. Uma variável que pode não ter valor precisa ser declarada com um ponto de interrogação no tipo, como String?, enquanto um tipo sem interrogação nunca pode ser nil. Para usar um valor que pode ser nil, o compilador exige que você faça o unwrap com if let ou guard let.
var name: String? = fetchUserName()
// Erro de compilação — opcionais não podem ser usados diretamente
// print(name.count)
if let name {
print(name.count) // Aqui a segurança é garantida
}
O bug em runtime “esqueci de verificar nil” vira o erro de compilação “não fiz unwrap do opcional”. O bug morre durante o build, antes de chegar ao usuário.
A filosofia de segurança aparece em muitos lugares além dos opcionais.
- Inicialização obrigatória das variáveis antes do uso: impede na origem bugs causados pela leitura de memória não inicializada.
- Verificação dos limites do array: se o índice sair do intervalo, o Swift para imediatamente em vez de ler uma memória arbitrária.
- Detecção de overflow de inteiros: em C, o valor muda silenciosamente; o Swift gera um trap nas operações comuns.
- Inferência de tipos, mas sem conversões implícitas: não é possível simplesmente somar
InteDouble. É inconveniente, mas vale a pena diante dos bugs sutis causados pelas conversões implícitas de C.
Há um ponto importante: a segurança do Swift está mais próxima de “não há comportamento indefinido” do que de “não há crashes”. Quando um índice sai do intervalo, o Swift provoca um crash de propósito. Parar com certeza no ponto do problema é mais seguro do que continuar com um valor estranho.
Fast — Não sacrificar desempenho pela segurança
Existem muitas linguagens seguras. O problema é que os mecanismos de segurança normalmente custam caro: garbage collection, verificação de tipos em runtime e interpretadores. As linguagens de script tradicionalmente trocavam velocidade por segurança e conveniência.
A ambição do Swift é rejeitar essa troca. O objetivo é claro: manter todos esses mecanismos de segurança e oferecer desempenho comparável ao das linguagens da família C. Para isso, várias camadas de mecanismos são combinadas.
Primeiro, ele decide o máximo possível em tempo de compilação. Swift é uma linguagem de tipagem estática; como o compilador conhece os tipos, pode gravar chamadas de método como endereços diretos durante a compilação (despacho estático). Isso contrasta com o Objective-C, que procurava todas as chamadas em runtime por meio de objc_msgSend. O mesmo princípio permite otimizações mais agressivas em classes marcadas com final.
Segundo, usa ARC (Automatic Reference Counting, contagem automática de referências) em vez de garbage collection. A contagem de referências insere código retain/release em tempo de compilação, portanto não há a pausa do GC (garbage collection), que interrompe o programa em runtime para limpar a memória. Também é uma vantagem poder prever quando a memória será liberada.
Terceiro, tipos por valor e design centrado em protocolos. Um struct pode ficar na stack sem os custos de alocação no heap e de contagem de referências, e os genéricos, após a especialização, são compilados como código dedicado a cada tipo. O compilador remove a abstração e gera código concreto, em vez de cobrar um custo em runtime. Isso é chamado de abstração sem custo.
A realidade é mais complexa que o objetivo. O Swift também tem custos ocultos, como existential containers para tipos de protocolo e o overhead de contagem de referências das classes. Portanto, a interpretação correta não é “Swift é sempre rápido”, mas “a linguagem abriu um caminho para a velocidade; se você sair dele, paga o custo”. Os artigos avançados tratarão desse caminho em detalhes.
Expressive — Fazer a intenção aparecer diretamente no código
Expressividade é o valor mais difícil de captar dos três. Em outras palavras, o código deve transmitir diretamente a intenção de quem o escreveu, permitindo dizer o que se quer sem cerimônia desnecessária.
A diferença fica clara quando comparamos com Objective-C.
// Objective-C
NSArray *names = @[@"Kim", @"Lee", @"Park"];
NSMutableArray *upper = [NSMutableArray array];
for (NSString *name in names) {
[upper addObject:[name uppercaseString]];
}
// Swift
let names = ["Kim", "Lee", "Park"]
let upper = names.map { $0.uppercased() }
Reduzir linhas importa, mas a densidade de intenção é mais importante. Uma única palavra, map, transmite toda a intenção de transformar cada elemento e criar um novo array. Na versão com for, o leitor precisa reconstruir essa intenção.
Alguns mecanismos que favorecem a expressividade são:
- Inferência de tipos: se você escrever
let names = ["Kim", "Lee"], o compilador sabe que é[String]. A segurança de tipos permanece, enquanto o ruído das anotações é reduzido. - enum e valores associados: modelam diretamente o estado “dados no sucesso, erro na falha” como
case success(Data)ecase failure(Error), mantendo estado e dados unidos. - Trailing closures, subscripts e definições de operadores: permitem que bibliotecas criem APIs que leem como sintaxe da linguagem.
- resultBuilder: a sintaxe declarativa do SwiftUI é criada com isso. A estrutura da UI coincide com a estrutura do código.
Também há um ponto de atenção. Expressividade não é sinônimo de “ser curto”. O primeiro princípio das Swift API Design Guidelines é “clareza no ponto de uso” (clarity at the point of use), e clareza vem antes da concisão. É por isso que existe uma sintaxe que adiciona rótulos de argumentos de propósito, como remove(at: 3). remove(3) é mais curto, mas o leitor pode se confundir sobre remover a terceira posição ou o valor 3.
Quem vence quando os três entram em conflito?
Com três filosofias, conflitos são inevitáveis. O verdadeiro caráter do Swift aparece na forma como ele os resolve.
Segurança vs. expressividade: fazer unwrap de opcionais claramente deixa o código mais barulhento. Permitir o uso direto, como em Python, seria mais curto. O Swift escolheu a segurança. Em compensação, adicionou sintaxes que reduzem o ruído sem abrir mão da segurança, como a forma abreviada de if let, optional chaining (user?.name) e nil coalescing (??).
Segurança vs. desempenho: a verificação dos limites do array adiciona uma comparação a cada acesso. O Swift escolhe segurança por padrão, mas recupera desempenho removendo a verificação quando o compilador consegue provar que não haverá acesso fora dos limites. Para quem realmente precisa, há saídas como withUnsafeBufferPointer. A palavra unsafe no nome deixa o risco assumido visível no código.
Desempenho vs. expressividade: abstrações como funções de ordem superior e genéricos são essenciais para a expressividade, mas implementações ingênuas são lentas. O Swift investiu na capacidade do compilador para que inline e especialização de genéricos façam “usar uma abstração gerar o mesmo código de máquina que uma implementação manual”.
Percebe o padrão? O padrão é sempre segurança; desempenho e expressividade são recuperados por otimizações do compilador e saídas explícitas. Quase toda decisão de design do Swift pode ser explicada por essa fórmula.
O significado dessa filosofia na prática
Filosofia pode parecer abstrata, mas há pontos diretamente ligados ao trabalho prático.
Primeiro, é melhor trabalhar com o compilador, não contra ele. No Swift, a maioria dos erros de compilação indica que “um futuro bug de runtime foi capturado agora”. Abusar de ! porque opcionais são incômodos é derrubar por conta própria as defesas construídas pela linguagem.
Segundo, você ganha um critério para projetar APIs. Se uma função criada por você é fácil de usar incorretamente, ela não é muito Swift. Projetar tipos para que o uso incorreto vire erro de compilação é o núcleo do estilo Swift e aparecerá repetidamente nesta série.
Terceiro, fica mais fácil entender recursos novos. async/await mira simultaneamente o problema de expressividade do callback hell e o problema de segurança das condições de corrida de dados. A strict concurrency do Swift 6 estende a filosofia de segurança ao tentar detectar bugs de concorrência em tempo de compilação. Macros resolvem em tempo de compilação o problema de expressividade do boilerplate. Conhecendo as três filosofias, cada recurso novo mostra qual valor está promovendo e como.
Resumo
- Todo o design do Swift nasce do equilíbrio entre Safe, Fast e Expressive.
- Safe: opcionais, inicialização obrigatória e verificação de limites transformam erros em erros de compilação, não em bugs de runtime.
- Fast: despacho estático, ARC, tipos por valor e especialização de genéricos buscam desempenho de nível C mantendo as proteções de segurança.
- Expressive: inferência de tipos, enum e closures buscam clareza de intenção, não apenas brevidade.
- Quando há conflito, a segurança é o padrão; otimizações do compilador e saídas explícitas recuperam desempenho e expressividade.
No próximo artigo, veremos como essa filosofia se reflete na curva de aprendizado: o segredo que permite a convivência de um script print de uma linha e uma biblioteca genérica na mesma linguagem, Progressive Disclosure.
Continue lendo
- [Filosofia do Swift #2] O segredo de uma linguagem que começa com uma linha de print: Swift Progressive Disclosure
- [Filosofia do Swift #3] Por que tudo no Swift é struct? Guia completo do princípio de tipos por valor
- [Filosofia do Swift #4] O que é SE-0296? Como nasce a sintaxe do Swift: guia completo de Swift Evolution

![Imagem de capa de [Filosofia do Swift #1] Safe · Fast · Expressive](/assets/images/posts/31c00204-0641-451d-ab08-920722d6d25e/1.jpg)