---
slug: 01-counter-your-priors
title: Contra tus instintos
description: Los lugares donde Synsema difiere de lo que un LLM (o un dev) asume por defecto — cada uno verificado contra el engine.
example_ids: [priors]
---

# Contra tus instintos

Ningún LLM fue entrenado en Synsema, así que un modelo que escribe Synsema recae en hábitos
de otros lenguajes. Estas son las diferencias que muerden. **Cada afirmación acá está
verificada contra el engine** (las de abajo son un doctest que pasa):

> ¿Venís de **Python** en particular? Empezá por
> [Python → Synsema — la tabla de traducción](/es/0.6.x/01a-python-to-synsema): mapea los
> reflejos de Python (`def`/`return`, f-strings, comprehensions, `try/except`, `d.get`) a
> las formas Synsema en un solo lugar. Esta página junta el resto de los gotchas verificados.

```synsema
-- Doc example: places where Synsema differs from what a fresh LLM assumes.
-- Every claim below is a passing assertion against the engine (doctested).
intent: "doc example: counter-your-priors gotchas"
require secret("API_KEY")

print("1 / 2 = " + text(1 / 2) + "   (division is always float)")

test "division is ALWAYS float (1/2 is 0.5, not 0)"
    assert_eq(1 / 2, 0.5)
    assert_eq(type_of(1 / 2), "number")

test "there is no has(); use contains() for map keys"
    let m be {"a": 1, "b": 2}
    assert(contains(m, "a"))
    assert(not contains(m, "z"))

test "concatenating text + secret redacts the WHOLE string (prefix absorbed)"
    let k be secret("API_KEY", "sk-real-123")
    assert_eq(type_of("Bearer " + k), "secret")
    assert_eq(text("Bearer " + k), "secret(API_KEY)")

test "property access uses `of` (or dot)"
    let cfg be {"host": "localhost", "port": 8080}
    assert_eq(host of cfg, "localhost")
```

## Más gotchas (verificados)

- **`log` es una sentencia, no una función.** Escribí `log "mensaje"`, no `log("mensaje")` —
  la forma de función parsea con `check` pero revienta en runtime (`Undefined variable: log`).
- **`random()` / `random_int()` necesitan `require random`** incluso bajo `run` — **no** se
  auto-otorga (random es para tokens/nonces, así que es deny-by-default).
- **El orden de `apply` ya no es una trampa** — la familia intencional (`apply`/`where`/
  `transform`/`reduce`/`sort_by`/`group_by`/`find_first`/`every`/`some`/`count_where`/
  `zip_with`) acepta **ambos** órdenes `(fn, lista, …)` y `(lista, fn, …)`; dos tasks o
  dos listas donde se esperaba una-y-una es error explícito, jamás una adivinanza.
  `index_of` devuelve **`nothing`** si no está (no -1 — chequeá `when idx != nothing`).
- **`a of b.c` se lee como `a of (b.c)`** — para `(a of b).c`, bindeá primero: `let x be
  a of b`, después `x.c` (el error de runtime ahora trae este hint). Y `request`/`query`/
  `params` existen solo dentro de los route handlers — pasalos a las tasks auxiliares
  como parámetros.
- **La memoria del agente se DECLARA** — `remember`/`recall`/reglas/progreso fallan con
  `Capability not granted: memory` salvo que el programa tenga `require memory("<name>")` al
  tope (no se auto-otorga, ni bajo `run`: escribe archivos). El nombre declarado — no el del
  archivo — keyea el `.db`; ver [Memoria y estado](/es/0.6.x/61-memory).
- **`recall(...)` es más-nuevo-primero** — `[0]` es la entrada más reciente — y trunca a 200
  resultados (pasá un 5º argumento para subir el límite). Dentro de un `agent`, `recall()` lee
  solo las entradas propias de ese agente por defecto — cruzá namespaces con
  `recall(from = "other")` o `from = "*"`.
- **Las operaciones LLM llevan un sujeto:** `reason about X`, `decide between [...] given X`,
  `analyze X for "..."`, `generate "..." given X`. El `reason "literal"` pelado recién es
  válido tras un fix reciente.
- **Una ruta `:param` se come un sufijo `.md` / `.json`** (es negociación de contenido). Para
  detectar el sufijo, leé `path of request` — el param ya viene sin él.
- **Las rutas declaradas siempre ganan sobre los `static` mounts.** Con rutas comodín como
  `GET /:lang/:version`, un `static "/assets"` nunca se alcanza — serví los assets con una
  ruta declarada `GET /assets/*path`.
- **La división es siempre float:** `1 / 2` es `0.5`, y `type_of(1 / 2)` es `"number"`.
- **`print` bufferea bajo `run`** — para un REPL en vivo usá `flush()` / `read_line`. Bajo
  `serve`, `print`/`log` llegan a la terminal con prefijo `[serve]`.
- **El lexer rechaza el BOM UTF-8**, y un `use "..."` **no puede escapar su directorio**
  (`../x.syn` se deniega).

> Si un modelo insiste en generar mal alguno de estos, copiá esta página a su contexto — es
> exactamente el instinto que hay que corregir.
