Apéndice A — A. Tres sintaxis, un programador
La tabla de traducción TS ↔︎ Python ↔︎ Go
Solo lo que el libro usó, en tres columnas: tipos, módulos, errores, clases/structs, concurrencia — y los errores típicos del que viene de JS. Cuando leas un backend en el stack que no practicas, esta tabla es el diccionario.
A.1 Sintaxis esencial
| Concepto | TypeScript | Python | Go |
|---|---|---|---|
| Función | function f(x: number): number {} |
def f(x: int) -> int: |
func f(x int) int {} |
| Bloques | { } |
indentación | { } |
| Nulo | null / undefined |
None |
nil |
| Lista | T[] / Array<T> |
list[T] |
[]T (slice) |
| Mapa | Record<K,V> / Map |
dict[K,V] |
map[K]V |
| Módulo | import { x } from "./m" |
from m import x |
import "m" |
| Error | throw / catch |
raise / except |
return err (valor) |
| Async | async/await + Promise.all |
async/await + gather |
go f() + channels/errgroup |
| “Clase” | class |
class |
struct + métodos (sin herencia) |
A.2 Tipos y estructuras
TS: interface Task { id: number; title: string; done: boolean }
Python: class Task(BaseModel): id: int; title: str; done: bool
Go: type Task struct { ID int64; Title string; Done bool }
TS: tasks.filter(t => !t.done).map(t => t.title)
Python: [t.title for t in tasks if not t.done]
Go: var titles []string; for _, t := range tasks { if !t.Done { titles = append(...) } }
A.3 Errores: el modelo mental de cada uno
TS: excepciones que suben — throw new DomainError(...) → catch/handler
Python: excepciones que suben — raise NotFoundError → except/handler
Go: errores como VALOR — if err != nil { return err } → sin saltos
El que viene de JS a Go siempre pregunta “¿dónde está el catch?” — no hay: el error viaja por return, visible en cada firma. Verbosidad que compra visibilidad.
return hace dos cosas a la vez: devuelve el resultado Y termina la función — lo que esté debajo nunca corre. return task = “aquí está el plato, salgo de la cocina”.
Una firma (HMAC) prueba que un mensaje es auténtico y no fue tocado: se calcula con un secreto sobre el contenido. Los webhooks la usan para que verifiques “esto realmente vino de Stripe”.
A.4 Lo que NO se traduce directo
| Pieza | Solo existe en | Por qué |
|---|---|---|
yield/generadores |
Python (y TS iterators) | Streams perezosos — Go usa canales/loops |
defer |
Go | “Ejecuta esto al salir de la función” — el finally que no olvidas |
Context managers (with) |
Python | Recurso que se cierra solo — TS usa try/finally, Go defer |
| Goroutines | Go | Concurrencia nativa barata — en los otros es modelo, no palabra clave |
| Punteros explícitos | Go (*T vs T) |
Valor vs referencia visible en la firma |
A.5 Errores típicos del que viene de JS
| Trampa | En qué lenguaje muerde | El por qué |
|---|---|---|
Default mutable def f(items=[]) |
Python | El default se crea UNA vez — compartido entre llamadas → None + crear dentro |
== vs is |
Python | == compara valor, is compara identidad — x == [] no es x is [] |
if (err) vs err == nil |
Go | nil es su propio tipo de valor — y el error se retorna, no se lanza |
Comparar struct con == |
Go | Funciona pero compara campos — con slices/maps adentro no compila |
interface{}/any como escape |
TS/Go | “Luego lo tipo” = nunca — el tipo débil contamina todo lo que lo toca |
| Slices que comparten array | Go | append puede mutar el backing array — copia si dudas |
A.6 Mini reto
Traducir una función del proyecto a los otros dos lenguajes sin mirar la solución.
Toma createTask(userId, title) — validar, trim, insertar, devolver. La traducción correcta no es literal: en Go el error viaja por return ((Task, error)), en Python el tipo va en la firma con -> Task, en TS el schema de entrada se valida con zod antes. Si tu traducción usa try/catch en Go o return err en Python, estás escribiendo JS con acento — la forma correcta es la del idioma, no la tuya.
A.7 Vocabulario técnico del capítulo
Una variable es una caja con nombre donde guardas un valor: let total = 42 guarda el 42 bajo el nombre total. Puedes leerla y cambiarla después (total = 50). const = caja que no se puede reemplazar.
Una función es una receta reutilizable: recibe ingredientes (parámetros), hace pasos y devuelve un plato (return). La escribes una vez y la llamas mil veces: add(2, 3) → 5.
Un array es una colección ordenada de elementos accedidos por posición: ["a","b","c"][0] es "a" (se cuenta desde 0). Python las llama listas, Go slices — misma idea, distinto acento.
Un objeto es una colección de datos con nombre: {name: "Ana", age: 30} — cada dato es una propiedad (clave → valor). Python los llama dict, Go los arma con struct, TS con objetos/interface.
Un bucle repite una acción por cada elemento o hasta cumplir una condición: for task in tasks hace algo con cada tarea. map y filter son bucles disfrazados de funciones — transforman/filtran colecciones sin for explícito.
Una clase es el molde de un objeto: define qué datos y qué métodos tiene. class Task es el molde; new Task() es una instancia concreta. Go no tiene clases — usa struct + métodos sueltos.
Un string es texto entre comillas: "hola". El nombre viene de “cadena de caracteres” — una secuencia de letras. Todo lo que llega de un formulario o una URL llega como string, aunque parezca número.
Un booleano es un valor de dos estados: true o false. Es el resultado de toda comparación (age > 18) y lo que los if evalúan. Nombrado por George Boole, el matemático de la lógica.
null (TS), None (Py), nil (Go) = “aquí no hay valor”. Es la respuesta a “¿qué devuelvo cuando no hay nada?” — y la fuente del bug más famoso de la historia (su inventor lo llamó “el error del billón de dólares”). Por eso el código revisa if x is not None.
Un compilador traduce código a otra forma: TypeScript → JavaScript (transpila), Go → binario (compila). Atrapa errores antes de ejecutar. tsc, esbuild, go build son compiladores.
El esquema es el plano de la base de datos: qué tablas hay, qué columnas tiene cada una y de qué tipo. Es contrato: una fila que no cumple el esquema no entra. Se cambia con migraciones, no a mano.
Concurrencia = manejar muchas cosas en progreso (atender 1000 requests intercalando). Paralelismo = ejecutar varias a la vez en varios núcleos. Un camarero con 10 mesas es concurrente; 10 camareros son paralelos.
Un módulo es un archivo de código que exporta cosas para que otros archivos las importen. Es la unidad de organización: en vez de un archivo gigante, el código vive en módulos con responsabilidad propia.
Async/await es la sintaxis para operaciones que tardan (red, disco): await pausa esa función sin congelar el programa entero. Una Promise es la “promesa” de un resultado futuro — el ticket que recibes mientras lo preparan.
Los tipos (int, string, boolean, Task) son el contrato de cada dato. Tipado estático (TypeScript, Go, Python con hints) = los tipos se revisan al escribir, no cuando explota en producción.