Skip to content
Ridgun
English

Ridgun

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

03-funcions-tipus-i-alineacio.md159 lines · 8.2 KBRaw
1# Capítol 03: Funcions, signatures de tipus i l'art d'escriure codi com una taula
2
3Hi ha una pregunta que tot programador es fa la primera vegada que veu codi funcional:
4
5> *"Si aquí no hi ha classes, ni objectes, ni variables que canvien de valor... aleshores on fico la meva lògica?"*
6
7En **funcions**. Però no en aquelles funcions de 200 línies plenes de banderes booleanes que tots hem patit alguna vegada, sinó en funcions petites, directes i tan fàcils de llegir que semblen una taula en una pissarra.
8
9Vegem com es construeixen.
10
11---
12
13## 3.1. Dues maneres de presentar una funció (Tu tries el vestit)
14
15En Ridgun tota funció comença amb la seva **signatura de tipus** (què entra i què surt després de `=>`) i a sota hi van les seves **clàusules d'implementació** (amb `=`).
16
17Pots escriure la capçalera de dues maneres:
18
19### Opció A: Directa al gra (sense prefix)
20```ridgun
21aplicar descompte Int Int => Int
22aplicar descompte preu percentatge = preu - (preu * percentatge / 100)
23```
24
25### Opció B: Amb etiqueta explícita (`fn ::`)
26```ridgun
27fn :: aplicar descompte Int Int => Int
28 aplicar descompte preu percentatge = preu - (preu * percentatge / 100)
29```
30
31*"Escolta, i per què existeixen totes dues?"*
32Perquè per a gustos, els colors:
33- Hi ha qui prefereix que les funcions comencin enganxades al marge esquerre sense escriure `fn ::` cada vegada (al cap i a la fi, la fletxa `=>` ja crida als quatre vents que aquella línia és una signatura de tipus).
34- I hi ha qui prefereix tenir una columna esquerra dedicada a les etiquetes (`fn ::`, `op ::`, `type`, `import`) per escanejar el fitxer visualment.
35
36El compilador i `stable format` entenen totes dues a la perfecció. A més, les paraules `fn` i `op` es poden fer servir lliurement com a part del nom de qualsevol funció o operador (per exemple `fn :: op`, `op :: fn` o `op :: op`), i si una funció retorna múltiples valors, en mode canònic/estricte els tipus de sortida s'escriuen separats per espais després de `=>` (`dividir amb residu Int Int => Int Int`).
37
38---
39
40## 3.2. La màgia de les columnes: per què els teus ulls descansen
41
42Mira aquesta funció que calcula el cost d'un enviament segons el país i si és urgent:
43
44```ridgun
45cost enviament String Bool Int => Int
46cost enviament "ES" False _ = 5
47cost enviament "ES" True _ = 12
48cost enviament _ False pes = 10 + (pes * 2)
49cost enviament _ True pes = 25 + (pes * 4)
50```
51
52Fes la prova: tapa la meitat dreta de la pantalla i mira només les tres columnes d'entrada:
53- Primera columna (`String`): `"ES"`, `"ES"`, `_`, `_`.
54- Segona columna (`Bool`): `False`, `True`, `False`, `True`.
55- Tercera columna (`Int`): `_`, `_`, `pes`, `pes`.
56
57Hi veus cap forat lògic? Cap ni un: hi ha les 4 combinacions possibles davant dels teus nassos, alineades verticalment sota `String`, `Bool` i `Int`. En un bloc d'`if / else` tradicional hauries de llegir 18 línies per estar segur que no t'has deixat cap cas penjat.
58
59---
60
61## 3.3. Els tipus bàsics i un regal per no comptar zeros (`_KB`, `_MB`, `_GB`)
62
63Els tipus escalars de Ridgun són directes i sense sorpreses:
64
65| Tipus | Què és en realitat | Exemples |
66|---|---|---|
67| `Int` | Enter de 64 bits amb signe (`i64`) | `0`, `42`, `-100`, `0xFF00`, `1_000_000` |
68| `U64` | Enter de 64 bits sense signe (`u64`) amb aritmètica modular i bit a bit nativa | `u64 0`, `u64 0x6a09e667f3bcc908`, `a ^ b`, `a << u64 13` |
69| `Float` / `Real` | Decimal de doble precisió (`f64`) | `3.14159`, `0.001`, `-2.5` |
70| `String` | Cadena de text immutable | `"Hola"`, `'ruta\crua'` |
71| `Char` | Codi de caràcter | Retornat per `str char at` |
72| `Bool` | Booleà de tota la vida | `True`, `False` |
73| `()` | Buit (*Unit*, quan només imprimeixes o fas I/O) | `()` |
74
75### Cansat d'escriure `65536` o `1048576` i resar per no haver-te menjat un dígit?
76En Ridgun els literals numèrics accepten directament els sufixos **`_KB`**, **`_MB`** i **`_GB`**, a més de guions baixos `_` per separar grups de xifres:
77
78```ridgun
79mida buffer => Int
80mida buffer = 64_KB -- El compilador ho tradueix a 65536
81
82limit fitxer => Int
83limit fitxer = 16_MB -- El compilador ho tradueix a 16777216
84
85mascara octet => Int
86mascara octet = 0xFF_00 -- Hexadecimal net i llegible
87```
88
89---
90
91## 3.4. Cometes dobles (`"..."`) vs. Cometes simples (`'...'`)
92
93En molts llenguatges les cometes simples i dobles fan exactament el mateix (un malbaratament). En Ridgun cadascuna té una missió claríssima:
94
95### 1. Cometes dobles (`"..."`): Intel·ligents i interpolades
96Interpreten escapaments (`\n`, `\t`, `\"`, `\\`) i **avaluen qualsevol variable o expressió que posis entre claus `{...}`**:
97
98```ridgun
99resum comanda String Int Int => String
100resum comanda item uts preu =
101 "Has demanat {uts}x {item}. Total a pagar: {uts * preu} euros."
102```
103
104*(Truc: si necessites escriure una clau literal dins de cometes dobles —per exemple en generar un script de shell `"$\{VAR:-default\}"` o un JSON—, pots escapar-la amb barra invertida `\{` i `\}` o duplicar-la `{{` i `}}`).*
105
106### 2. Cometes simples (`'...'`): Crues i literals (*Raw Strings*)
107El que escrius entre cometes simples surt **tal qual**, sense tocar ni una barra invertida `\`, ni una clau `{}`. Perfecte per a quan generes codi en un altre llenguatge, escrius ordres de shell o treballes amb rutes plenes de barres:
108
109```ridgun
110ordre sed => String
111ordre sed = 's/\([0-9]+\)/[\1]/g'
112```
113
114### La teva caixa d'eines per a cadenes (`String`)
115Unir cadenes és tan simple com sumar-les amb `+`: `"Hola, " + nom`. I quan necessites fer cirurgia fina sobre un text, tens aquestes funcions natives a punt sense importar res:
116
117- `str len s` $\rightarrow$ longitud de `s`.
118- `str char at s i` $\rightarrow$ codi numèric (`Int`) del caràcter a la posició `i` (`-1` si et passes).
119- `str slice s inici fi` $\rightarrow$ retalla des d'`inici` fins a `fi` (sense incloure `fi`).
120- `char from code c` $\rightarrow$ converteix un codi numèric (`Int`, p. ex. `10` per a `\n` o `34` per a `"`) en un `String` d'1 caràcter.
121- `str contains s agulla` i `str starts with s prefix` $\rightarrow$ retornen `True` o `False`.
122- `int to str n` i `str to int s` $\rightarrow$ converteixen de número a text i viceversa (`str to int` entén fins i tot `"0xFF"`!).
123
124---
125
126## 3.5. Blocs de diverses línies, la regla universal de l'`=` i variables `mut`
127
128Quan una funció no cap en una sola línia, fas un salt de línia després de l'`=` i sagnes el bloc.
129
130Mira com es llegeix un bloc pas a pas:
131
132```ridgun
133calcular factura Int Int => Int
134calcular factura base iva_pct =
135 impostos = base * iva_pct / 100
136 despeses_gestio = 5
137 echo "Desglossament -> Base:" base "Impostos:" impostos
138 base + impostos + despeses_gestio
139```
140
141Quatre regles d'or que fan que els blocs en Ridgun siguin nets i uniformes:
1421. **Immutable per defecte sense `let` ni `const`**: escrius `impostos = ...` i ja tens la teva constant local immutable. Si per descuit intentes sobreescriure `impostos = 99` més avall en el mateix bloc, el compilador et frena en sec.
1432. **Variables mutables explícites amb `mut`**: quan de debò vols anar actualitzant un acumulador local pas a pas dins d'una funció, el declares amb **`mut`** i després el reassignes lliurement amb `=`:
144 ```ridgun
145 aplicar recarrecs Int => Int
146 aplicar recarrecs preu =
147 mut total = preu
148 total = total + 10
149 total = total * 2
150 total
151 ```
152 *(I si `total` desa una llista o estructura en memòria, la política **`RMM2`** de Ridgun suma `+1` al nou valor abans de descomptar `-1` a l'antic, alliberant-lo a l'instant si ningú més el fa servir).*
1533. **La regla universal de l'`=`**: darrere de **qualsevol `=`** (en una funció, en un operador, en una variable local `x =` o en una branca condicional) pots posar sempre qualsevol de les tres formes de bloc de Ridgun:
154 - **`(res)`**: línies seqüencials sagnades (com a dalt).
155 - **`|`**: un arbre de guardes condicionals.
156 - **`||`**: un graf de càlculs en paral·lel amb `->`.
1574. **L'última expressió és sempre el resultat**: `base + impostos + despeses_gestio` és el que retorna `calcular factura`. Sense `return`.
158
159Al **Capítol 04** veurem com prendre decisions complexes —incloent-hi arbres de decisió de diversos nivells amb `|.`— sense escriure mai un `if/else` ni un bucle `while`: benvingut al món de les **guardes booleanes** i la **recursió de cua de cost zero**.