Skip to content
Ridgun
English

Ridgun

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

00-per-que-necessito-ridgun.md133 lines · 8.1 KBRaw
1# Capítol 00: Per què necessito Ridgun? Ah, sí? No ho sabia... Explica-m'ho!
2
3Siguem sincers: quan algú et diu *"hem creat un nou llenguatge de programació"*, la teva primera reacció natural —i molt sana— és arquejar una cella i pensar:
4
5> *"Un altre? Però si ja tinc Python per anar ràpid, Rust o C per a quan necessito velocitat, i Bash per enganxar coses al terminal. Per a què dimonis necessito jo aprendre Ridgun?"*
6
7És una pregunta excel·lent. I la resposta curta és: **perquè t'has acostumat a patir quatre mals de cap diaris pensant que eren inevitables**.
8
9Posem-los nom.
10
11---
12
13## Mal de cap núm. 1: "La síndrome dels dos mons" (Prototipar en un, reescriure en un altre)
14
15Segur que has viscut aquesta pel·lícula:
16
171. Comences una eina o un motor de càlcul en **Python**, **JavaScript** o **Ruby** perquè vols pensar en el problema, no en punters ni en el compilador.
182. El codi queda curt i bonic... però quan li passes un fitxer de 500 MB o intentes fer servir els 16 nuclis de la teva màquina, s'arrossega. I si vols distribuir el teu programa a un servidor net, has d'empaquetar mig gigabyte d'entorn virtual, intèrpret i llibreries dinàmiques.
193. Resignat, decideixes reescriure'l en **C**, **C++** o **Rust**. Ara vola i ocupa uns pocs centenars de kilobytes, però el teu codi de 40 línies s'ha convertit en 300 línies plenes d'`unwrap()`, `&mut`, `'a`, `Arc<Mutex<...>>`, claus `{}` i punts i coma `;`.
20
21**Què canvia amb Ridgun?**
22En Ridgun escrius codi **més curt i net que en Python**, però quan executes `ridgunc build`, obtens **un únic binari natiu ELF de ~350 KB** sense intèrpret, sense màquina virtual externa i sense recol·lector de brossa. No hi ha fase de *"després ho reescrivim en el llenguatge ràpid"*: el codi net on penses el problema **ja és** el binari natiu de producció.
23
24---
25
26## Mal de cap núm. 2: "Llegir codi aliè (o el teu de fa 6 mesos) és jugar a fer de detectiu"
27
28Mira com escrivim lògica condicional en gairebé tots els llenguatges convencionals:
29
30```text
31if (estat == ACTIU && (rol == ADMIN || (rol == EDITOR && tePermis))) {
32 if (quota > 0) {
33 return processar(usuari);
34 } else {
35 return denegar("Sense quota");
36 }
37} else {
38 return denegar("No autoritzat");
39}
40```
41
42Els nostres ulls no van evolucionar per aparellar claus imbricades ni per desentranyar arbres d'`if / else` esglaonats. Quan els enginyers, matemàtics o físics volen entendre regles complexes sense equivocar-se, no escriuen paràgrafs d'`if / else`: **dibuixen una taula**.
43
44En Ridgun, **el codi és aquesta taula**:
45
46```ridgun
47autoritzar String String Bool Int => String
48autoritzar "actiu" "admin" _ quota =
49 | quota > 0 = "Processant petició"
50 | otherwise = "Denegat: sense quota"
51autoritzar "actiu" "editor" True quota =
52 | quota > 0 = "Processant petició"
53 | otherwise = "Denegat: sense quota"
54autoritzar _ _ _ _ = "Denegat: no autoritzat"
55```
56
57Mira les columnes:
58- Columna 1: l'estat (`"actiu"` o `_`).
59- Columna 2: el rol (`"admin"`, `"editor"` o `_`).
60- Columna 3: si té permís (`True` o `_`).
61- Columna 4: la `quota`.
62
63No has d'executar mentalment el programa línia per línia per saber què passa quan entra un `"editor"` amb permís `False`: els teus ulls baixen verticalment per la taula i ho veuen en mig segon.
64
65---
66
67## Mal de cap núm. 3: "El meu ordinador té 16 nuclis, però el meu programa només en fa servir 1 (perquè em fa pànic tocar fils)"
68
69Avui fins i tot el telèfon més modest té 8 nuclis, i qualsevol servidor o portàtil de feina en té entre 12 i 32. Tot i això, el 95% dels programes quotidians continuen executant-se en un sol fil seqüencial.
70
71Per què? Perquè en els llenguatges imperatius, paral·lelitzar significa obrir la caixa de Pandora:
72- I si dos fils modifiquen el mateix diccionari alhora? (*Data race*).
73- I si bloquejo el `Mutex` A i després el B en un fil, i el B i després l'A en un altre? (*Deadlock*).
74- I si contamino tota la meva base de codi amb `async` i `await` de dalt a baix?
75
76En Ridgun, **tota funció és pura i tota dada és immutable per defecte**. Això té una conseqüència màgica: **dues expressions que no depenen l'una de l'altra mai no poden interferir entre si**.
77
78Per això, en Ridgun no has de gestionar fils per aprofitar la teva CPU. Només declares **què depèn de què** amb barres paral·leles `||` i fletxes `->`:
79
80```ridgun
81informe mensual Dades => Informe
82informe mensual d = combinar metriques_xarxa metriques_disc metriques_cpu
83 || analitzar xarxa d -> metriques_xarxa
84 || analitzar disc d -> metriques_disc
85 || analitzar cpu d -> metriques_cpu
86```
87
88Tu només has escrit tres línies netes indicant d'on surt cada dada. El compilador veu que les tres branques són independents i sap que pot llançar-les en paral·lel sense que hi hagi ni la més mínima possibilitat d'un *data race* o un *deadlock*.
89
90I si necessites agents persistents amb bústia de missatges i estat aïllat (per exemple, per mantenir milers de sessions de clients, treballadors en segon pla o connexions de xarxa)? En Ridgun no cal definir classes `Actor` ni usar `Mutex`: **qualsevol funció normal es converteix en un agent autònom en una sola línia amb `agent`**:
91
92```ridgun
93comptador = agent (sumar visita) 0
94send 1 to comptador
95send 5 to comptador
96total = receive from comptador
97stop comptador
98```
99
100A més, el compilador realitza una **elecció intel·ligent en temps de compilació**: analitza estàticament la profunditat i el cost de cada funció a `||`, `||map`, `||filter` i `agent` per executar les funcions lleugeres com a passos *green-thread* de sobrecàrrega zero i despatxar automàticament els càlculs pesats o recursius a fils reals del nucli en múltiples nuclis (`SYS_clone`).
101
102---
103
104## Mal de cap núm. 4: "El recol·lector de brossa decideix pausar el món just en el pitjor moment"
105
106Els llenguatges funcionals clàssics (Haskell, OCaml, Erlang, Clojure) són meravellosos per raonar sobre el codi, però gairebé tots depenen d'un **Recol·lector de Brossa (*Garbage Collector*)** en temps d'execució. Això els descarta quan necessites:
107- Latències predicibles al microsegon.
108- Controlar exactament quanta memòria RAM pot consumir una operació abans d'avortar-la netament.
109- Escriure utilitats del sistema operatiu (`ls`, `find`, `sh`, `doas`, `make`) o tocar registres de maquinari (`MMIO`).
110
111Ridgun et dóna **tota l'elegància del món funcional pur, però amb Gestió de Memòria de Ridgun (`RMM`: `RMM1` estàtica i `RMM2` per recompte d'assignacions en cascada) més regions lèxiques amb quota exacta (`with region`)**:
112
113```ridgun
114analitzar paquet String => Result
115analitzar paquet cru =
116 with region 16_KB do
117 descodificar trama cru
118```
119
120Cada estructura temporal és alliberada de manera determinista pel compilador (`RMM1` / `RMM2`) en l'instant en què deixa d'utilitzar-se, i si un atacant t'envia un paquet maliciós dissenyat per rebentar la memòria, en superar el byte 16.384 la regió es talla a l'instant, allibera la seva arena en $O(1)$ i et retorna `Err OutOfMemory`. Sense caigudes del procés, sense pauses de GC i sense fuites de memòria.
121
122---
123
124## En resum: Quan brilla Ridgun?
125
126Ridgun està fet per a tu si alguna vegada has volgut:
127
1281. **Escriure eines de sistemes, compiladors, analitzadors o utilitats CLI** que arrenquin en microsegons, pesin uns pocs centenars de KB i no es puguin trencar per punters nuls ni efectes col·laterals ocults.
1292. **Construir sistemes concurrents i servidors basats en el Model Natiu d'Agents (`agent`, `send ... to`, `receive from`, `stop`)**, on qualsevol funció pura es converteix en un agent amb o sense estat aïllat i el compilador tria intel·ligentment entre execució *green-thread* ultralleugera i fils natius multinucli.
1303. **Programar algorismes, canonades de dades o àlgebra de tensors** on el compilador verifiqui per tu fins i tot les dimensions de les matrius (`Tensor[M, K] * Tensor[K, N] => Tensor[M, N]`) abans d'executar res.
1314. **Gaudir llegint el teu propi codi**: que cada fitxer `.rg` sembli una pàgina d'un llibre ben maquetat gràcies al formatador tabular automàtic (`stable format`).
132
133Et pica la curiositat? Passa al **Capítol 01** i escrivim el nostre primer programa en menys de dos minuts.