Observabilidad
-- Doc example: observability. `log` is real; `trace`/`measure`/`checkpoint` are
-- decorative markers — they RUN their body but don't persist timing/snapshots.
intent: "doc example: observability"
let answer be 0
measure "demo"
set answer to 41 + 1
print("measure ran → answer = " + text(answer))
test "measure runs its body (the timing instrumentation is decorative)"
let x be 0
measure "compute"
set x to 41 + 1
assert_eq(x, 42)
Logging (real)
log toma una expresión completa (también es una expresión). Bajo serve, log/print llegan a la terminal con prefijo [serve].
log "Procesando orden " + order_id
loges una sentencia, no una función.log "msg"funciona;log("msg")parsea concheckpero revienta en runtime.
Logs bajo serve (logging de requests)
serve no escribe un access log por vos — por defecto la terminal está callada, lo que dificulta el desarrollo. Agregá un log en tus handlers para ver el tráfico en vivo:
route "GET /:lang/:version/:slug"
log "GET " + (path of request)
give render_page(...)
Cada request entonces aparece en la terminal del server como [serve] [LOG] GET /…. print también funciona ahí (mismo prefijo [serve]). (Este sitio de docs loguea sus propios requests así.)
Marcadores — trace / measure / checkpoint (decorativos)
Estos corren su cuerpo pero la instrumentación de timing/snapshot hoy es un stub — no persisten nada. trace/measure toman un nombre literal; checkpoint toma una expresión.
measure "db_query"
run_query(sql)
Para crash-resume / tracking de pasos real, usá los builtins de progress, no checkpoint — ver Memoria y estado.
Diagnósticos de error (opt-in)
El run plano imprime una línea estable (Runtime error: file:line:col: msg). Para un reporte rico — contexto de fuente, call stack, variables visibles, clasificación, sugerencias — optá por:
synsema run --explain program.syn # legible, en stderr
synsema run --explain --format json program.syn # estructurado, para tools/agentes
El exit code no cambia (1 al fallar, 0 al tener éxito) en cualquier caso.