Skip to content
Ridgun
English

Ridgun

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

01-ongi-etorri-ridgunera.md195 lines · 11.8 KBRaw
1# 01. kapitulua: Zure lehen kontaktua Ridgunekin (Kaskorik gabe, giltzarik gabe eta puntu eta komarik gabe)
2
3Ados, 00. kapituluan konbentzitu zaitut ez gaudela zoratuta Ridgun sortzeagatik. Orain ziurrenik hau pentsatzen ari zara:
4
5> *"Oso polita taulen eta 16 nukleoen diskurtsoa, baina erakutsi benetako kodea. Zenbat denbora behar da funtzionatzen duen zerbait idazteko konpiladorearekin borrokatu gabe?"*
6
7Goazen ba harira!
8
9---
10
11## 1.1. "Kaixo, mundua!", baina mamiarekin
12
13Programazio-liburu gehienetan `print("Kaixo mundua")` motel bat erakusten dizute eta orrialdea pasatzen dute. Guk zuzenean benetako logika duen funtzio bat idatziko dugu, Ridgunek lehen minututik nola arnasten duen ikus dezazun.
14
15Sortu `kaixo.rg` izeneko fitxategi bat eta idatzi hau:
16
17```ridgun
18agurra String => String
19agurra "" = "Kaixo, bidaiari misteriotsua! (Ez didazu zure izena esan)"
20agurra "Root" = "Hara, Root! Kontuz gaur ezabatzen duzunarekin."
21agurra izena = "Kaixo, {izena}! Ongi etorri Ridgunera."
22
23main => ()
24main =
25 echo (agurra "Ada")
26 echo (agurra "Root")
27 echo (agurra "")
28```
29
30Oraintxe bertan exekutatzeko:
31
32```bash
33ridgunc run kaixo.rg
34```
35
36Eta zure terminalean hau ikusiko duzu:
37
38```text
39Kaixo, Ada! Ongi etorri Ridgunera.
40Hara, Root! Kontuz gaur ezabatzen duzunarekin.
41Kaixo, bidaiari misteriotsua! (Ez didazu zure izena esan)
42```
43
44Gelditu une batez eta begiratu goiko `agurra` blokeari. Nabaritzen duzu zer **EZ** dagoen?
45- **Ez dago `function`, ez `def`, ez `pub fn`** (sinaduraren aurrean `fn ::` jarri nahi baduzu, egin dezakezu, baina hautazkoa da).
46- **Ez dago `(String izena)` parentesirik, ezta `{ ... }` giltzarik ere** pantaila zikintzen.
47- **Ez dago `if (izena == "") ... else if (izena == "Root") ... else ...`**.
48- **Ez dago `return`-ik**.
49
50---
51
52## 1.2. Nola irakurtzen duen zure garunak `.rg` fitxategi bat
53
54Goazen `agurra`-ren lau lerro horiek xehatzera, hemen baitago dagoeneko Ridgunen filosofiaren % 50a:
55
56```ridgun
57agurra String => String
58agurra "" = "Kaixo, bidaiari misteriotsua! (Ez didazu zure izena esan)"
59agurra "Root" = "Hara, Root! Kontuz gaur ezabatzen duzunarekin."
60agurra izena = "Kaixo, {izena}! Ongi etorri Ridgunera."
61```
62
631. **Lehenengo lerroa kontratua da (`agurra String => String`)**:
64 Honela dio: *"`agurra` dut izena, `String` bat jasotzen dut eta beste `String` bat itzultzen dizut (`=>`)"*. Kitto. Norbait `42` zenbakia pasatuz deitzen saiatzen bada, konpiladoreak sorbaldan ukitu bat emango dio programa exekutatu aurretik ere.
652. **Beheko lerroak kasuak dira (goitik behera)**:
66 - `""` kate hutsa pasatu didazu? Lehenengo esaldia itzultzen dut.
67 - Zehazki `"Root"` pasatu didazu? Bigarren esaldia itzultzen dut.
68 - Beste edozer pasatu didazu? `izena` aldagaian gordetzen dut eta testuaren barruan sartzen dut `{izena}` erabiliz.
693. **Eta zer da `main => ()`?**:
70 `main`-ek argumenturik jasotzen ez duenez, `=>` zuzenean izenaren ondoren jartzen dugu. Eta `()` itzultzen du (mota hutsa edo *Unit*, lagunentzat), bere lan bakarra `echo`-rekin gauzak pantailatik ateratzea delako.
71
72---
73
74## 1.3. "Itxaron... zuriune horiek eskuz lerrokatu behar ditut fraide kopiatzaile baten moduan?"
75
76Inola ere ez! Zutabeak begiz zenbatuz zuriune-barrari eman beharko bazenio, hamar minutura utziko zenuke Ridgun (eta arrazoi osoz).
77
78Zuk kodea azkar idazten duzu, hitz bakoitzaren artean zuriune bakar batekin:
79
80```ridgun
81agurra String => String
82agurra "" = "Kaixo, bidaiari misteriotsua!"
83agurra izena = "Kaixo, {izena}!"
84```
85
86Eta **`stable format`** exekutatzen duzunean (edo Emacsen `ridgun-mode`-rekin `TAB` sakatzen / fitxategia gordetzen duzunean), formateatzaile kanonikoak parametro bakoitza bere motaren azpian kokatzen du eta `=` guztiak zehaztasun milimetrikoz lerrokatzen ditu. Zuk azkar idazten duzu; makinak taula maketatzen du.
87
88---
89
90## 1.4. Script azkarretik borrokako bitarrera komando bakarrean
91
92`ridgunc run kaixo.rg` egiten duzunean, programa hegaldian konpilatzen eta abiarazten ari zara. Baina imajinatu zure tresna amaitu duzula eta ekoizpen-zerbitzari batera eraman nahi duzula edo Ridgun instalatuta ez duen lankide batekin partekatu nahi duzula.
93
94Hau exekutatzen duzu:
95
96```bash
97ridgunc build kaixo.rg -o kaixo
98```
99
100Eta baduzu `./kaixo`: **Linux x86_64rako ELF exekutagarri natibo bat**, garbia, kode hilik gabe (*Tree-Shaking*), esteka osoko optimizazioarekin (*LTO*) eta kanpoko inongo interpretatzaileren menpe egon gabe.
101
102---
103
104## 1.5. Txuleta zintzoa: Nondik dator Ridgunen ideia bakoitza?
105
106Ridgunek ez du gurpil karratua berrasmatu nahi; konplexurik gabe hartzen du maileguan lau tradizioren onena:
107
108| Norengandik | Zer hartzen du Ridgunek | Zer uzten du kanpoan (zure osasun mentalagatik) |
109|---|---|---|
110| **Haskell / ML** | Funtzio puruak, kasukako *pattern matching*-a, datu-mota aljebraikoak (`Option`, `Result`) eta polimorfismoa (`A`..`Z`). | Monada abstraktuak, 40 `LANGUAGE pragma`-k eta zabor-biltzailea. |
111| **J / APL** | Kodearen forma taularatuarekiko obsesioa, tentsore natiboak eta sekuentzia-maskarak (`s(_ + _)`). | Teklatu arrunt batean idazteko ezinezkoak diren ikur hieroglifikoak. |
112| **Rust / C** | ELF bitar natibo txikiak, zero GC, memoriaren kontrola (`with region`) eta POSIX sistema-deiak. | *Borrow checker*-arekiko etengabeko borroka, `'a` *lifetime*-ak eta berritsukeria sintaktikoa. |
113| **Erlang / Go** | Agente isolatuak (`agent`, `send ... to`, `receive from`) eta kanal bidezko konkurrentzia (`new bounded channel`). | `nil` erakusleak eta deskuiduz partekatutako mutazioak. |
114
115---
116
117## 1.6. Eta garrantzitsuena: Zer egiten du Ridgunek beste INORK ez duena?
118
119Klasikoak aitortzea gizalegezkoa da, baina Ridgun beste lengoaia batzuen "arrakasta handien bilduma" hutsa balitz, ez zinateke liburu hau irakurtzen ariko.
120
121Badira Ridgunen diseinatu eta integratu ditugun **zortzi gauza**, egungo beste inongo lengoaiatan elkarrekin —eta horietako asko, ezta banaka ere— aurkituko ez dituzunak:
122
123### 1. `||` bloke paraleloak `->` geziekin: benetako grafo paraleloak dira, ez azukre sintaktiko hutsa
124Beste lengoaia funtzional batzuetan, aldagai lokalen bloke batek gero hari bakar batean ebaluatzen diren adierazpenak ordenatu baino ez ditu egiten.
125Ridgunen, **`||` bloke bat `->` geziekin exekuzio paraleloko Grafo Azikliko Zuzendu (DAG) bat da**, `where` bezalako hitz gako gehigarririk idatzi beharrik ere izan gabe:
126```ridgun
127urteko txostena Int => Int
128urteko txostena id = diru_sarrerak - gastuak
129 || kalkulatu salmentak id -> diru_sarrerak
130 || kalkulatu kostuak id -> gastuak
131```
132Zuk fluxu-geziak (`->`) marrazten dituzu. Konpiladoreak aztertzen du zer dagoen zeren menpe, **estatikoki egiaztatzen du ez duzula begizta infinitorik sortu**, eta adar independenteak paraleloan abiarazten ditu zuk `async`, `await`, `Future` edo `Mutex` bakar bat ere idatzi gabe.
133
134### 2. Marruskadurarik gabeko Agenteen Eredu Natiboa (`agent`) konpilazio-garaiko hari-aukeraketa adimendunarekin
135Beste lengoaia batzuetan, aktore edo agenteekin programatzeak klase bereziak sortzera, *trait*-ak inplementatzera, *lock*-ak kudeatzera edo funtzioak `async`-ekin kutsatzera behartzen zaitu.
136Ridgunen, **edozein funtzio puru arrunt (`fn ::` edo `op ::`) zuzenean agente autonomo bihurtzen da —egoera isolatuarekin edo gabe— `agent` erabiliz**:
137```ridgun
138erantzun http (Saioa, String) => (Saioa, String)
139...
140zerbitzaria = agent erantzun http hasierako_saioa
141send "GET /profila" to zerbitzaria
142erantzuna = receive from zerbitzaria
143stop zerbitzaria
144```
145Are hobeto: konpiladoreak **funtzioaren sakonera eta kostu konputazionala aztertzen ditu konpilazio-garaian** bai `agent`-en, bai `||` eta `||map`-en. Funtzioa arina bada, berehalako *green thread* gisa exekutatzen du sistema eragilearen hariak berotzearen kostua ordaindu gabe; kalkulu astuna edo errekurtsibo sakona bada, automatikoki paraleloan bidaltzen du kerneleko benetako harietara (`SYS_clone`) zure PUZaren nukleoetan zehar.
146
147### 3. Kodea bi dimentsioko taula gisa, non sinadura zutabeen goiburua den
148Beste edozein lengoaiatan, mota-sinadura bere aldetik doa lerro batean eta funtzioaren gorputza azpian doa testu arrunteko paragrafo baten moduan.
149Ridgunen, **mota-sinadura hitzez hitz taula baten goiburua da**, eta azpiko kasu bakoitzak eredu bakoitza bere motaren bertikalean bertan lerrokatzen du, eta `=` bakoitza `=>`-ren azpian:
150```ridgun
151zatitu Int Int => Option
152zatitu _ 0 = None
153zatitu a b = Some (a / b)
154```
155Beste inork ez ditu sinadura eta ekuazioak konpiladoreak egiaztatutako eta `stable format`-ek automatikoki maketatutako matrize bisual bakar gisa tratatzen.
156
157### 4. Esaldi-eragile (*Mixfix* N-ario) tipatuak eta lerrokatuak (`op ::`)
158Lengoaia gehienetan, edo `+`, `-`, `*`-rekin konformatzen zara, edo gehienez ere inork zer esan nahi duen ez dakien `<|>` bezalako eragile bitar kriptiko bat definitzen duzu.
159Ridgunen **nahi adina hutsune tipatu dituzten esaldi irakurgarriak diren eragileak** sor ditzakezu (`type` edo `with` bezalako testuinguruko hitzak barne):
160```ridgun
161op :: Int mugatua Int eta Int artean => Int
162 x mugatua min eta max artean =
163 | x < min = min
164 | x > max = max
165 | otherwise = x
166```
167Eta gero zure kodean `abiadura mugatua 0 eta 120 artean` idazten duzu. Euskara (edo ingelesa) bezala irakurtzen da, baina % 100ean tipatuta eta kode natibora konpilatuta dago.
168
169### 5. Maskara bisualak sekuentzien gainean (`s(_ + _)` eta `-> (+ _ _ +) ->`)
170Inoiz idatzi behar izan duzu indize-entsalada bat edo tupla bat aldagai mutuekin ireki bi posizio jakinekin geratzeko soilik?
171Ridgunen zuzenean **maskara bisual** bat pasatzen diozu:
172- `datuak(_ + _)`: lehenengoa baztertzen du (`_`), bigarrenarekin geratzen da (`+`), hirugarrena baztertzen du (`_`).
173- `parseatu paketea "v0.9.9" -> (+ _ _ +) -> konbinatu kodea -> laburpena`: 4 elementuko tupla bat hodian bertan iragazten du eta 1.a eta 4.a zuzenean hurrengo funtzioaren argumentu gisa pasatzen ditu.
174Zero indize-aritmetika, zero *off-by-one* errore.
175
176### 6. "Zerozko zarata" duen polimorfismoa (`A`..`Z`), zure domeinuak gobernatua
177Rust, TypeScript edo Javan, funtzio bat generikoa denean lerroa parentesi angeluarrez bete behar duzu: `fn trukatu<A, B>(bikotea: (A, B)) -> (B, A)`.
178Ridgunen letra larri solte bat erabiltzen duzu, besterik gabe:
179```ridgun
180trukatu (A, B) => (B, A)
181trukatu (x, y) = (y, x)
182```
183*"Eta nire programan `type A` deitzen den benetako mota bat eduki nahi badut?"* — Arazorik ez: Ridgunen **zure `type` deklarazioek agintzen dute**. `type A` existitzen ez bada, `A` generikoa da; `type A = ...` definitzen duzun une berean, zure mota zehatza izatera pasatzen da modulu osoan.
184
185### 7. Zero konfigurazio-fitxategi arrotz: `build.rg` Ridgun purua da
186Ahaztu Cargorako TOML, npm-rako JSON, Mavenerako XML edo tabuladore ikusezinak dituen `Makefile`-ren sintaxi arkanoa ikasteaz. Ridgunen, zure proiektua eraikitzen duen errezeta (`build.rg`) **beste `.rg` fitxategi bat gehiago da**, zure gainerako kodearen funtzio puru eta *pattern matching* berberekin.
187
188### 8. Ezinezkoa zirudien "Hirutasun Santua": Haskell maila + RMM memoria GC eta Lifetimerik gabe + ~350 KB-ko bitarrak
189Gaur arte aukeratu egin behar zenuen:
190- Adierazkortasun funtzional purua nahi bazenuen (Haskell, OCaml, Elixir), zabor-biltzaile batekin eta runtime astun batekin ordaintzen zenuen.
191- Zabor-biltzailerik gabeko sistemako bitar ñimiñoak nahi bazenituen (C, Rust, Zig), erakusleak kudeatuz edo *borrow checker*-arekin borrokatuz eta `let mut`-ez betetako kode inperatiboa idatziz ordaintzen zenuen.
192
193Ridgunek dilema hori hausten du **Ridgun Memory Management (`RMM`: `RMM1` estatikoa eta `RMM2` esleipen-kontaketa kaskadakoarekin)**, arena osoak $O(1)$-ean askatzen dituzten **eskualde lexikoak (`with region`)**, **begizta natibo (`loop`) bihurtutako isats-errekurtsioa** eta `main`-etik abiatutako **dei-grafoaren inausketa (*Tree-Shaking*)** konbinatuz. Emaitza: maila goren-goreneko kode deklaratiboa idazten duzu eta C-n idatzitako tresnekin buruz buru lehiatzeko gai den **~350 KB**-ko ELF exekutagarri autonomo bat lortzen duzu.
194
195Orain bai: kartak mahai gainean ditugula, goazen **02. kapitulura** **`ridgunc`** eta **`stable`** lanean jartzera.