Skip to content
Ridgun
English

Ridgun

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

00-varfor-behover-jag-ridgun.md133 lines · 8.1 KBRaw
1# Kapitel 00: Varför behöver jag Ridgun? Jaså? Det visste jag inte... Berätta mer!
2
3Låt oss vara ärliga: när någon säger *"vi har skapat ett nytt programmeringsspråk"* är din första naturliga — och mycket sunda — reaktion att höja på ögonbrynet och tänka:
4
5> *"Ännu ett? Men jag har ju redan Python när det ska gå fort, Rust eller C när jag behöver prestanda, och Bash för att klistra ihop saker i terminalen. Varför i hela friden skulle jag behöva lära mig Ridgun?"*
6
7Det är en utmärkt fråga. Och det korta svaret är: **därför att du har vant dig vid att lida av tre dagliga plågor i tron att de var oundvikliga**.
8
9Låt oss sätta namn på dem.
10
11---
12
13## Plåga nr 1: "Tvåvärldssyndromet" (Prototypa i ett språk, skriva om i ett annat)
14
15Du har säkert varit med om den här filmen:
16
171. Du påbörjar ett verktyg eller en beräkningsmotor i **Python**, **JavaScript** eller **Ruby** eftersom du vill tänka på problemet, inte på pekare eller kompilatorn.
182. Koden blir kort och vacker... men när du matar den med en fil på 500 MB eller försöker utnyttja alla 16 kärnor i din dator kryper den fram. Och om du vill distribuera ditt program till en ren server måste du paketera en halv gigabyte med virtuell miljö, tolk och dynamiska bibliotek.
193. Uppgiven bestämmer du dig för att skriva om det i **C**, **C++** eller **Rust**. Nu flyger det fram och tar bara några hundra kilobyte, men din kod på 40 rader har förvandlats till 300 rader fulla av `unwrap()`, `&mut`, `'a`, `Arc<Mutex<...>>`, måsvingar `{}` och semikolon `;`.
20
21**Vad förändras med Ridgun?**
22I Ridgun skriver du kod som är **kortare och renare än i Python**, men när du kör `ridgunc build` får du **en enda inbyggd ELF-binär på ~350 KB** utan tolk, utan extern virtuell maskin och utan skräpsamlare (*Garbage Collector*). Det finns ingen fas där man säger *"vi skriver om det i det snabba språket senare"*: den rena koden där du formulerar problemet **är redan** produktionsbinären.
23
24---
25
26## Plåga nr 2: "Att läsa andras kod (eller din egen från för 6 månader sedan) är som att leka detektiv"
27
28Titta på hur vi skriver villkorslogik i nästan alla vanliga språk:
29
30```text
31if (status == AKTIV && (roll == ADMIN || (roll == REDAKTOR && harBehorighet))) {
32 if (kvot > 0) {
33 return bearbeta(anvandare);
34 } else {
35 return neka("Ingen kvot");
36 }
37} else {
38 return neka("Obehörig");
39}
40```
41
42Våra ögon har inte utvecklats för att para ihop nästlade måsvingar eller nysta upp trappstegsformade `if / else`-träd. När ingenjörer, matematiker eller fysiker vill förstå komplexa regler utan att göra fel skriver de inte stycken av `if / else`: **de ritar en tabell**.
43
44I Ridgun **är koden den tabellen**:
45
46```ridgun
47auktorisera String String Bool Int => String
48auktorisera "aktiv" "admin" _ kvot =
49 | kvot > 0 = "Bearbetar begäran"
50 | otherwise = "Nekad: ingen kvot"
51auktorisera "aktiv" "redaktor" True kvot =
52 | kvot > 0 = "Bearbetar begäran"
53 | otherwise = "Nekad: ingen kvot"
54auktorisera _ _ _ _ = "Nekad: obehörig"
55```
56
57Titta på kolumnerna:
58- Kolumn 1: statusen (`"aktiv"` eller `_`).
59- Kolumn 2: rollen (`"admin"`, `"redaktor"` eller `_`).
60- Kolumn 3: om behörighet finns (`True` eller `_`).
61- Kolumn 4: `kvot`.
62
63Du behöver inte köra programmet mentalt rad för rad för att veta vad som händer när en `"redaktor"` med behörigheten `False` kommer in: blicken glider vertikalt nedför tabellen och du ser det på en halv sekund.
64
65---
66
67## Plåga nr 3: "Min dator har 16 kärnor, men mitt program använder bara 1 (för att jag får panik av att röra trådar)"
68
69I dag har till och med den enklaste telefonen 8 kärnor, och varje server eller arbetsdator har mellan 12 och 32. Ändå körs 95 % av alla vardagliga program fortfarande i en enda sekventiell tråd.
70
71Varför? Därför att i imperativa språk innebär parallellisering att öppna Pandoras ask:
72- Tänk om två trådar ändrar samma uppslagsverk samtidigt? (*Data race*).
73- Tänk om jag låser `Mutex` A och sedan B i en tråd, och B och sedan A i en annan? (*Deadlock*).
74- Tänk om jag förorenar hela min kodbas med `async` och `await` uppifrån och ner?
75
76I Ridgun **är varje funktion ren och all data oföränderlig (*immutable*) som standard**. Det får en magisk konsekvens: **två uttryck som inte är beroende av varandra kan aldrig någonsin störa varandra**.
77
78Därför behöver du inte hantera trådar i Ridgun för att utnyttja din processor. Du deklarerar bara **vad som beror på vad** med parallella streck `||` och pilar `->`:
79
80```ridgun
81manadsrapport Data => Rapport
82manadsrapport d = kombinera nat_matt disk_matt cpu_matt
83 || analysera nat d -> nat_matt
84 || analysera disk d -> disk_matt
85 || analysera cpu d -> cpu_matt
86```
87
88Du har bara skrivit tre rena rader som anger varifrån varje datamängd kommer. Kompilatorn ser att de tre grenarna är oberoende och vet att den kan starta dem parallellt utan minsta risk för vare sig *data race* eller *deadlock*.
89
90Och vad gör du om du behöver långlivade agenter med inkorg och isolerat tillstånd (till exempel för att hålla tusentals klientsessioner, bakgrundsarbetare eller nätverksanslutningar)? I Ridgun behöver du varken definiera `Actor`-klasser eller använda `Mutex`: **vilken vanlig funktion som helst blir en autonom agent på en enda rad med `agent`**:
91
92```ridgun
93raknare = agent (addera besok) 0
94send 1 to raknare
95send 5 to raknare
96totalt = receive from raknare
97stop raknare
98```
99
100Dessutom gör kompilatorn ett **smart val vid kompilering**: den analyserar statiskt djupet och kostnaden för varje funktion i `||`, `||map`, `||filter` och `agent` för att köra lätta funktioner som *green-thread*-steg utan overhead och automatiskt skicka tunga eller djupt rekursiva beräkningar till riktiga kärntrådar över flera CPU-kärnor (`SYS_clone`).
101
102---
103
104## Plåga nr 4: "Skräpsamlaren bestämmer sig för att pausa hela världen i exakt fel ögonblick"
105
106Klassiska funktionella språk (Haskell, OCaml, Erlang, Clojure) är underbara för att resonera kring kod, men nästan alla är beroende av en **skräpsamlare (*Garbage Collector*)** vid körning. Det utesluter dem när du behöver:
107- Förutsägbara svarstider på mikrosekundnivå.
108- Exakt kontroll över hur mycket RAM-minne en operation får förbruka innan den avbryts snyggt.
109- Skriva operativsystemverktyg (`ls`, `find`, `sh`, `doas`, `make`) eller arbeta direkt mot hårdvaruregister (`MMIO`).
110
111Ridgun ger dig **hela elegansen från den rent funktionella världen, men med Ridguns minneshantering (`RMM`: statisk `RMM1` och kaskadräknad `RMM2`) plus lexikala regioner med exakt kvot (`with region`)**:
112
113```ridgun
114tolka paket String => Result
115tolka paket radata =
116 with region 16_KB do
117 avkoda ram radata
118```
119
120Varje tillfällig struktur frigörs deterministiskt av kompilatorn (`RMM1` / `RMM2`) i samma ögonblick som den slutar användas, och om en angripare skickar ett skadligt paket utformat för att spränga minnet klipps regionen omedelbart när den passerar byte 16 384, frigör sin arena i $O(1)$ och returnerar `Err OutOfMemory`. Inga kraschade processer, inga GC-pauser och inga minnesläckor.
121
122---
123
124## Sammanfattningsvis: När glänser Ridgun?
125
126Ridgun är skapat för dig om du någonsin har velat:
127
1281. **Skriva systemverktyg, kompilatorer, parsrar eller CLI-verktyg** som startar på mikrosekunder, väger några hundra KB och inte kan krascha på grund av null-pekare eller dolda sidoeffekter.
1292. **Bygga samtidiga system och servrar med den inbyggda agentmodellen (`agent`, `send ... to`, `receive from`, `stop`)**, där varje ren funktion kan bli en agent med eller utan isolerat tillstånd och kompilatorn smart väljer mellan ultralätta *green-thread*-steg och flerkärniga operativsystemtrådar.
1303. **Programmera algoritmer, datapipelines eller tensoralgebra** där kompilatorn kontrollerar ända ner till matrisdimensionerna åt dig (`Tensor[M, K] * Tensor[K, N] => Tensor[M, N]`) innan något ens körs.
1314. **Njuta av att läsa din egen kod**: låta varje `.rg`-fil se ut som en sida ur en välformgiven bok tack vare den automatiska tabellformateraren (`stable format`).
132
133Har vi väckt din nyfikenhet? Gå vidare till **Kapitel 01** så skriver vi vårt första program på under två minuter.