Skip to content
Ridgun
English

Ridgun

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

02-primeros-pasos-y-herramientas.md221 lines · 12.1 KBRaw
1# Capítulo 02: Tus dos mejores amigos: `ridgunc` y `stable` (Cero archivos YAML, prometido)
2
3Hay lenguajes cuyo compilador es maravilloso, pero cuyo sistema de proyectos parece diseñado por tu peor enemigo: que si un `Makefile` de 400 líneas con tabuladores invisibles, que si un `pom.xml` infinito, que si un `webpack.config.js` que deja de funcionar si lo miras fijo...
4
5En Ridgun nos hicimos una promesa muy simple desde el primer día:
6
7> *"Sólo habrá dos ejecutables en todo el ecosistema (`ridgunc` y `stable`), ambos estarán escritos en el propio Ridgun, y el archivo de configuración del proyecto (`build.rg`) será código Ridgun normal y corriente. Ni JSON, ni YAML, ni TOML, ni inventos raros."*
8
9Vamos a ver cómo se usan.
10
11---
12
13## 2.1. `ridgunc`: El francotirador para archivos sueltos
14
15Cuando tienes un único archivo `.rg` entre manos y quieres probar una idea rápida, analizar sus tipos o compilar un ejecutable, hablas directamente con **`ridgunc`**.
16
17Sólo tiene 4 comandos que de verdad necesitas recordar:
18
19```bash
20# 1. "¿Compila esto o he metido la pata con algún tipo?"
21ridgunc check experimento.rg
22
23# 2. "¡Ejecútalo ya!" (Compila y corre de un tirón)
24ridgunc run experimento.rg
25
26# 3. "Hazme un binario nativo ELF64 listo para llevar"
27ridgunc build experimento.rg -o mi-programa
28
29# 4. "Compílame una librería reutilizable (.rglib y .so ELF64 sin necesitar main)"
30ridgunc build --lib utilidades.rg -o target/utilidades.rglib
31ridgunc build --so utilidades.rg -o target/libutilidades.so
32
33# 5. "Sácame el artefacto intermedio de bytecode (.rgc)"
34ridgunc compile experimento.rg -o experimento.rgc
35```
36
37### El superpoder oculto de `ridgunc check`
38Cuando lanzas `ridgunc check`, no solo te dice *"0 errores"*. También te chiva qué estrategia ha elegido el analizador estático para cada una de tus funciones:
39- **`InlineSequential`**: *"Esta función es pequeñita y directa; la voy a ejecutar en línea sin meter sobrecoste de planificación"*.
40- **`LazyStealableTask`**: *"Aquí hay recursión o un grafo paralelo `||`; la preparo para que otros núcleos de CPU puedan robar trabajo si hace falta"*.
41
42### El bisturí de `ridgunc build` (Por qué tus binarios no pesan 20 MB)
43Cuando ejecutas `ridgunc build`, el compilador no se limita a escupir todo el código de las librerías que hayas importado:
441. Empieza en tu función `main` y recorre el grafo de llamadas para ver **qué funciones usas de verdad**. Si importaste una librería enorme de 80 funciones pero solo llamas a 2, las otras 78 se descartan antes siquiera de tocar el ensamblador (*Tree-Shaking*).
452. Busca todas las funciones recursivas de cola y las convierte en bucles `loop` nativos que consumen **0 bytes de pila**.
463. Pasa el enlace final con optimización global (*fat LTO*) y limpia la basura de depuración DWARF para dejarte un binario compacto y afilado (~350 KB).
47
48---
49
50## 2.2. `stable`: Cuando tu proyecto crece y quieres orden
51
52Un archivo suelto está genial para un script, pero en cuanto tienes varios módulos, librerías compartidas y tests, necesitas un director de orquesta. Ese es **`stable`**.
53
54La estructura de carpetas de un proyecto Ridgun no tiene misterio:
55
56```text
57mi-super-herramienta/
58├── build.rg # El manifiesto del proyecto (¡es código Ridgun!)
59├── src/
60│ ├── main/
61│ │ └── ridgun/
62│ │ ├── lib/ # Tus módulos reutilizables (`import utilidades`)
63│ │ └── app/
64│ │ └── main.rg # Punto de entrada (`main => ()`)
65│ └── test/
66│ └── ridgun/ # Tus baterías de tests (`test *.rg`)
67│ └── test todo.rg
68└── target/ # Donde aparecen los binarios compilados
69```
70
71---
72
73## 2.3. `build.rg`: Un archivo de configuración que nunca te mentirá
74
75¿Por qué nos negamos a usar YAML o TOML para configurar un proyecto Ridgun?
76Porque en YAML te equivocas en dos espacios de indentación y no te enteras hasta que falla el despliegue. En cambio, como **`build.rg` es un archivo Ridgun**, tiene tipos estáticos, pasa por `stable check` y se alinea solo con `stable format`:
77
78```ridgun
79fn :: project name => String
80 project name = "mi-super-herramienta"
81
82fn :: project version => String
83 project version = "0.1.0"
84
85-- "exe" (ejecutable), "lib" (librería .rglib + .so) o "both" (ambos)
86fn :: project kind => String
87 project kind = "both"
88
89-- Opcional: modo estricto (prohíbe '_' en nombres fn/op y exige retornos '=> Int Int')
90fn :: strict mode => Bool
91 strict mode = True
92
93fn :: main entry => String
94 main entry = "src/main/ridgun/app/main.rg"
95
96fn :: source dir => String
97 source dir = "src/main/ridgun"
98
99fn :: test dir => String
100 test dir = "src/test/ridgun"
101
102fn :: target dir => String
103 target dir = "target"
104
105fn :: dependencies => [String]
106 dependencies = []
107
108fn :: plugins => [String]
109 plugins = []
110
111fn :: task verificar todo => String
112 task verificar todo = "./bin/stable check && ./bin/stable test"
113```
114
115Si te equivocas al escribir un campo o un tipo, el propio compilador te avisa. Y fíjate en que todas las funciones de configuración usan **espacios naturales** (`project name`, `project kind`, `source dir`, `task verificar todo`) en lugar de guiones bajos.
116
117---
118
119## 2.4. Tu rutina diaria con `stable` (Los 4 fantásticos)
120
121Cuando estás trabajando dentro de tu proyecto, tu día a día se reduce a cuatro comandos:
122
123### 1. `stable format` — El fin de las discusiones de estilo en el equipo
124```bash
125stable format
126```
127¿Que tu compañero pone tres espacios antes del `=>` y tú pones uno? Da igual. Ejecutas `stable format` y en menos de un segundo deja **todos** los archivos `.rg` del repositorio alineados como una tabla suiza.
128
129### 2. `stable check` — El radar instantáneo
130```bash
131stable check
132```
133Recorre todos los módulos de `src/main/ridgun/`, verifica tipos, constructores, aridades y dimensiones de tensores, y te da el veredicto módulo por módulo.
134
135### 3. `stable test` — Dormir tranquilo por las noches
136```bash
137stable test
138```
139Busca todas las suites `src/test/ridgun/test *.rg`, las ejecuta y comprueba cada `assert equals` y `assert true`.
140
141```ridgun
142-- Ejemplo de src/test/ridgun/test mates.rg
143import test
144
145doble Int => Int
146doble x = x * 2
147
148main => ()
149main =
150 assert equals (doble 21) 42
151 assert true ((doble 5) > 0)
152```
153
154### 4. `stable built` (y `stable clean`) — A producción
155```bash
156stable built
157```
158Compila todos los objetivos nativos en `target/`. Y si algún día quieres borrar `target/` y empezar limpio: `stable clean`.
159
160---
161
162## 2.5. Crear y usar Librerías Reutilizables (`.rglib` y `.so` ELF64) y Plugins de `stable`
163
164Una librería no tiene función `main => ()`: ofrece tipos (`type`, `expand type`), funciones (`fn ::`) y operadores (`op ::`) para que otros proyectos los importen.
165
166### 1. Crear un proyecto de librería con `stable`
167```bash
168stable new --lib geometria
169cd geometria
170stable built lib
171```
172Al compilar en modo librería (`project kind = "lib"` o `stable built lib`), el compilador desactiva la poda desde `main` para conservar **todas** las funciones y tipos exportados, y genera dos artefactos en `target/`:
173- **`target/geometria.rglib`**: paquete autocontenido de librería Ridgun (con todas sus fuentes y dependencias internas resueltas), listo para importar desde cualquier otro proyecto con `import geometria` o `import "target/geometria.rglib"`.
174- **`target/libgeometria.so`**: biblioteca dinámica nativa ELF64 (`ET_DYN`, para `x86_64` o `arm64-linux`).
175
176```ridgun
177-- src/main/ridgun/lib/geometria.rg (¡Sin función main!)
178type Punto = x: Int, y: Int
179
180fn :: desplazar punto Punto Int Int => Punto
181 desplazar punto p dx dy = Punto ((x p) + dx) ((y p) + dy)
182
183fn :: coordenadas punto Punto => Int Int
184 coordenadas punto p = (x p, y p)
185```
186
187### 2. ¿Cómo importo un módulo o librería desde otro archivo? (`import`)
188
189Sin rutas relativas infernales tipo `../../../lib/cosas.rg`. Si tienes un módulo `src/main/ridgun/lib/geometria.rg` o un paquete `geometria.rglib` (en `target/`, `lib/` o `.stable/deps/` tras ejecutar `stable deps`), en cualquier otro archivo escribes arriba del todo:
190
191```ridgun
192import geometria
193```
194
195Y listo: todas las funciones, operadores y tipos de `geometria` están disponibles como si estuvieran en tu propio archivo. Si varios módulos hacen `import geometria`, el cargador de Ridgun recuerda qué archivos canónicos ha leído ya y **solo lo incluye una vez**.
196
197### 3. Extender `stable` con tareas (`fn :: task`) y plugins (`plugins/*.rg`)
198¿Quieres añadir comandos propios para tu framework web, tus migraciones de base de datos o tu flujo de despliegue?
199- **En `build.rg`**: declara cualquier función `fn :: task <palabras...> => String` (por ejemplo, `fn :: task levantar servidor => String`) y ejecútala con `stable levantar servidor`.
200- **En `plugins/*.rg` o `.stable/plugins/*.rg`**: coloca módulos `.rg` que definan tareas `fn :: task ...` o su propio `fn :: main => ()`, o extiende el tipo abierto `expand type StableCommand` de `stable`. Ejecuta `stable tasks` y `stable plugins` para inspeccionarlos en cualquier momento.
201
202### 4. El modo estricto opcional (`--strict` y `strict mode = True`)
203Por defecto, ni `ridgunc` ni los proyectos nuevos creados con `stable new` o `stable init` activan el modo estricto. Sin embargo, cuando quieras garantizar en tu propio proyecto que todo el equipo siga al 100% la convención canónica de espacios naturales de Ridgun, puedes pasar `--strict` a `ridgunc` (`ridgunc check --strict`, `ridgunc build --strict`) o declarar `strict mode = True` en tu `build.rg`. El modo estricto convierte en **error de compilación**:
2041. Cualquier guion bajo `_` dentro del nombre de una declaración `fn ::` u `op ::` (debiendo escribirse `fn :: calcular total`, nunca `fn :: calcular_total`; las variables locales y campos de registros sí pueden usar `_`).
2052. Cualquier tipo de salida múltiple escrito con paréntesis o comas tras `=>` (debiendo escribirse `=> Int Int` o `=> RToken [RToken]`, nunca `=> (Int, Int)`).
206
207---
208
209## 2.6. El Ecosistema de Librerías Estándar y Criptográficas (`ridgun-libs`)
210
211Ridgun cuenta con una suite oficial de **32 librerías puras** (`ridgun-libs`), compiladas como paquetes `.rglib` y bibliotecas dinámicas `.so` ELF64 listas para importar con `import <nombre>`:
212
213| Familia | Librerías (`import ...`) | Qué aportan a tus proyectos |
214|---|---|---|
215| **1. Texto, Formatos y Plantillas** | `str`, `fmt`, `regex`, `diff`, `template`, `json`, `csv`, `ini`, `codec` | Manipulación avanzada de cadenas, formateo tabular, expresiones regulares Thompson NFA, diferencias Myers (`diff`), plantillas sin lógica, parsers/serializadores `json`/`csv`/`ini` y codificación hexadecimal/Base64 (`codec`). |
216| **2. Colecciones, Matemáticas y Álgebra Tensorial** | `list`, `btree`, `math`, `tensor`, `linalg` | Operaciones funcionales sobre listas, árboles B ordenados en memoria (`btree`), aritmética avanzada (`math`), vistas y constructores de tensores tipados (`tensor`) y descomposición/álgebra lineal (`linalg`). |
217| **3. Sistema Operativo, Archivos y CLI** | `posix`, `io`, `path`, `glob`, `cli`, `time`, `log`, `uuid`, `test` | Descriptores y señales POSIX (`posix`), E/S con `with timeout` (`io`), rutas y patrones (`path`, `glob`), argumentos CLI tipados (`cli`), relojes monotónicos (`time`), logging estructurado (`log`), RFC 4122 `uuid` y aserciones (`test`). |
218| **4. Criptografía y Seguridad** | `crypto`, `argon2id`, `jwt` | SHA-256 binario directo (`sha256 raw` / `sha256 bytes` en 32 bytes crudos), HMAC-SHA-256, PBKDF2-HMAC-SHA-256, HKDF, ChaCha20-Poly1305 AEAD (`crypto`), hashing de contraseñas RFC 9106 `argon2id` sobre `Tensor[U64 * 8 * 16]` con permutación BlaMka sin alojar tuplas en el heap (`argon2id`), y tokens firmados (`jwt`). |
219| **5. Redes, Protocolos y Agentes** | `socket`, `http`, `ws`, `agent`, `pool`, `net_agent` | Sockets TCP/UDP POSIX (`socket`), cliente/servidor HTTP/1.1 (`http`), WebSockets RFC 6455 (`ws`), supervisores de agentes (`agent`), pools de trabajadores (`pool`) y servidores reactivos orientados a agentes (`net_agent`). |
220
221Ahora que tienes la caja de herramientas y las librerías controladas, pasemos al **Capítulo 03** para dominar las funciones con espacios naturales, las firmas de tipos y los bloques.