No es la velocidad. Tampoco el sistema de tipos. Lo que se queda contigo
es la pregunta que borrow() hace por ti cada vez:
¿Quién es dueño de este dato, exactamente?
Y de pronto miras tu código Python, ese mismo dict que pasas a tres
funciones, y entiendes por qué el lunes algo dejó de funcionar.
El préstamo como modelo mental#
Cuando llevas tiempo en lenguajes con garbage collector, dejas de pensar en propiedad. El intérprete se encarga. Y eso está bien hasta que no lo está.
def normalize(items):
items.sort() # (1)!
return [x.lower() for x in items]
users = ["Beatriz", "Ana", "Carlos"]
result = normalize(users)
print(users) # ['Ana', 'Beatriz', 'Carlos'] ← sorpresa- Mutar el parámetro de entrada es un préstamo mutable. En Rust ni compilaría sin marcarlo. En Python compila, corre, y te muerde en producción.
En Rust el equivalente no compila:
fn normalize(items: &Vec<String>) -> Vec<String> {
items.sort(); // ❌ cannot borrow immutable
items.iter().map(|s| s.to_lowercase()).collect()
}El compilador te obliga a decidir: ¿lo necesitas mutable o no? Esa decisión, llevada de vuelta a Python, mejora cómo escribes funciones.
Tres heurísticas que me llevé#
- Acepta
Iterable, devuelvelist. Es el equivalente cultural de&[T]→Vec<T>. - Anota los tipos como si fueran un contrato. No para el type checker; para el siguiente humano.
- Si una función muta su entrada, dilo en el nombre.
sort_in_place, nosort.
Próxima entrada. En la siguiente parte hablo de
Result<T, E> y cómo me hizo dejar
de usar excepciones para flujo de control en Python.¿Comentarios o correcciones? info@encodigo.es.



