Ridgun
The language itself: a compiler that compiles itself, the stable project tool, the specification and the book
| 1 | # 03. kapitulua: Funtzioak, mota-sinadurak eta kodea taula bat bezala idaztearen artea |
| 2 | |
| 3 | Badago galdera bat programatzaile orok bere buruari egiten diona kode funtzionala ikusten duen lehen aldian: |
| 4 | |
| 5 | > *"Hemen klaserik, objekturik edo balioz aldatzen diren aldagairik ez badago... orduan non sartzen dut nire logika?"* |
| 6 | |
| 7 | **Funtzioetan**. Baina ez guztiok noizbait pairatu ditugun bandera boolearrez betetako 200 lerroko funtzio horietan, baizik eta funtzio txiki, zuzen eta irakurtzeko hain errazetan, ezen arbel bateko taula bat baitirudite. |
| 8 | |
| 9 | Ikus dezagun nola eraikitzen diren. |
| 10 | |
| 11 | --- |
| 12 | |
| 13 | ## 3.1. Funtzio bat aurkezteko bi modu (Zuk aukeratzen duzu trajea) |
| 14 | |
| 15 | Ridgunen funtzio oro bere **mota-sinadurarekin** hasten da (zer sartzen den eta zer ateratzen den `=>` ondoren) eta azpian bere **inplementazio-klausulak** doaz (`=` ikurrarekin). |
| 16 | |
| 17 | Goiburua bi modutara idatz dezakezu: |
| 18 | |
| 19 | ### A aukera: Zuzenean harira (aurrizkirik gabe) |
| 20 | ```ridgun |
| 21 | aplikatu beherapena Int Int => Int |
| 22 | aplikatu beherapena prezioa ehunekoa = prezioa - (prezioa * ehunekoa / 100) |
| 23 | ``` |
| 24 | |
| 25 | ### B aukera: Etiketa esplizituarekin (`fn ::`) |
| 26 | ```ridgun |
| 27 | fn :: aplikatu beherapena Int Int => Int |
| 28 | aplikatu beherapena prezioa ehunekoa = prezioa - (prezioa * ehunekoa / 100) |
| 29 | ``` |
| 30 | |
| 31 | *"Aizu, eta zergatik existitzen dira biak?"* |
| 32 | Gustuak askotarikoak direlako: |
| 33 | - Bada nahiago duena funtzioak ezkerreko marjinari itsatsita hastea aldi bakoitzean `fn ::` idatzi gabe (azken finean, `=>` geziak lau haizeetara oihukatzen du lerro hori mota-sinadura bat dela). |
| 34 | - Eta bada nahiago duena ezkerreko zutabe bat etiketei (`fn ::`, `op ::`, `type`, `import`) eskainita edukitzea fitxategia bisualki eskaneatzeko. |
| 35 | |
| 36 | Konpiladoreak eta `stable format`-ek biak ezin hobeto ulertzen dituzte. Gainera, `fn` eta `op` hitzak askatasunez erabil daitezke edozein funtzio edo eragileren izenaren parte gisa (adibidez `fn :: op`, `op :: fn` edo `op :: op`), eta funtzio batek balio anitz itzultzen baditu, modu kanoniko/zorrotzean irteera-motak zuriunez bereizita idazten dira `=>` ondoren (`zatitu hondarrarekin Int Int => Int Int`). |
| 37 | |
| 38 | --- |
| 39 | |
| 40 | ## 3.2. Zutabeen magia: zergatik zure begiek atseden hartzen duten |
| 41 | |
| 42 | Begira bidalketa baten kostua herrialdearen eta premiazkoa den ala ez kontuan hartuta kalkulatzen duen funtzio honi: |
| 43 | |
| 44 | ```ridgun |
| 45 | bidalketa kostua String Bool Int => Int |
| 46 | bidalketa kostua "EH" False _ = 5 |
| 47 | bidalketa kostua "EH" True _ = 12 |
| 48 | bidalketa kostua _ False pisua = 10 + (pisua * 2) |
| 49 | bidalketa kostua _ True pisua = 25 + (pisua * 4) |
| 50 | ``` |
| 51 | |
| 52 | Egin proba: estali pantailaren eskuineko erdia eta begiratu sarrerako hiru zutabeei bakarrik: |
| 53 | - Lehenengo zutabea (`String`): `"EH"`, `"EH"`, `_`, `_`. |
| 54 | - Bigarren zutabea (`Bool`): `False`, `True`, `False`, `True`. |
| 55 | - Hirugarren zutabea (`Int`): `_`, `_`, `pisua`, `pisua`. |
| 56 | |
| 57 | Ikusten duzu zulo logikorik? Bat ere ez: 4 konbinazio posibleak zure sudurraren aurrean daude, `String`, `Bool` eta `Int`-en azpian bertikalki lerrokatuta. Ohiko `if / else` bloke batean 18 lerro irakurri beharko zenituzke kasu solterik utzi ez duzula ziurtatzeko. |
| 58 | |
| 59 | --- |
| 60 | |
| 61 | ## 3.3. Oinarrizko motak eta opari bat zeroak ez zenbatzeko (`_KB`, `_MB`, `_GB`) |
| 62 | |
| 63 | Ridgunen mota eskalarrak zuzenak eta ezustekorik gabeak dira: |
| 64 | |
| 65 | | Mota | Zer den benetan | Adibideak | |
| 66 | |---|---|---| |
| 67 | | `Int` | Zeinudun 64 biteko osokoa (`i64`) | `0`, `42`, `-100`, `0xFF00`, `1_000_000` | |
| 68 | | `U64` | Zeinurik gabeko 64 biteko osokoa (`u64`) aritmetika modular eta bit-eragiketa natiboekin | `u64 0`, `u64 0x6a09e667f3bcc908`, `a ^ b`, `a << u64 13` | |
| 69 | | `Float` / `Real` | Doitasun bikoitzeko hamartarra (`f64`) | `3.14159`, `0.001`, `-2.5` | |
| 70 | | `String` | Testu-kate aldaezina | `"Kaixo"`, `'bide\gordina'` | |
| 71 | | `Char` | Karaktere-kodea | `str char at`-ek itzulia | |
| 72 | | `Bool` | Betiko boolearra | `True`, `False` | |
| 73 | | `()` | Hutsa (*Unit*, inprimatu edo I/O bakarrik egiten duzunean) | `()` | |
| 74 | |
| 75 | ### Nazkatuta `65536` edo `1048576` idazteaz eta digitu bat jan ez izateko otoitz egiteaz? |
| 76 | Ridgunen zenbakizko literalek zuzenean onartzen dituzte **`_KB`**, **`_MB`** eta **`_GB`** atzizkiak, zifra-taldeak bereizteko `_` azpimarrez gain: |
| 77 | |
| 78 | ```ridgun |
| 79 | buffer tamaina => Int |
| 80 | buffer tamaina = 64_KB -- Konpiladoreak 65536ra itzultzen du |
| 81 | |
| 82 | fitxategi muga => Int |
| 83 | fitxategi muga = 16_MB -- Konpiladoreak 16777216ra itzultzen du |
| 84 | |
| 85 | zortzikote maskara => Int |
| 86 | zortzikote maskara = 0xFF_00 -- Hamaseitar garbia eta irakurgarria |
| 87 | ``` |
| 88 | |
| 89 | --- |
| 90 | |
| 91 | ## 3.4. Komatxo bikoitzak (`"..."`) vs. Komatxo bakunak (`'...'`) |
| 92 | |
| 93 | Lengoaia askotan komatxo bakunek eta bikoitzek gauza bera egiten dute zehazki (alferrikako xahuketa). Ridgunen bakoitzak eginkizun oso argia du: |
| 94 | |
| 95 | ### 1. Komatxo bikoitzak (`"..."`): Adimendunak eta interpolatuak |
| 96 | Ihes-sekuentziak (`\n`, `\t`, `\"`, `\\`) interpretatzen dituzte eta **`{...}` giltzen artean sartzen duzun edozein aldagai edo adierazpen ebaluatzen dute**: |
| 97 | |
| 98 | ```ridgun |
| 99 | eskaera laburpena String Int Int => String |
| 100 | eskaera laburpena gaia kop prezioa = |
| 101 | "{kop}x {gaia} eskatu duzu. Ordaintzeko guztira: {kop * prezioa} euro." |
| 102 | ``` |
| 103 | |
| 104 | *(Trikimailua: komatxo bikoitzen barruan giltza literal bat idatzi behar baduzu —adibidez `"$\{VAR:-default\}"` shell script bat edo JSON bat sortzean—, alderantzizko barrarekin ihes egin diezaiokezu `\{` eta `\}` erabiliz edo bikoiztu `{{` eta `}}`).* |
| 105 | |
| 106 | ### 2. Komatxo bakunak (`'...'`): Gordinak eta literalak (*Raw Strings*) |
| 107 | Komatxo bakunen artean idazten duzuna **bere horretan** ateratzen da, alderantzizko barra `\` bakar bat edo `{}` giltza bat ere ukitu gabe. Ezin hobea beste lengoaia batean kodea sortzen duzunerako, shell komandoak idazten dituzunerako edo barraz betetako bideekin lan egiten duzunerako: |
| 108 | |
| 109 | ```ridgun |
| 110 | sed komandoa => String |
| 111 | sed komandoa = 's/\([0-9]+\)/[\1]/g' |
| 112 | ``` |
| 113 | |
| 114 | ### Testu-kateetarako (`String`) zure tresna-kutxa |
| 115 | Kateak lotzea `+` ikurrarekin batzea bezain sinplea da: `"Kaixo, " + izena`. Eta testu baten gainean kirurgia fina egin behar duzunean, funtzio natibo hauek prest dituzu ezer inportatu gabe: |
| 116 | |
| 117 | - `str len s` $\rightarrow$ `s`-ren luzera. |
| 118 | - `str char at s i` $\rightarrow$ `i` posizioko karakterearen zenbakizko kodea (`Int`) (`-1` kanpora ateratzen bazara). |
| 119 | - `str slice s hasiera amaiera` $\rightarrow$ `hasiera`-tik `amaiera`-ra mozten du (`amaiera` sartu gabe). |
| 120 | - `char from code c` $\rightarrow$ zenbakizko kode bat (`Int`, adib. `10` `\n`-rako edo `34` `"`-rako) karaktere 1eko `String` bihurtzen du. |
| 121 | - `str contains s orratza` eta `str starts with s aurrizkia` $\rightarrow$ `True` edo `False` itzultzen dute. |
| 122 | - `int to str n` eta `str to int s` $\rightarrow$ zenbakitik testura eta alderantziz bihurtzen dute (`str to int`-ek `"0xFF"` ere ulertzen du!). |
| 123 | |
| 124 | --- |
| 125 | |
| 126 | ## 3.5. Lerro anitzeko blokeak, `=`-ren arau unibertsala eta `mut` aldagaiak |
| 127 | |
| 128 | Funtzio bat lerro bakarrean sartzen ez denean, `=` ondoren lerro-jauzi bat egiten duzu eta blokeari koska ematen diozu. |
| 129 | |
| 130 | Begira nola irakurtzen den bloke bat urratsez urrats: |
| 131 | |
| 132 | ```ridgun |
| 133 | kalkulatu faktura Int Int => Int |
| 134 | kalkulatu faktura oinarria bez_eh = |
| 135 | zergak = oinarria * bez_eh / 100 |
| 136 | kudeaketa_gastuak = 5 |
| 137 | echo "Xehakapena -> Oinarria:" oinarria "Zergak:" zergak |
| 138 | oinarria + zergak + kudeaketa_gastuak |
| 139 | ``` |
| 140 | |
| 141 | Ridguneko blokeak garbiak eta uniformeak bihurtzen dituzten urrezko lau arau: |
| 142 | 1. **Aldaezina lehenespenez `let` eta `const` gabe**: `zergak = ...` idazten duzu eta baduzu zure konstante lokal aldaezina. Deskuiduz bloke berean beherago `zergak = 99` gainidazten saiatzen bazara, konpiladoreak lehorrean gelditzen zaitu. |
| 143 | 2. **Aldagai aldakor esplizituak `mut`-ekin**: funtzio baten barruan metatzaile lokal bat urratsez urrats eguneratzen joan nahi duzunean benetan, **`mut`**-ekin deklaratzen duzu eta gero askatasunez berresleitzen duzu `=`-rekin: |
| 144 | ```ridgun |
| 145 | aplikatu gainkarguak Int => Int |
| 146 | aplikatu gainkarguak prezioa = |
| 147 | mut guztira = prezioa |
| 148 | guztira = guztira + 10 |
| 149 | guztira = guztira * 2 |
| 150 | guztira |
| 151 | ``` |
| 152 | *(Eta `guztira`-k memorian zerrenda edo egitura bat gordetzen badu, Ridgunen **`RMM2`** politikak `+1` gehitzen dio balio berriari zaharrari `-1` kendu aurretik, eta berehala askatzen du beste inork erabiltzen ez badu).* |
| 153 | 3. **`=`-ren arau unibertsala**: **edozein `=`-ren** atzean (funtzio batean, eragile batean, `x =` aldagai lokal batean edo baldintzazko adar batean) Ridgunen hiru bloke-formetako edozein jar dezakezu beti: |
| 154 | - **`(ezer ez)`**: koska duten lerro sekuentzialak (goian bezala). |
| 155 | - **`|`**: baldintzazko zainen zuhaitz bat. |
| 156 | - **`||`**: kalkulu paraleloen grafo bat `->` geziekin. |
| 157 | 4. **Azken adierazpena da beti emaitza**: `oinarria + zergak + kudeaketa_gastuak` da `kalkulatu faktura`-k itzultzen duena. `return` gabe. |
| 158 | |
| 159 | **04. kapituluan** ikusiko dugu nola hartu erabaki konplexuak —`|.` bidezko maila anitzeko erabaki-zuhaitzak barne— inoiz `if/else` bat edo `while` begizta bat idatzi gabe: ongi etorri **zain boolearren** eta **zero kostuko isats-errekurtsioaren** mundura. |