Skip to content
Ridgun
English

Ridgun

The language itself: a compiler that compiles itself, the stable project tool, the specification and the book

01-bienvenido-a-ridgun.md196 lines · 11.6 KBRaw
1# Capítulo 01: Tu primer contacto con Ridgun (Sin cascos, sin llaves y sin puntos y coma)
2
3Vale, ya te he convencido en el Capítulo 00 de que no estamos locos por crear Ridgun. Ahora seguramente estés pensando:
4
5> *"Muy bonito el discurso de las tablas y los 16 núcleos, pero enséñame código de verdad. ¿Cuánto tarda uno en escribir algo que funcione sin pelearse con el compilador?"*
6
7Venga, ¡al turrón!
8
9---
10
11## 1.1. "¡Hola, mundo!", pero con chicha
12
13En la mayoría de los libros de programación te enseñan un `print("Hola mundo")` soso y pasan de página. Nosotros vamos a escribir directamente una función con lógica real para que veas cómo respira Ridgun desde el minuto uno.
14
15Crea un archivo llamado `hola.rg` y escribe esto:
16
17```ridgun
18saludo String => String
19saludo "" = "¡Hola, viajero misterioso! (No me has dicho tu nombre)"
20saludo "Root" = "¡Hombre, Root! Cuidado con lo que borras hoy."
21saludo nombre = "¡Hola, {nombre}! Bienvenido a Ridgun."
22
23main => ()
24main =
25 echo (saludo "Ada")
26 echo (saludo "Root")
27 echo (saludo "")
28```
29
30Para ejecutarlo ahora mismo:
31
32```bash
33ridgunc run hola.rg
34```
35
36Y verás en tu terminal:
37
38```text
39¡Hola, Ada! Bienvenido a Ridgun.
40¡Hombre, Root! Cuidado con lo que borras hoy.
41¡Hola, viajero misterioso! (No me has dicho tu nombre)
42```
43
44Para un momento y mira el bloque de `saludo` arriba. ¿Notas lo que **NO** hay?
45- **No hay `function`, ni `def`, ni `pub fn`** (si quieres poner `fn ::` delante de la firma puedes hacerlo, pero es opcional).
46- **No hay paréntesis `(String nombre)` ni llaves `{ ... }`** ensuciando la pantalla.
47- **No hay `if (nombre == "") ... else if (nombre == "Root") ... else ...`**.
48- **No hay `return`**.
49
50---
51
52## 1.2. Cómo lee tu cerebro un archivo `.rg`
53
54Vamos a destripar esas cuatro líneas de `saludo`, porque aquí ya está el 50% de la filosofía de Ridgun:
55
56```ridgun
57saludo String => String
58saludo "" = "¡Hola, viajero misterioso! (No me has dicho tu nombre)"
59saludo "Root" = "¡Hombre, Root! Cuidado con lo que borras hoy."
60saludo nombre = "¡Hola, {nombre}! Bienvenido a Ridgun."
61```
62
631. **La primera línea es el contrato (`saludo String => String`)**:
64 Dice: *"Me llamo `saludo`, recibo un `String` y te devuelvo (`=>`) otro `String`"*. Punto. Si alguien intenta llamarme pasándome el número `42`, el compilador le dará un toque en el hombro antes siquiera de ejecutar el programa.
652. **Las líneas de abajo son los casos (de arriba abajo)**:
66 - ¿Me has pasado la cadena vacía `""`? Devuelvo la primera frase.
67 - ¿Me has pasado exactamente `"Root"`? Devuelvo la segunda frase.
68 - ¿Me has pasado cualquier otra cosa? La guardo en la variable `nombre` y la meto dentro del texto usando `{nombre}`.
693. **¿Y qué es `main => ()`?**:
70 Como `main` no recibe argumentos, ponemos `=>` directamente después del nombre. Y devuelve `()` (el tipo vacío o *Unit*, para los amigos), porque su único trabajo es sacar cosas por pantalla con `echo`.
71
72---
73
74## 1.3. "Espera... ¿tengo que alinear esos espacios a mano como un monje copista?"
75
76¡Ni de broma! Si tuvieras que darle a la barra espaciadora contando columnas a ojo, abandonarías Ridgun a los diez minutos (y con razón).
77
78Tú escribes el código deprisa, con un solo espacio entre cada palabra:
79
80```ridgun
81saludo String => String
82saludo "" = "¡Hola, viajero misterioso!"
83saludo nombre = "¡Hola, {nombre}!"
84```
85
86Y cuando ejecutas **`stable format`** (o pulsas `TAB` / guardas el archivo en Emacs con `ridgun-mode`), el formateador canónico coloca cada parámetro debajo de su tipo y alinea todos los `=` con precisión milimétrica. Tú escribes rápido; la máquina maqueta la tabla.
87
88---
89
90## 1.4. De script rápido a binario de combate en un comando
91
92Cuando haces `ridgunc run hola.rg`, estás compilando y lanzando el programa al vuelo. Pero imagina que ya has terminado tu herramienta y quieres llevártela a un servidor de producción o compartirla con un compañero que no tiene instalado Ridgun.
93
94Ejecutas:
95
96```bash
97ridgunc build hola.rg -o hola
98```
99
100Y ya tienes `./hola`: un **ejecutable nativo ELF de Linux x86_64**, limpio, sin código muerto (*Tree-Shaking*), con optimización de enlace completo (*LTO*) y sin depender de ningún intérprete externo.
101
102---
103
104## 1.5. La chuleta honesta: ¿De dónde viene cada idea de Ridgun?
105
106Ridgun no pretende reinventar la rueda cuadrada; toma prestado sin complejos lo mejor de cuatro tradiciones:
107
108| De quién | Qué toma Ridgun | Qué deja fuera (por tu salud mental) |
109|---|---|---|
110| **Haskell / ML** | Funciones puras, *pattern matching* por casos, tipos algebraicos (`Option`, `Result`) y polimorfismo (`A`..`Z`). | Las mónadas abstractas, los 40 `LANGUAGE pragmas` y el recolector de basura. |
111| **J / APL** | La obsesión por la forma tabular del código, tensores nativos y máscaras de secuencias (`s(_ + _)`). | Los símbolos jeroglíficos imposibles de escribir en un teclado normal. |
112| **Rust / C** | Binarios ELF nativos pequeños, cero GC, control de memoria (`with region`) y llamadas al sistema POSIX. | La pelea constante con el *borrow checker*, los *lifetimes* `'a` y la verbosidad sintáctica. |
113| **Erlang / Go** | Agentes aislados (`agent`, `send ... to`, `receive from`) y concurrencia por canales (`new bounded channel`). | Los punteros `nil` y las mutaciones compartidas por descuido. |
114
115---
116
117## 1.6. Y lo más importante: ¿Qué hace Ridgun que NO tiene nadie más?
118
119Reconocer a los clásicos es de buena educación, pero si Ridgun fuera solo un "recopilatorio de grandes éxitos" de otros lenguajes, no estarías leyendo este libro.
120
121Hay **ocho cosas** que hemos diseñado e integrado en Ridgun que no vas a encontrar juntas —y muchas de ellas, ni siquiera por separado— en ningún otro lenguaje actual:
122
123### 1. Bloques paralelos `||` con `->` que son grafos paralelos reales, no simple azúcar sintáctico
124En otros lenguajes funcionales un bloque de variables locales solo ordena expresiones que luego se evalúan en un único hilo.
125En Ridgun, **un bloque `||` con flechas `->` es un Grafo Acíclico Dirigido (DAG) de ejecución paralela** sin siquiera necesitar escribir palabras clave extra como `where`:
126```ridgun
127informe anual Int => Int
128informe anual id = ingresos - gastos
129 || calcular ventas id -> ingresos
130 || calcular costes id -> gastos
131```
132Tú dibujas las flechas de flujo (`->`). El compilador analiza quién depende de quién, **verifica estáticamente que no hayas creado ningún ciclo infinito**, y lanza las ramas independientes en paralelo sin que escribas ni un solo `async`, `await`, `Future` ni `Mutex`.
133
134### 2. Modelo Nativo de Agentes (`agent`) de cero fricción con elección inteligente en compilación
135En otros lenguajes, programar con actores o agentes te obliga a crear clases especiales, implementar *traits*, gestionar *locks* o infectar tus funciones con `async`.
136En Ridgun, **cualquier función pura normal (`fn ::` u `op ::`) se convierte directamente en un agente autónomo —con o sin estado aislado— usando `agent`**:
137```ridgun
138atender http (Sesion, String) => (Sesion, String)
139...
140servidor = agent atender http sesion_inicial
141send "GET /perfil" to servidor
142respuesta = receive from servidor
143stop servidor
144```
145Mejor aún: el compilador **analiza en tiempo de compilación la profundidad y el coste computacional de la función** tanto en `agent` como en `||` y `||map`. Si la función es ligera, la ejecuta como un *green thread* instantáneo sin pagar el coste de calentar hilos del sistema operativo; si es un cálculo pesado o recursivo profundo, la despacha automáticamente en paralelo sobre hilos reales del kernel (`SYS_clone`) repartidos por los núcleos de tu CPU.
146
147### 3. El código como tabla bidimensional donde la firma es la cabecera de las columnas
148En cualquier otro lenguaje, la firma de tipos va por libre en una línea y el cuerpo de la función va debajo como un párrafo de texto normal.
149En Ridgun, **la firma de tipos es literalmente la cabecera de una tabla**, y cada caso debajo alinea cada patrón justo en la vertical de su tipo y cada `=` bajo el `=>`:
150```ridgun
151dividir Int Int => Option
152dividir _ 0 = None
153dividir a b = Some (a / b)
154```
155Nadie más trata la firma y las ecuaciones como una única matriz visual verificada por el compilador y maquetada automáticamente por `stable format`.
156
157### 4. Operadores frase (*Mixfix* N-arios) tipados y alineados (`op ::`)
158En la mayoría de los lenguajes, o te aguantas con `+`, `-`, `*` o como mucho defines un operador binario críptico como `<|>` que nadie sabe qué significa.
159En Ridgun puedes crear **operadores que son frases legibles con tantos huecos tipados como quieras** (incluyendo palabras contextuales como `type` o `with`):
160```ridgun
161op :: Int limitado entre Int y Int => Int
162 x limitado entre min y max =
163 | x < min = min
164 | x > max = max
165 | otherwise = x
166```
167Y luego en tu código escribes `velocidad limitado entre 0 y 120`. Se lee como castellano (o inglés), pero está 100% tipado y compilado a código nativo.
168
169### 5. Máscaras visuales sobre secuencias (`s(_ + _)` y `-> (+ _ _ +) ->`)
170¿Alguna vez has tenido que escribir una ensalada de índices `filter(\(i, x) -> i % 2 == 0)` o abrir una tupla con variables mudas solo para quedarte con dos posiciones concretas?
171En Ridgun le pasas directamente una **máscara visual**:
172- `datos(_ + _)`: descarta el primero (`_`), se queda el segundo (`+`), descarta el tercero (`_`).
173- `parsear paquete "v0.9.9" -> (+ _ _ +) -> combinar codigo -> resumen`: filtra una tupla de 4 elementos en plena tubería y pasa el 1.º y el 4.º directamente como los 2 argumentos de la siguiente función.
174Cero aritmética de índices, cero errores *off-by-one*.
175
176### 6. Polimorfismo de "cero ruido" (`A`..`Z`) gobernado por tu dominio
177En Rust, TypeScript o Java, cuando una función es genérica tienes que llenar la línea de paréntesis angulares: `fn intercambiar<A, B>(par: (A, B)) -> (B, A)`.
178En Ridgun simplemente usas una letra mayúscula suelta:
179```ridgun
180intercambiar (A, B) => (B, A)
181intercambiar (x, y) = (y, x)
182```
183*"¿Y si en mi programa quiero tener un tipo real que se llame `type A`?"* — Ningún problema: en Ridgun **tus declaraciones `type` mandan**. Si no existe `type A`, `A` es genérico; en el instante en que defines `type A = ...`, pasa a ser tu tipo concreto en todo el módulo.
184
185### 7. Cero archivos de configuración extraños: `build.rg` es Ridgun puro
186Olvídate de aprender TOML para Cargo, JSON para npm, XML para Maven o la sintaxis arcana de `Makefile` con tabuladores invisibles. En Ridgun, la receta que construye tu proyecto (`build.rg`) **es un archivo `.rg` más**, con las mismas funciones puras y el mismo *pattern matching* que el resto de tu código.
187
188### 8. La "Santísima Trinidad" que parecía imposible: Nivel Haskell + Memoria RMM sin GC ni Lifetimes + Binarios de ~350 KB
189Hasta hoy tenías que elegir:
190- Si querías expresividad funcional pura (Haskell, OCaml, Elixir), pagabas con un recolector de basura y un runtime pesado.
191- Si querías binarios diminutos de sistema sin recolector de basura (C, Rust, Zig), pagabas gestionando punteros o peleándote con el *borrow checker* y escribiendo código imperativo lleno de `let mut`.
192
193Ridgun rompe ese dilema combinando **Ridgun Memory Management (`RMM`: `RMM1` estática y `RMM2` por conteo de asignaciones en cascada)**, **regiones léxicas (`with region`)** que liberan arenas enteras en $O(1)$, **recursión de cola transformada en bucles nativos (`loop`)**, y **poda de grafo de llamadas (*Tree-Shaking*)** desde `main`. El resultado: escribes código declarativo de altísimo nivel y obtienes un ejecutable ELF autónomo de **~350 KB** capaz de competir de tú a tú con herramientas escritas en C.
194
195Ahora sí: con las cartas sobre la mesa, vamos al **Capítulo 02** para poner a trabajar a **`ridgunc`** y **`stable`**.
196