Ridgun
The language itself: a compiler that compiles itself, the stable project tool, the specification and the book
| 1 | # Capítol 02: Els teus dos millors amics: `ridgunc` i `stable` (Zero fitxers YAML, promès) |
| 2 | |
| 3 | Hi ha llenguatges el compilador dels quals és meravellós, però amb un sistema de projectes que sembla dissenyat pel teu pitjor enemic: que si un `Makefile` de 400 línies amb tabuladors invisibles, que si un `pom.xml` infinit, que si un `webpack.config.js` que deixa de funcionar si te'l mires fixament... |
| 4 | |
| 5 | A Ridgun ens vam fer una promesa molt simple des del primer dia: |
| 6 | |
| 7 | > *"Només hi haurà dos executables en tot l'ecosistema (`ridgunc` i `stable`), tots dos estaran escrits en el mateix Ridgun, i el fitxer de configuració del projecte (`build.rg`) serà codi Ridgun normal i corrent. Ni JSON, ni YAML, ni TOML, ni invents estranys."* |
| 8 | |
| 9 | Vegem com es fan servir. |
| 10 | |
| 11 | --- |
| 12 | |
| 13 | ## 2.1. `ridgunc`: El franctirador per a fitxers solts |
| 14 | |
| 15 | Quan tens un únic fitxer `.rg` entre mans i vols provar una idea ràpida, analitzar els seus tipus o compilar un executable, parles directament amb **`ridgunc`**. |
| 16 | |
| 17 | Només té 4 ordres que de debò necessites recordar: |
| 18 | |
| 19 | ```bash |
| 20 | # 1. "Compila això o he ficat la pota amb algun tipus?" |
| 21 | ridgunc check experiment.rg |
| 22 | |
| 23 | # 2. "Executa-ho ja!" (Compila i corre d'una tirada) |
| 24 | ridgunc run experiment.rg |
| 25 | |
| 26 | # 3. "Fes-me un binari natiu ELF a punt per emportar" |
| 27 | ridgunc build experiment.rg -o el_meu_programa |
| 28 | |
| 29 | # 4. "Treu-me l'artefacte intermedi de bytecode (.rgc)" |
| 30 | ridgunc compile experiment.rg -o experiment.rgc |
| 31 | ``` |
| 32 | |
| 33 | ### El superpoder ocult de `ridgunc check` |
| 34 | Quan llances `ridgunc check`, no només et diu *"0 errors"*. També et xiva quina estratègia ha triat l'analitzador estàtic per a cadascuna de les teves funcions: |
| 35 | - **`InlineSequential`**: *"Aquesta funció és petitona i directa; l'executaré en línia sense afegir sobrecost de planificació"*. |
| 36 | - **`LazyStealableTask`**: *"Aquí hi ha recursió o un graf paral·lel `||`; la preparo perquè altres nuclis de CPU puguin robar feina si cal"*. |
| 37 | |
| 38 | ### El bisturí de `ridgunc build` (Per què els teus binaris no pesen 20 MB) |
| 39 | Quan executes `ridgunc build`, el compilador no es limita a escopir tot el codi de les llibreries que hagis importat: |
| 40 | 1. Comença a la teva funció `main` i recorre el graf de crides per veure **quines funcions fas servir de debò**. Si has importat una llibreria enorme de 80 funcions però només en crides 2, les altres 78 es descarten abans fins i tot de tocar l'assemblador (*Tree-Shaking*). |
| 41 | 2. Busca totes les funcions recursives de cua i les converteix en bucles `loop` natius que consumeixen **0 bytes de pila**. |
| 42 | 3. Passa l'enllaç final amb optimització global (*fat LTO*) i neteja la brossa de depuració DWARF per deixar-te un binari compacte i esmolat (~350 KB). |
| 43 | |
| 44 | --- |
| 45 | |
| 46 | ## 2.2. `stable`: Quan el teu projecte creix i vols ordre |
| 47 | |
| 48 | Un fitxer solt està genial per a un script, però tan bon punt tens diversos mòduls, llibreries compartides i tests, necessites un director d'orquestra. Aquest és **`stable`**. |
| 49 | |
| 50 | L'estructura de carpetes d'un projecte Ridgun no té misteri: |
| 51 | |
| 52 | ```text |
| 53 | la-meva-super-eina/ |
| 54 | ├── build.rg # El manifest del projecte (és codi Ridgun!) |
| 55 | ├── src/ |
| 56 | │ ├── main/ |
| 57 | │ │ └── ridgun/ |
| 58 | │ │ ├── lib/ # Els teus mòduls reutilitzables (`import utilitats`) |
| 59 | │ │ └── app/ |
| 60 | │ │ └── main.rg # Punt d'entrada (`main => ()`) |
| 61 | │ └── test/ |
| 62 | │ └── ridgun/ # Les teves bateries de tests (`test *.rg`) |
| 63 | │ └── test tot.rg |
| 64 | └── target/ # On apareixen els binaris compilats |
| 65 | ``` |
| 66 | |
| 67 | --- |
| 68 | |
| 69 | ## 2.3. `build.rg`: Un fitxer de configuració que mai no et mentirà |
| 70 | |
| 71 | Per què ens neguem a fer servir YAML o TOML per configurar un projecte Ridgun? |
| 72 | Perquè en YAML t'equivoques en dos espais de sagnat i no te n'assabentes fins que falla el desplegament. En canvi, com que **`build.rg` és un fitxer Ridgun**, té tipus estàtics, passa per `stable check` i s'alinea sol amb `stable format`: |
| 73 | |
| 74 | ```ridgun |
| 75 | type ProjectInfo = |
| 76 | name: String |
| 77 | version: String |
| 78 | edition: String |
| 79 | |
| 80 | project => ProjectInfo |
| 81 | project = ProjectInfo "la-meva-super-eina" "0.1.0" "2026" |
| 82 | |
| 83 | source dir => String |
| 84 | source dir = "src/main/ridgun" |
| 85 | |
| 86 | test dir => String |
| 87 | test dir = "src/test/ridgun" |
| 88 | |
| 89 | target dir => String |
| 90 | target dir = "target" |
| 91 | |
| 92 | -- Opcional: activa el mode estricte de signatures i noms (desactivat per defecte) |
| 93 | strict mode => Bool |
| 94 | strict mode = True |
| 95 | ``` |
| 96 | |
| 97 | Si t'equivoques en escriure un camp, el mateix compilador t'avisa. Sense sorpreses. |
| 98 | |
| 99 | ### El mode estricte (`--strict` / `strict mode = True`) |
| 100 | Per defecte, tant `ridgunc` com els nous projectes creats amb `stable new` o `stable init` tenen el mode estricte **desactivat** perquè puguis prototipar amb total llibertat. Quan vulguis blindar l'estil canònic d'un projecte (com fem al propi compilador de Ridgun), pots passar `--strict` a `ridgunc` o afegir `strict mode = True` al teu `build.rg`. El mode estricte exigeix dues regles d'elegància: |
| 101 | 1. **Noms de `fn ::` i `op ::` amb espais naturals, sense `_`**: les declaracions han de fer servir espais (`fn :: calcular impost`, mai `fn :: calcular_impost`). |
| 102 | 2. **Retorns múltiples separats per espais després de `=>`**: quan una funció o operador retorna diversos valors, la seva signatura de sortida s'escriu `=> Int Int` o `=> Estat Int` (mai `=> (Int, Int)` amb parèntesis ni comes). |
| 103 | |
| 104 | --- |
| 105 | |
| 106 | ## 2.4. La teva rutina diària amb `stable` (Els 4 fantàstics) |
| 107 | |
| 108 | Quan estàs treballant dins del teu projecte, el teu dia a dia es redueix a quatre ordres: |
| 109 | |
| 110 | ### 1. `stable format` — La fi de les discussions d'estil a l'equip |
| 111 | ```bash |
| 112 | stable format |
| 113 | ``` |
| 114 | Que el teu company posa tres espais abans del `=>` i tu en poses un? Tant se val. Executes `stable format` i en menys d'un segon deixa **tots** els fitxers `.rg` del repositori alineats com una taula suïssa. |
| 115 | |
| 116 | ### 2. `stable check` — El radar instantani |
| 117 | ```bash |
| 118 | stable check |
| 119 | ``` |
| 120 | Recorre tots els mòduls de `src/main/ridgun/`, verifica tipus, constructors, aritats i dimensions de tensors, i et dóna el veredicte mòdul per mòdul. |
| 121 | |
| 122 | ### 3. `stable test` — Dormir tranquil a les nits |
| 123 | ```bash |
| 124 | stable test |
| 125 | ``` |
| 126 | Busca totes les suites `src/test/ridgun/test *.rg`, les executa i comprova cada `assert equals` i `assert true`. |
| 127 | |
| 128 | ```ridgun |
| 129 | -- Exemple de src/test/ridgun/test mates.rg |
| 130 | import test |
| 131 | |
| 132 | doble Int => Int |
| 133 | doble x = x * 2 |
| 134 | |
| 135 | main => () |
| 136 | main = |
| 137 | assert equals (doble 21) 42 |
| 138 | assert true ((doble 5) > 0) |
| 139 | ``` |
| 140 | |
| 141 | ### 4. `stable built` (i `stable clean`) — A producció |
| 142 | ```bash |
| 143 | stable built |
| 144 | ``` |
| 145 | Compila tots els objectius natius a `target/`. I si algun dia vols esborrar `target/` i començar de nou: `stable clean`. |
| 146 | |
| 147 | --- |
| 148 | |
| 149 | ## 2.5. Com importo un fitxer des d'un altre? (`import`) |
| 150 | |
| 151 | Sense rutes relatives infernals tipus `../../../lib/coses.rg`. Si tens un fitxer `src/main/ridgun/lib/cadenes.rg`, en qualsevol altre fitxer escrius a dalt de tot: |
| 152 | |
| 153 | ```ridgun |
| 154 | import cadenes |
| 155 | ``` |
| 156 | |
| 157 | I llestos: totes les funcions i tipus de `cadenes.rg` estan disponibles com si fossin al teu propi fitxer. I què passa si el mòdul `A` fa `import cadenes`, el mòdul `B` també fa `import cadenes`, i el teu `main.rg` importa `A` i `B`? Tranquil: el carregador de Ridgun recorda quins fitxers canònics ja ha llegit i **només l'inclou una vegada**. |
| 158 | |
| 159 | Ara que tens la caixa d'eines controlada, passem al **Capítol 03** per dominar les funcions, els tipus, els blocs i els trucs amb cadenes de text. |