Erreferentzia
Ridgun lengoaiaren espezifikazioa
Ikuspegi orokorra
Ridgun lengoaia funtzionala da, paralelismoa oinarrian duena, hizkuntza naturaleko eragileak eta tipatze estatiko sendoa dituena. Haren sintaxiak Haskell eta ML familiako lengoaietan du inspirazioa, eta paralelismorako eta gizakiek irakurtzeko moduko eragileak definitzeko eraikuntza berriak gehitzen ditu.
Ezaugarri nagusiak:
- Hizkuntza naturaleko eragileak — Eragileak ingelesezko esaldiak bezala irakurtzen dira
- Paralelismo inplizitua — Exekuzio paraleloa primitiba sintaktikoa da, ez liburutegi-dei bat
- Tipatze estatiko sendoa — Mota guztiak sinaduretan deklaratzen dira
- Ereduen bidezko definizioak — Funtzioak eta eragileak ekuazioen bidez definitzen dira
Iruzkinak
Lerro bakarreko iruzkinek -- erabiltzen dute:
-- This is a comment
Testu-kateak
Ridgunek bi kate-literal mota ditu, interpolazioaren aldetik portaera desberdinarekin.
Kate interpolatuak (komatxo bikoitzak)
Komatxo bikoitzeko kateek lerro barruko kode-interpolazioa onartzen dute {expr} erabiliz. Giltzen arteko adierazpena ebaluatu egiten da eta emaitza katean txertatzen da.
name = "Ridgun"
"Hello, {name}!" -- "Hello, Ridgun!"
"Sum is {sum 3 4}" -- "Sum is 7"
"Nested: {factorial 5} done" -- "Nested: 120 done"
"..." barruan giltza literal bat sartzeko, ihes egin alderantzizko barrarekin (\{ eta \}) edo bikoiztu ({{ eta }}):
"Shell expansion: \$\{VAR:-default\}" -- "Shell expansion: ${VAR:-default}"
"This is {{not interpolated}}" -- "This is {not interpolated}"
"Use \{ \} or {{}} for literal braces" -- "Use { } or {} for literal braces"
Kate gordinak (komatxo bakunak)
Komatxo bakuneko kateak gordinak dira: ez da interpolaziorik egiten. Karaktere guztiak testu literal gisa hartzen dira, giltzak barne.
'Hello, {name}!' -- "Hello, {name}!"
'{this is just pure chars}' -- "{this is just pure chars}"
'No {interpolation} here' -- "No {interpolation} here"
Laburpena
| Sintaxia | Interpolazioa | Erabilera |
|---|---|---|
"..." | Bai — {expr} (ihes egin giltzei \{/\} edo {{/}} erabiliz) | Adierazpenak txertatuta dituzten kate dinamikoak |
'...' | Ez — dena literala | Testu estatikoa, txantiloiak, regex ereduak |
Programaren egitura
Ridgunen kode exekutagarri guztiak funtzio edo eragile baten barruan egon behar du. main funtzioa da programa exekutatzeko derrigorrezko sarrera-puntua.
fn :: main => ()
main = echo "Hello, Ridgun!"
Ridgun iturburu-fitxategi batek hauek bakarrik izan ditzake:
importsententziaktypedefinizioakfnetaopdeklarazioak eta definizioakmainfuntzio bat sarrera-puntu gisa
Ez da onartzen goi-mailako adierazpen soltarik. Exekutatzen den guztiari main-etik deitu behar zaio.
CLI erabilera
ridgunc <command> [options] <file.rg>
| Komandoa | Zertarako |
|---|---|
run | Iturburu-fitxategi bat konpilatu eta exekutatzen du |
check | Motak egiaztatu eta aztertzen ditu, exekutatu gabe |
compile | .rgc bytecode-fitxategi bat sortzen du |
build | Exekutagarri natibo bat sortzen du; liburutegi bat --lib edo --so aukerarekin |
version | Konpiladorearen bertsioa erakusten du |
help | Laguntza erakusten du |
Formatua, probak eta proiektuak stable tresnaren ardura dira.
Funtzioak eta eragileak
Funtzioak eta hizkuntza naturaleko edo infix eragileak => <return_type>-rekin amaitzen den mota-sinadura batekin deklaratzen dira, eta atzetik ekuazio bat edo gehiago (cases) dituzte. Hasierako fn :: eta op :: aurrizkiak aukerakoak dira:
- Aurrizkirik gabeko forma kanonikoa (0 zutabean hasten da):
list len [A] => Int
list len [] = 0
list len (_:xs) = 1 + (list len xs)
swap A with B => (B, A)
swap x with y = (y, x)
- Aurrizki esplizitudun forma (
fn ::/op ::, 0 zutabean hasten da, klausulak 6 zutabean lerrokatuta):
fn :: sum Int Int => Int
sum a b = a + b
fn :: format app err AppErr => String
format app err (IoError msg) = "IO:{msg}"
- Hizkuntza naturaleko zuriuneak
fn ::-n, funtzio integratuetan eta fitxategi-izenetan (FR-COMP-005): fn ::deklarazioek eta deiek zuriunez bereizitako hitz anitzeko izenak onartzen dituzte (fn :: format app err AppErr => String,fn :: project name => String),op ::eta aurrizkirik gabeko deklarazioek bezala.- Runtime-ko eta testetako funtzio integratuei zuriuneekin dei dakieke (
assert equals a b,str len s,read file p,cmm live blocks), eta_formek ere bateragarriak izaten jarraitzen dute. ridgunc-ek etastable-k modu natiboan onartzen dituzte hitz anitzeko funtzio-erreferentzia lehen mailakoak (map double val xs,||map double val xs,filter is even xs,fold add pair 0 xs) eta zuriuneak dituzten.rgfitxategi-izenak (src/test/ridgun/test core language.rg).
Mota-aldagai polimorfikoak (A..Z) eta testuinguruko gako-hitzak (type, with)
Eragile-hitzen eta mota-parametroen artean anbiguotasun lexikorik ez dagoela bermatzeko, bai aurrizkidun sinaduretan (op ::) bai aurrizkirik gabekoetan:
- Sinadura bateko mota-token guztiak letra larriz hasten dira (edo
[...]/(...)-rekin): - Letra larri bakarrek (
A..Z) mota-aldagai polimorfikoak adierazten dituzte (adibidez,[A],(A, B),(A => B),swap A with B => (B, A)). Parametroetan errepikatzen den mota-aldagaia bateratu egiten da dei-gune bakoitzean, eta itzulera-motan ordezkatzen da. - Letra larriz hasitako karaktere anitzeko identifikatzaileek (
Int,String,Bool,RExpr,Tensor) mota zehatzak edo erabiltzaileak definitutakoak adierazten dituzte. - Goi-mailako sinadura bateko letra xehez idatzitako token guztiak (edo
+,-,*,/,%eragile-ikurrak) funtzioaren edo eragile mixfix-aren izenaren parte dira. typeetawithtestuinguruko gako-hitzak:type-k goi-mailan bakarrik sartzen du mota-deklarazio bat, eta atzetikUpperName =duenean soilik. Beste leku guztietan (fn ::etaop ::sinaduretan, eragile-hitzetan, parametro-ereduetan, aldagai lokaletan eta erregistro-eremuen izenetan),typeetawithbaliozko identifikatzaile edo hitzak dira, anbiguotasunik gabe.=>aurretik letra xehezko identifikatzaile bat hasieran eta motak bakarrik dituen goi-mailako sinadura aurrizki-funtzio bat da (fn);=>aurretik motekin tartekatuta bi letra xehezko hitz edo gehiago edo eragile-ikurrak dituen edozein sinadura eragile mixfix, infix edo postfix bat da (op).
Deklarazioa eta definizioa bereizita daude:
- Deklarazioa (
fn ::) — izena, parametro-motak eta itzulera-mota zehazten ditu - Definizioa — parametro-izenak lotzen ditu eta inplementazioa ematen du
Eragileak
Eragileak dira Ridgunen ezaugarri bereizgarria. Hizkuntza naturalaz izendatzen dira eta op ::-rekin definitzen dira. Ohiko eragileek (+, -) ez bezala, Ridgunen eragileak esaldiak bezala irakurtzen diren hitz anitzeko adierazpenak dira.
Sintaxia
op :: <natural language signature with types> -> <return_type>
<natural language pattern with params> = <body>
Oinarrizko adibidea
-- Declaration: "add [Int] to [Int]" returns an Int
op :: add Int to Int => Int
add a to b = a + b
Erabilera honela irakurriko litzateke: add 3 to 5 → 8
Parametro tipatuen arteko hitzak (to, and, in eta abar) eragilearen gako-hitzak dira: eragilearen identitatearen parte dira eta dei-guneetan agertu behar dute.
Eragile paraleloak (||)
Eragileek exekuzio paraleloa lehen mailako kontzeptu gisa adieraz dezakete || erabiliz:
-- Run two configs in parallel with named DAG bindings (|| expr -> var)
op :: run Conf and Conf in parallel => Res, Res
run a and b in parallel = res_a, res_b
|| run my own process a -> res_a
|| run my own process b -> res_b
Elementu nagusiak:
- Itzulera-balio anitz —
=> Res, Res-k bi itzulera-balio deklaratzen ditu || expr -> varblokea — Azpikalkuluak emaitza-izenei lotzen dizkie (wherekendu egin da;||-k adar paralelo guztiak bateratzen ditu)->— Azpikalkulu paralelo baten emaitza aldagai bati (edo tentsore-xerra bati,-> out[i, j]) esleitzen dio||adar independenteak aldi berean exekutatzen dira DAG paralelo gisa, datuen mendekotasunen arabera
Bloke paralelo zuzena (|| expr)
Adierazpen edo funtzio batek tarteko aldagai-izenik gabe kalkulu paraleloen tupla bat zuzenean itzultzen duenean, || lerroak = ondoren agertzen dira zuzenean:
-- Run two processes in parallel and return their results as a tuple
op :: another way to run two processes Conf Conf in parallel => Res, Res
another way to run two processes a b in parallel =
|| run my own process a
|| run my own process b
|| lerro bakoitza ataza paralelo independente gisa exekutatzen da. Emaitzak deklarazio-ordenan biltzen dira.
Eragileak gainkargatzea
Lehendik dauden eragileak (+ bezalako integratuak barne) mota berrietarako gainkarga daitezke:
-- Overload + for Complex numbers
op :: Complex + Complex => Complex
a + b = (real a) + (real b) + complex_i * ((imaginary a) + (imaginary b))
Lehentasuna
Eragile sinbolikoek dute lehentasunik handiena: matematika lehenik.
Eragile sinbolikoak (+, * bezalakoak) hizkuntza naturaleko eragileen gorputzetan agertzen direnean, inguruko eragile-gako-hitzek baino estuago lotzen dira. Horri esker, adierazpen aritmetikoak espero bezala ebaluatzen dira, parentesi gehigarririk gabe.
| Lehentasuna | Kategoria | Adibideak |
|---|---|---|
| Handiena | Eragile sinbolikoak | *, /, +, -, % |
| Funtzio-aplikazioa | f x | |
| Alderaketa | ==, !=, <, > | |
| Logikoak | and, or, xor, not | |
| Txikiena | Hizkuntza naturaleko eragileak | add a to b, run a and b in parallel |
Eragileak kateatzea eta ezkerretik eskuinerako hodi idiomatikoak (->) (FR-COMP-014)
Balioak edo sekuentziak eraldatzen dituzten eragileak eta funtzioak ezkerretik eskuinera katea daitezke, datuak iturritik helmugara modu naturalean joan daitezen, eskuinetik ezkerrerako parentesi habiaratuen (h (g (f x))) edo behin erabiltzeko tarteko aldagaien (st1, st2, st3) beharrik gabe.
1. Gomendatutako Ridgun hodi-estilo idiomatikoa (2b)
Ridgunek ezkerreko eragigaiaren infix deia eta -> hodi-urrats esplizituak AST berean bateratzen ditu. Beheko lau formak baliozkoak eta baliokideak diren arren, 2b forma da gomendatutako Ridgun estilo idiomatikoa: subjektu eta eragiketa batekin hasten da ezkerrean, ondorengo eraldaketak ->-rekin kateatzen ditu eta azken emaitza -> target-ekin lotzen du:
-- Recommended idiomatic style (2b):
xs map (x => x * 2) -> filter (x => x > 6) -> compact limit 14 -> results
-- Equivalent unified forms (all normalize to the exact same AST):
xs -> map (x => x * 2) -> filter (x => x > 6) -> compact limit 14 -> results -- (2) explicit -> from subject
xs map (x => x * 2) filter (x => x > 6) compact limit 14 -> results -- (1) contiguous infix chain
map (x => x * 2) xs -> filter (x => x > 6) -> compact limit 14 -> results -- (3) prefix start + -> chain
Urrats anitzeko hodiak ->-rekin hasten diren koskadun jarraipen-lerroetan ere idatz daitezke:
raw_nums map (x => x * 3)
-> filter (x => x >= 12)
-> fold 0 (acc x => acc + x)
-> total_sum
2. ->-ren lehen argumentuaren arau unibertsala eta bilduma-konbinatzaileak
- Funtzioen eta eragileen arau unibertsala:
->-ren ezkerretik datorren edozein balio (edox op a binfix dei baten ezkerretik datorrena) eskuineko funtzioaren edo eragilearen lehen argumentu gisa sartzen da: x -> f a b$\equiv$x f a b$\equiv$f x a b- Arazorik gabe funtzionatzen du bai
fn ::deklarazioekin baiop ::deklarazio mixfix-ekin, sinadurak bikoiztu gabe. - Ondorengo funtzio batek hodiko balioa lehena ez den parametro-posizio batean behar badu,
_leku-marka esplizitu batek_horretan jartzen du balioa (payload -> write_file output_path _). - Bilduma-konbinatzaileak (
map,||map,filter,||filter,fold): Bilduma onartzen dute bai ohiko aurrizki-posizioan (map f xs,filter g xs,fold f init xs) bai infix edo hodi-urrats baten ezkerretik (xs map f,xs -> map f,xs filter g,xs -> filter g,xs fold init f,xs -> fold init f). - Agente-urratsak (
-> send to,-> ask to):-> send to agedo-> ask to agurratsek ezkerreko balioa pasatzen dute mezu gisa ([5, 10, 15] -> sum int list -> send to worker_ag). - Amaierako aldagai-lotura (
-> var): Bloke sekuentzial bateko hodi-sententzia bat-> var-rekin amaitzen denean (varaldagai lokal baten izena denean eta ez deklaratutako funtzio batena),varlotzen du (var = <pipeline_result>) blokearen gainerakorako.
3. Sekuentzia-maskarak hodietan (-> (+ _ _ +) ->)
Urrats batek balio anitzeko sekuentzia edo tupla bat itzultzen duenean, sekuentzia-maskara urrats batek (-> (+ _ _ +) ->) haren elementuak iragazten ditu (+-k posizio bat mantentzen du, _-k baztertu egiten du) eta hautatutako tupla zuzenean despaketatzen du hurrengo argumentu anitzeko funtziorako:
parse header packet "v0.9.9" -> (+ _ _ +) -> combine code msg -> status_line
4. _ = gabeko albo-ondorioko sententziak eta Unit balioaren baztertze esplizitua (-> ())
Bloke sekuentzialetan, albo-ondorioko sententziak (echo, write_file, write_bytes, shell_exec, log info, print_error_lines, sys_mkdir eta abar) zuzenean idazten dira, _ = errepikapenik gabe:
verify strict if enabled strict_mode input_path
s_errs -> format_type_errors -> print_error_lines
echo "[ridgunc --strict] {input_path}: {err_c} error(s) found."
sys_exit 1
=> () funtzio baten azken adierazpenak () ez den balio bat itzultzen duen laguntzaile bati deitzen dionean (adibidez, shell_exec : String => Int), gehitu -> () adierazpena ebaluatzeko, haren itzulera-balioa baztertzeko eta () emateko:
fn :: exec built run Int => ()
exec built run 0 = shell_exec "./target/app" -> ()
exec built run _ = sys_exit 1
5. Sekuentzia-eragileak point-free erara kateatzea
Sekuentziak itzultzen dituzten eragileak ere point-free erara katea daitezke:
op :: Int Int switch -> Int Int
a b switch = b a
op :: Int Int invariant -> Int Int
a b invariant = a b switch switch
Oharra:
->eta=>biak onartzen dira itzulera-motaren bereizle gisafn ::/op ::goiburuetan. Adierazpenetan,->ezkerretik eskuinerako hodi- eta lotura-eragilea da, eta=>-k itxitura lexikoak sartzen ditu:(x => expr).
Mota-sistema
Mota-sinadurak
Mota-sinadurak deklarazioetan agertzen dira, fn :: edo op :: ondoren (edo aurrizkirik gabe):
fn :: <name> <type1> <type2> ... => <return_type1> <return_type2> ...
op :: <words and types mixed> => <return_type1> <return_type2> ...
- Parametroak posizionalak dira; motak parametroak espero diren lekuan agertzen dira.
- Tuplen eta sekuentzien mota-sintaxi bateratua (
FR-COMP-008): - Ridgunen,
T1 T2 ... Tnargumentu-zerrenda batek eta(T1, T2, ..., Tn)tupla batek azpiko mota konposatu bera adierazten dute: tipatutako balioen sekuentzia ordenatu eta tamaina finkoko bat (seq). - Horregatik, zuriunez bereizitako motak eta komaz bereizitako tupla-motak % 100 trukagarriak dira itzulera-motetan, zerrenda-kortxeteetan eta parentesi arteko tupletan:
- Itzulera-motak
=>/->ondoren:
fn :: parse header String => Int Int [String String] String
-- 100% equivalent to:
fn :: parse header String => (Int, Int, [(String, String)], String)
- Tuplen zerrendak (
[T1 T2 ... Tn]):
[String String] -- equivalent to [(String, String)]
[Int String Bool] -- equivalent to [(Int, String, Bool)]
- Parentesi arteko tuplak (
(T1 T2 ... Tn)):
fn :: fst (A B) => A
fst (a, _) = a
- Zergatik ez duen honek anbiguotasun sintaktikorik: Haskell/ML-n ez bezala (non
Maybe Intelkarren ondoan jartzeak mota-aplikazioa adierazten duen), Ridgunen mota parametrizatuek parentesi esplizituak erabiltzen dituzte (Tensor(Float, 3, 3)) eta zerrendek kortxeteak ([T]). Gainera, mota-token guztiak letra larriz (A..Z,Int,String),[-rekin edo(-rekin hasten dira, eta funtzio- eta eragile-hitzak letra xehez idazten dira. Beraz,T1 T2ez dator inoiz talkan mota-eraikitzaileekin edo eragile-gako-hitzekin. =>(edo->) geziak sarrera-motak eta itzulera-mota bereizten ditu.
Mota integratuak
| Mota | Deskribapena |
|---|---|
Int | Osokoa |
Real | Zenbaki erreala |
Bool | Boolearra |
Char | Unicode karaktere bakarra (UTF-8) |
String | Testu-katea (UTF-8) |
Complex | Zenbaki konplexua |
Tensor | N dimentsioko tentsore aldakorra (Real elementuak, PUZ) |
Tensor_GPU | N dimentsioko tentsore aldakorra (Real elementuak, GPU) |
[!NOTE] Ridgunen testu guztia UTF-8 kodeketan dago lehenespenez.
Char-ek Unicode kode-puntu bakarra adierazten du, etaStringChar-en sekuentzia bat da.
Bool literalak
Bool-ek bi balio primitibo ditu:
True -- boolean true
False -- boolean false
True eta False eraikitzaileak dira: adierazpenetan erabil daitezke, argumentu gisa pasa daitezke eta ereduekin parekatu daitezke:
fn :: is_valid Int => Bool
is_valid n =
| n > 0 = True
| otherwise = False
Eragile logikoak
Ridgunek letra xehezko hitzez osatutako eragile logikoak erabiltzen ditu, ikurren ordez:
| Eragilea | Esanahia | Adibidea |
|---|---|---|
and | Konjuntzio logikoa | a and b |
or | Disjuntzio logikoa | a or b |
xor | Disjuntzio esklusiboa | a xor b |
not | Ukapen logikoa | not a |
result = True and False -- False
result = True or False -- True
result = True xor True -- False
result = not False -- True
Hauek gako-hitzezko infix eragileak dira, semantika boolear estandarrarekin.
Bilduma-mota natiboak
Zerrendak
Zerrendak mota errekurtsibo integratu eta aldaezinak dira, sintaxi propioarekin. Ez dago eskuzko ADT definiziorik egin beharrik. Zerrendak egokiak dira datuen prozesamendu funtzionalerako, kalkulu sinbolikorako eta algoritmo errekurtsiboetarako. Zenbakizko kalkulu aldakorrerako, ikus Tentsoreak behean.
Mota-sintaxia: [type] — emandako motako elementuen zerrenda bat.
fn :: sum_list [Int] => Int
fn :: reverse [Int] => [Int]
Literal-sintaxia: [elem1, elem2, ...] — zerrenda-literal bat. [] zerrenda hutsa da.
fn :: my_list => [Int]
my_list = [1, 2, 3, 4, 5]
Cons ereduen bat-etortzea: (x:xs) — zerrenda bat x burutan eta xs isatsean deskonposatzen du. [] zerrenda hutsarekin bat dator. Erabili _ komodin gisa: bat dator baina ez du ezer lotzen.
fn :: sum_list [Int] => Int
sum_list [] = 0
sum_list (x:xs) = x + sum_list xs
fn :: list_length [Int] => Int
list_length [] = 0
list_length (_:xs) = 1 + list_length xs
Kateaketa: ::-k bi zerrenda (edo sekuentzia) elkartzen ditu.
fn :: append [Int] [Int] => [Int]
append a b = a :: b
Tentsoreak
Tentsoreak Ridgunen N dimentsioko zenbakizko mota natibo eta aldakorra dira. Bektoreak, matrizeak eta dimentsio handiagoko matrizeak mota bakarrean orokortzen dituzte. Elementuak Real dira lehenespenez.
Literal-sintaxia: Tensor eta atzetik kortxete habiaratuak. Habiaratze-sakonerak dimentsio-kopurua zehazten du.
v = Tensor [1, 2, 3] -- 1D (vector), shape: (3)
m = Tensor [[1, 2], [5, 3]] -- 2D (matrix), shape: (2, 2)
t = Tensor [[[1, 2], [3, 4]], -- 3D tensor, shape: (2, 2, 2)
[[5, 6], [7, 8]]]
Indexatzea: Bai indexatze kateatua bai komaz bereizitakoa onartzen dira.
val = m[0][1] -- chained indexing: row 0, col 1
val = m[0, 1] -- comma indexing: equivalent
row = m[0] -- slice: entire first row
Aldaketa (lekuan bertan): Tentsoreak aldakorrak dira: elementuak eta xerrak lekuan bertan alda daitezke (PyTorch/NumPy eran).
m[0, 1] = 5.0 -- set element
m[0] = Tensor [10, 20] -- set entire row
Tentsore-uzkurdura (@): @ eragileak Einsteinen batuketa egiten du. Eragigai bakoitzeko azpiindizeek uzkurdura definitzen dute: eragigai guztiek partekatzen dituzten indizeak batu egiten dira, eta indize bakarrek emaitzan irauten dute.
-- A has shape (s, d, f), B has shape (n, d, f)
-- Shared indices: d, f → contracted (summed)
-- Result T has shape (s, n)
T = A_sdf @ B_ndf
-- Equivalent to: np.einsum('sdf,ndf->sn', A, B)
Uzkurdurak adierazpen bakarrean hainbat tentsorerekin funtzionatzen du:
-- A(a,b,c), B(a,b,c), C(a,b,c,d)
-- Shared: a, b, c → contracted. Result R has shape (d)
R = A_abc @ B_abc @ C_abcd
-- Equivalent to: np.einsum('abc,abc,abcd->d', A, B, C)
Hadamard eragiketak (+, -, *, /): Azpiindizeak dituzten eragile aritmetikoek elementuz elementuko eragiketak egiten dituzte. Bat datozen indizeek dimentsioak lerrokatzen dituzte, eta bat ez datozenei broadcasting aplikatzen zaie.
-- Element-wise multiply: same shape, same indices
H = A_ij * B_ij -- shape (i, j)
-- Broadcasting: B has fewer dimensions
S = A_ij * B_j -- B broadcasts along i
-- Element-wise add
C = A_ij + B_ij
-- Element-wise divide
D = A_ij / B_j -- B broadcasts along i
Horrek unsqueeze, expand_dims edo eskuzko birmoldaketen beharra kentzen du: indizeak dira broadcasting arauak.
GPU aldaera: Tensor_GPU-k tentsorea GPUaren memorian jartzen du kalkulua azkartzeko.
g = Tensor_GPU [[1, 2], [3, 4]]
result = g_ij @ g_jk -- GPU-accelerated matrix multiply
Sekuentziak (seq)
Sekuentziak Ridgunen oinarrizko mota konposatua dira. seq bat balioen bilduma ordenatu eta tamaina finkokoa da: funtsean, tupla tipatu bat. Funtzioen eta eragileen parametro-zerrendak inplizituki sekuentziak dira.
-- These parameter types form implicit sequences:
fn :: sum Int Int => Int -- params: seq(Int, Int)
fn :: process Int Real => Bool -- params: seq(Int, Real)
Seq lotura ((name)) — parametro-izen bat parentesi artean jartzeak parametro guztiak seq aldagai bakarrean lotzen ditu:
fn :: first_of_seq Int Int => Int
first_of_seq (s) = s(+ _)
-- Equivalent without seq binding:
fn :: first_of Int Int => Int
first_of s _ => s
Maskara-hautatzailea (s(+ _)) — elementuak maskara baten bidez ateratzen ditu: +-k posizio bat hautatzen du eta _-k saltatu egiten du:
s(+ _) -- select 1st, skip 2nd
s(_ +) -- skip 1st, select 2nd
s(+ _ _ _) -- select 1st, skip 2nd-4th
s(_ _ _ +) -- skip 1st-3rd, select 4th
Indize-hautatzailea (s(0 3)) — elementuak zerotik hasitako posizioen bidez ateratzen ditu:
fn :: extreme_points Int Int Int Int => Int Int
extreme_points (s) = s(0 3)
Elkartze laua (:) — bi sekuentzia sekuentzia lau bakarrean kateatzen ditu:
seq1 = a, b -- seq(a, b)
seq2 = c, d -- seq(c, d)
seq1:seq2 -- seq(a, b, c, d)
Habiaratzea (,) — sekuentziak elementu bereizi gisa konposatzen ditu (sekuentzien sekuentzia):
seq1, seq2 -- seq(seq(a, b), seq(c, d))
Datu-mota aljebraikoak (ADTak)
Ridgunek datu-mota aljebraikoak erabiltzen ditu erabiltzaileak definitutako motetarako. Ez dago klaserik, metodorik edo impl blokerik: funtzioek eta eragileek motak hartzen dituzte parametro gisa.
Biderkadura-motak (erregistroak) eta erregistroak eguneratzeko sintaxia (with)
Eremu izendunak dituen mota:
type Conf = host: String, port: Int, tls: Bool
type Point = x: Real, y: Real
Eremuak izenez atzitzen dira, funtzioak balira bezala (host c, port c), eta modu funtzionalean eguneratzen dira with eta bi puntuak : erabiliz:
fn :: get_host Conf => String
get_host c = host c
-- Functional record update (creates a new Conf with updated fields;
-- mutates in place via Arc::try_unwrap when the record is uniquely owned):
fn :: enable_tls Conf => Conf
enable_tls c = c with tls = True, port = 443
Batura-motak (aldaerak)
| bidez bereizitako eraikitzaile anitz dituen mota:
type Result = Ok Int | Err String
type Option = Some Int | None
type Color = Red | Green | Blue
Batura-ADT generikoak eta biderkadura-erregistro generikoak (FR-COMP-013)
Erabiltzaileak definitutako batura-ADTek eta biderkadura-erregistroek letra larrizko mota-parametro bat edo gehiago deklara ditzakete (A..Z edo letra larriz hasitako mota-aldagaien izenak) motaren izenaren eta =-ren artean:
type Result T E = Ok T | Err E
type Option A = Some A | None
type Box A = Box A
type Page T = items: [T], total: Int
type Pair A B = fst: A, snd: B
- Mota parametrikoen aplikazioak (
Result Int String,Page User,[Box Int])fn ::/op ::sinaduretan, erregistro-eremu habiaratuetan eta ADT eraikitzaileen edukietan erabil daitezke. - Eraikitzaileek (
Ok 42,Ok "hello",Page [1, 2] 2), eredu bat-etortzeak, eremu-atzitzaileek (items p,total p) eta erregistroen eguneratze funtzionalek (p with total = 10) mota-aldagai berriak instantziatzen dituzte dei-gune bakoitzean. type Option A = Some A | NoneADT polimorfiko integratu gisa erregistratzen da aurrez, erabiltzaileak dagoeneko deklaratu ez badu; beraz,try receive from ag-kSome vedoNoneitzultzen du, deklarazio gehigarririk behar izan gabe (FR-COMP-013).
Funtzio anonimoak eta itxitura lexikoak ((x => expr), (a b => expr) — FR-COMP-013)
Funtzio anonimoak (lambdak) parentesi artean idazten dira, zuriunez bereizitako parametroekin eta atzetik => eta gorputzaren adierazpena jarrita ((x => expr) edo (a b => expr), adibidez map (x => x + offset) xs, fold (acc x => acc + x) 0 xs), eta aldagai lokalak edo parametroak harrapa ditzakete inguruko esparru lexikotik:
fn :: add offset Int [Int] => [Int]
add offset k xs = map (x => x + k) xs
Bost arau kanonikok gobernatzen dituzte funtzio anonimoak:
- Derrigorrezko parentesiak: Lambda orok parentesi artean egon behar du:
(... => ...). Parentesirik gabekox => expr(adibidezf = x => x + 1) konpilazio-errorea da (lambda expression must be enclosed in parentheses: '(x => expr)'). - Parametrorik gabeko lambdak (
(=> expr)): Ridgunek debekatu egiten du()jartzea=>aurretik funtzio-sinaduretan (fn :: main => ()). Horrekin bat etorriz, parametrorik gabeko lambda(=> expr)idazten da (thunk ()gisa deitzen zaio), eta sinaduretan bere mota(=> Type)da.(() => expr)edo(() => Type)idaztea konpilazio-errorea da. - Parametro anitz tuplen deskonposizioaren aldean (
(a b => expr)eta((a b) => expr)):(a b => expr)2 parametroko lambda bat da (adibidezfold (acc x => acc + x) 0 xs), eta((a b) => expr), berriz, tupla bat deskonposatzen duen parametro bakarreko lambda bat (map ((a b) => a + b) [(1, 2), (3, 4)]). Biak nahasteak aldea azaltzen duen mota-errore berezi bat sortzen du. - Lerro anitzeko lambda-gorputzak:
=>lerroaren amaieran dagoenean, azpiko koskadun blokeak sententzia anitzeko gorputza (edo|zain-gorputza) osatzen du, eta)-k ixten du:
map (x =>
doubled = x * 2
doubled + offset
) [1, 2, 3]
- Letra larrizko motak eta letra xehezko balioak:
(Conn => Conn)funtzio-mota bat da eta(conn => conn)lambda-balio bat. Letra larrizko motak ((Conn => Conn)) adierazpen batean edo letra xehezko parametroak ((conn => conn))fn ::sinadura batean idaztea konpilazio-errore argi batekin baztertzen da.
Harrapatutako loturak automatikoki aplikazio partzialeko itxitura bihurtzen dira, eta RMM1/RMM2-k kudeatzen ditu.
Mota errekurtsiboak
Motek beren buruari erreferentzia egin diezaiokete:
type List = Empty | Cons Int List
type Tree = Leaf Int | Node Tree Tree
Motek partekatutako eraikitzaile-izenak (FR-COMP-005)
type deklarazio anitzek aldaera-eraikitzaileen izen berak (Error, Var, Lit, None eta abar) berrerabil ditzakete, aritate berdin edo desberdinekin. Mota-egiaztatzaileak eraikitzaile-ereduak zutabeak espero duen parametro-motaren bidez bereizten ditu, eta eraikitzaile-deiak argumentuen aritate eta moten eta ADT bildura itzulera-moten bidez ebazten ditu:
type ParseOut = Parsed Int | Error String
type DbOut = Rows Int | Error Int String
type MiniExpr = Var String | Lit Int
type MiniPat = Var String | Lit Int | Wild
Mota irekien hedapenak (expand type) eta fn :: klausulen bateratze automatikoa (FR-COMP-005)
Lehendik dauden batura-ADTak eta biderkadura-erregistroak expand type UpperName = ...-rekin heda daitezke:
- Batura-ADT bat hedatzea: aldaera-eraikitzaile berriak gehitzen dizkio lehendik dagoen motari.
- Biderkadura-erregistro bat hedatzea: eremu izendun berriak (
field: Type) gehitzen ditu eta haien eremu-atzitzaile funtzioak automatikoki sortzen ditu. - Mota-izeneko aldaerak, eraikitzaile-izen erredundanterik gabe:
typeetaexpand typebatura-deklarazioetan, izena mota integratu soil bat (String,Int,Real/Float,Bool,Char) duen eta atzetik mota-argumentu gehigarririk ez duen aldaera batek mota horretako balioak zuzenean adierazten ditu (Int IntedoString Stringidatzi gabe). Deitzaileek balio soilak (describe "hej",describe 42) edo eraikitzaile-dei esplizituak (describe (String "hej"),describe (Int 42)) pasa ditzakete, eta ekuazioak bai literalekin ("admin",0) bai eredu tipatuekin ((String s),(Int n)) parekatu daitezke. fn ::/op ::klausulen bateratze automatikoa (expand fngabe): lehendik dagoenfn ::edoop ::bat eredu-klausula berriekin berriro deklaratzean, klausula horiek automatikoki bateratzen dira lehendik dagoen funtzio-definizioan, eta eraikitzaile edo literal zehatzen eredu-klausulak dena harrapatzen duen edozein ordezko klausularen (_/ aldagaia) aurretik jartzen dira:
type Something = String | Int | MyStruct Float Int
expand type Something = Bool
fn :: describe something Something => String
describe something "admin" = "special_admin"
describe something 0 = "zero_int"
describe something (String s) = "str:{s}"
describe something (Int n) = "int:{n}"
describe something (Bool b) = "bool:{b}"
describe something (MyStruct ratio cnt) = "struct:{ratio}:{cnt}"
type AppErr = IoError String | Timeout Int
fn :: format app err AppErr => String
format app err (IoError msg) = "IO:{msg}"
format app err (Timeout ms) = "TO:{ms}"
format app err _ = "UNKNOWN"
expand type AppErr = AuthError String | DbError Int String
fn :: format app err AppErr => String
format app err (AuthError user) = "AUTH:{user}"
format app err (DbError code db) = "DB:{code}:{db}"
type AppConfig = host: String, port: Int
expand type AppConfig = tls: Bool
Moduluen izen-espazioak, sarbide kualifikatua eta modulukako inportazio-ikusgarritasun zorrotza (FR-COMP-012)
.rg fitxategi edo .rglib sorta bakoitzak moduluaren izen-espazio bat definitzen du (fitxategi-izenaren oinarritik edo module :: <name> goiburu esplizitu batetik ateratzen da), eta beste modulu batzuk inporta ditzake import <mod> edo import <mod> as <alias> erabiliz.
- Fitxategi anitzeko moduluak (
module :: <name>):
module :: <name>goiburu bera deklaratzen duten fitxategi anitzek (adibidez,orm.rgetaorm_changeset.rg, biakmodule :: orm-ekin hasita)ormizen-espazio logiko bakarra partekatzen dute, eta elkarren motak, eraikitzaileak, erregistro-eremuak eta funtzioak zuzenean ikusten dituzte.
- Sarbide kualifikatua (
mod.Type,mod.Constructor,mod.field,mod.fn):
- Esportatutako motei, batura-ADTen eraikitzaileei, biderkadura-erregistroen eremu-atzitzaileei, erregistro-eguneratzeei (
with) eta funtzioei<mod_or_alias>.aurrizkiarekin egin dakieke erreferentzia (http.Config,db.Status,http.Ok 200,http.port cfg,http.check status cfg).
- Modulukako izen kualifikatugabeen 3 mailako ebazpen zorrotza:
Mmodulu bakoitzak (erroko aplikazio-modulua barne) kualifikatu gabeko motak, eraikitzaileak, erregistro-eremuak, funtzioak eta hitz anitzeko deiakM-ren inportazio-grafoaren arabera bakarrik ebazten ditu, hiru lehentasun-mailatan:- 1. maila — Modulua bera (
M):M-ren beraren deklarazioek (module :: Mpartekatzen duten fitxategi guztietan) dute beti lehentasunik handiena. - 2. maila —
M-ren inportazio zuzenak:M-k izena definitzen ez badu,ridgunc-ekM-k zuzenean inportatutako moduluetan bilatzen du (import D). Inportazio zuzen bakar batek (D) definitzen badu izena,D-ren deklaraziora ebazten da, anbiguotasunik gabe, konpilazio-unitateko beste modulu batzuek (mendekotasun iragankorrek, ondoko moduluek edo erroko aplikazioak) izen bera definitzen badute ere.M-ren bi inportazio zuzenek edo gehiagok izen bera definitzen badute etaM-k definitzen ez badu, kualifikatu gabeko erreferentziak anbiguo gisa baztertzen dira (__ambiguous__.<name>) eta kualifikatu egin behar dira (d1.<name>edod2.<name>). - 3. maila —
M-ren inportazio iragankorrak: 1. eta 2. mailek izena definitzen ez dutenean bakarrik kontsultatzen dira. Ondorioz,M-ko inportazio zuzen batek (import json) garbi estaltzen du laguntzaile iragankor bat (solstice-k barnean inportatutakocodec.json_get_str),solsticeedoMdeiak berrizendatzera edo kualifikatzera behartu gabe. - Inportatu gabeko ondoko moduluekiko eta erroko aplikazioarekiko isolamendua:
M-k inportatu ez dituen moduluetan (ez zuzenean, ez iragankorki) bakarrik definitutako deklarazioak ikusezinak diraMbarruko kualifikatu gabeko bilaketarentzat (__unimported__.<name>). Horien artean daude erroko aplikazioak inportatutako ondoko liburutegiak eta,Mliburutegi inportatua konpilatzean, erroko aplikazioaren beraren deklarazioak.
= gramatika bateratua ((none), |, ||) eta aldagai lokalak (FR-COMP-003)
Ridgunen definizio edo lotura orok —dela funtzio-klausula bat (fn ::), eragile-klausula bat (op ::), aldagai lokal aldaezin bat (x =), aldagai lokal aldakor bat (mut x =) edo zain-adar bat (| cond = / | otherwise =)— =-rekin amaitzen da eta eskuinaldean lau bloke- edo adierazpen-forma berberak onartzen ditu:
= ondorengo aurrizkia | Exekuzio-semantika | Esanahia |
|---|---|---|
Lerroko <expr> | Adierazpen bakarra (azpian || expr -> var lerro aukerakoekin) | <expr> zuzenean ebaluatzen du (azpiko || DAG lotura paraleloak ebatzita). |
(none) (lerro koskadunak) | Sekuentziala (goitik behera) | Sententziak ordenan ebaluatzen ditu (mut, esleipenak, albo-ondorioak); azken adierazpena da emaitza. |
| <cond> = ... | Baldintzazkoa (zainak eta erabaki-zuhaitz habiaratuak) | Baldintza boolearrak goitik behera ebaluatzen ditu, lehen True adarrera (edo | otherwise =-ra) iritsi arte. |
|| <expr> | Paraleloa (green-thread DAG / tupla) | || adarrak aldi berean ebaluatzen ditu (|| expr -> var DAG nodo izendunetarako, || expr tupla-emaitza paraleloetarako). |
1. Zainak (|) beti =-ren atzetik doaz (funtzioak, eragileak, aldagai lokalak eta erabaki-zuhaitz habiaratuak)
Zain-blokeak (| cond = ... eta | otherwise = ...) beti = baten atzetik agertzen dira, eta horrela funtzio-klausulak, eragile-klausulak, aldagai lokalen definizioak eta baldintzazko zuhaitz habiaratuak bateratzen dituzte:
Zainak dituzten funtzio- eta eragile-klausulak
fn :: abs Int => Int
abs n =
| n < 0 = 0 - n
| otherwise = n
op :: clamp Int between Int and Int => Int
clamp x between lo and hi =
| x < lo = lo
| x > hi = hi
| otherwise = x
Aldagai lokalen esleipena zainekin
| edozein =-ren ondoren baliozkoa denez, aldagai lokalak baldintzapean lot daitezke, if/else gako-hitzik edo funtzio laguntzailerik behar izan gabe:
discount =
| is_vip = 20
| total > 100 = 10
| otherwise = 0
Lerro anitzeko bloke sekuentzialak, erabaki-zuhaitz sakonak eta ixtaile habiaratuak (|. / ||.)
Zain-adar bakoitza =-rekin amaitzen da; beraz, haren gorputza bloke sekuentzial bat ((none)), bloke paralelo bat (||) edo beste | zain-bloke habiaratu bat izan daiteke. Horri esker, nahi adina erabaki-zuhaitz (3-4 maila edo gehiago) idatz daitezke | cond = eta | otherwise = barruan.
- Maila habiaratuak ixtea (
|.eta||.): - Maila bakarreko bloke sinpleetan edo funtzio edo zuhaitz baten amaieran, ez da ixteko tokenik behar.
|(edo||) azpibloke habiaratu bat amaitzen denean eta exekuzioa kanpoko maila batera itzultzen denean, non azpian adar edo sententzia gehiago dauden,|.-k (|-rako) edo||.-k (||-rako) maila habiaratu hori esplizituki ixten dute.- Baliozkoak dira bai azken lerroaren amaieran jartzea (
| otherwise = val |., estilo trinko kanonikoa) bai hurrengo lerroan jartzea (|.):
fn :: evaluate_payment Account Customer Payment => String
evaluate_payment account customer payment =
| is_locked account = "REJECTED_ACCOUNT_LOCKED"
| amount payment <= 0 = "ERROR_INVALID_AMOUNT"
| otherwise =
| tier customer == "ENTERPRISE" =
| amount payment > 50000 =
| has_dual_signature payment = "APPROVED_ENTERPRISE_DUAL_SIG"
| tenure customer > 10 = "RISK_COMMITTEE_REVIEW"
| otherwise = "REJECTED_ENTERPRISE_LIMIT" |.
| country payment != "US" =
| is_whitelisted (country payment) = "APPROVED_ENTERPRISE_INTL"
| otherwise = "HELD_COMPLIANCE_INTL" |.
| otherwise = "APPROVED_ENTERPRISE_STANDARD" |.
| tier customer == "VIP" =
| amount payment > 10000 =
| has_2fa payment = "APPROVED_VIP_2FA"
| otherwise = "REQUEST_VIP_SMS" |.
| otherwise = "APPROVED_VIP_DIRECT" |.
| otherwise =
| amount payment > 1000 =
| has_2fa payment and risk payment < 30 = "APPROVED_RETAIL_2FA"
| otherwise = "REJECTED_RETAIL_RISK" |.
| otherwise = "APPROVED_RETAIL_LOW_AMOUNT"
fn :: charge_order Payment => Int
charge_order payment =
|| fetch_base_fee payment -> base_fee
|| compute_risk_score payment -> risk_score ||.
surcharge =
| risk_score > 80 = 50
| otherwise = 0 |.
base_fee + surcharge
2. Aldaezinak lehenespenez (x = ...) eta aldagai aldakor esplizituak (mut x = ...)
Bloke sekuentzialen barruan, aldagai lokalek 1. aukera jarraitzen dute:
- Lotura aldaezina (
x = <rhs>): xaldagai lokal aldaezin berri bat deklaratzen du.- Esparru berean geroago
x = ...berriro esleitzen saiatzea, aurretikmut x = ...deklaratu gabe, konpilazio-errorea da. - Deklarazio aldakorra (
mut x = <rhs>) eta berresleipena (x = <new_rhs>): mut x = <rhs>-kxaldakor gisa deklaratzen du uneko esparruan eta hasieratu egiten du.- Esparru bereko ondorengo
xberresleipenakx = <new_rhs>idazten dira, besterik gabe (muterrepikatu gabe). RMM2-n,x = <new_rhs>berresleitzean egitura berria handitzen da (+1) egitura zaharra txikitu aurretik (-1, kaskadan bere seme-alabetara hedatuz kontagailua0-ra iristen bada).
fn :: accumulate Int => Int
accumulate n =
factor = 2
mut acc = n * factor
acc = acc + 10
acc =
| acc > 100 = 100
| otherwise = acc
acc
3. Literalen eta ADT eraikitzaileen eredu bat-etortzea
fn :: factorial Int => Int
factorial 0 = 1
factorial n = n * factorial (n - 1)
fn :: unwrap Result => Int
unwrap (Ok n) = n
unwrap (Err msg) = 0
fn :: length List => Int
length Empty = 0
length (Cons _ rest) = 1 + length rest
fn :: sum_tree Tree => Int
sum_tree (Leaf n) = n
sum_tree (Node left right) = sum_tree left + sum_tree right
Paralelismo-primitibak (||)
Ridgunek exekuzio paralelo guztia ||-ren pean bateratzen du (where kendu egin da):
DAG lotura paralelo izendunak (|| expr -> var)
fn :: compute_total Int Int => Int
compute_total a b = x + y + z
|| heavy_calc a -> x
|| heavy_calc b -> y
|| combine x y -> z
- Adierazpen baten azpiko
|| expr -> varlerro guztiek Grafo Zuzendu Azikliko (DAG) paralelo bat osatzen dute. - Konpiladoreak
||lerroen arteko aldagai-mendekotasunak aztertzen ditu (x-k etay-k ez dute mendekotasunik eta paraleloan exekutatzen dira 1. olatuan;zx-ren etay-ren menpe dago eta 2. olatuan exekutatzen da,x + y + zebaluatu aurretik). - Tentsore-xerren idazketa paraleloak ere onartzen dira (
|| expr -> out[i, j]).
Bloke paralelo zuzenak (|| expr)
op :: run Conf and Conf in parallel => Res, Res
run a and b in parallel =
|| run_process a
|| run_process b
|| lerro bakoitza green thread paralelo bereizi gisa exekutatzen da, eta emaitzak tupla gisa itzultzen dira deklarazio-ordenan (edo elkartu egiten dira bloke sekuentzial baten barruan jartzen direnean).
Kanal tipatuak
Green thread-en arteko datu-korronteetarako eta ekoizle-kontsumitzaile topologietarako, Ridgunek MPMC kanal tipatuak (Channel) eskaintzen ditu:
| Funtzio edo eragile integratua | Sinadura | Helburua |
|---|---|---|
new_channel | () => Channel | Kanal tipatu mugagabe bat sortzen du |
new_bounded_channel | Int => Channel | Kanal mugatu bat sortzen du, backpressure edukierarekin |
send_through | T Channel => () | Balio bat kanalera bidaltzen du (blokeatu egiten da mugatua eta beteta badago) |
receive_from | Channel => T | Kanaleko hurrengo balioa jasotzen du |
try_receive_from | Channel => Option | Kontsulta blokeatu gabea, Some v edo None itzultzen duena |
S/I primitibak
Ridgunek funtzio integratuak eskaintzen ditu terminaleko irteerarako.
echo
Nahi adina kate inprimatzen ditu terminalean, zuriunez bereizita, eta atzetik lerro-jauzia.
fn :: echo String... => ()
Azken parametro-motaren ... atzizkiak bariadiko gisa markatzen du: mota horretako argumentu bat edo gehiago onartzen ditu.
echo "hello" -- prints: hello
echo "hello" "world" "!" -- prints: hello world !
echo "result: {result}" -- prints: result: 42
out
Kate bat terminalean zuzenean idazten duen eta itzultzen duen eragilea (kateatzea ahalbidetzen du).
op :: String out => String
"hello" out -- prints: hello
"step 1 done" out -- prints: step 1 done
-- Chaining: out returns the string, so it can be passed onward
fn :: log_and_process String => String
log_and_process s = process (s out) and report
Laburpena
| Funtzioa | Mota | Helburua |
|---|---|---|
echo | String... => () | Kateak inprimatzen ditu zuriuneekin eta lerro-jauziarekin |
out | String => String | Katea inprimatzen du eta itzuli egiten du kateatzeko |
Liburutegi estandarra
Liburutegiak import-ekin inportatzen dira:
import test
Unitate-testak (lib/test.rg)
Terminaleko irteerarako echo erabiltzen duen test-liburutegi sinple bat.
Baieztapenak:
| Eragilea | Helburua |
|---|---|
assert Int equals Int | Osokoen berdintasuna |
assert Real equals Real | Errealen berdintasuna |
assert String equals String | Kateen berdintasuna |
assert Bool is true | Boolearra egiazkoa da |
assert Bool is false | Boolearra faltsua da |
Testen egitura:
import test
fn :: main => ()
main =
describe "Arithmetic" does
test "sum adds correctly" does
assert (sum 3 4) equals 7
test "factorial base case" does
assert (factorial 0) equals 1
Terminaleko irteera:
═══ Arithmetic ═══
● sum adds correctly
✓ PASS
● factorial base case
✓ PASS
Elementu sintaktikoen laburpena
| Elementua | Sintaxia | Helburua |
|---|---|---|
| Iruzkina | -- text | Lerro bakarreko iruzkina |
| Funtzio-deklarazioa | fn :: name types => return | Funtzio baten mota-sinadura deklaratzen du |
| Funtzio-definizioa | name params = body | Funtzio baten inplementazioa definitzen du |
| Eragile-deklarazioa | op :: words types words => return | Hizkuntza naturaleko eragile bat deklaratzen du |
| Eragile-definizioa | words params words = body | Eragile baten inplementazioa definitzen du |
| Itzulera anitz | => type, type | Itzulera-balio anitz deklaratzen ditu |
| Parametro bariadikoak | Type... | Mota bateko argumentu bat edo gehiago onartzen ditu |
| Tentsore-literala | Tensor [[1, 2], [3, 4]] | N dimentsioko tentsore bat sortzen du |
| Tentsoreen indexatzea | t[0, 1] edo t[0][1] | Tentsorearen elementuak atzitzen ditu |
| Tentsoreen aldaketa | t[0, 1] = 5.0 | Tentsorearen elementuak lekuan bertan aldatzen ditu |
| Einstein uzkurdura | A_ij @ B_jk | Partekatutako indizeen gaineko tentsore-uzkurdura |
| Hadamard eragiketa | A_ij * B_ij | Elementuz elementuko aritmetika, indizeak lerrokatuta |
echo | echo "a" "b" "c" | Kateak terminalean inprimatzen ditu |
out | "text" out | Katea terminalera ateratzen du |
| Lotura lokal aldaezina | x = expr | Aldagai lokal aldaezin bat lotzen du (=-k (none), |, || onartzen ditu) |
| Lotura lokal aldakorra | mut x = expr | Aldagai lokal aldakor bat deklaratzen du (x = new_expr bidez berresleitzen da) |
| Zain-blokea | | cond = expr | = ondorengo baldintzazko zain-adarra (| habiaratua onartzen du) |
| DAG bloke paraleloa | || expr -> var | Azpikalkulu paraleloak, DAG emaitza izendunekin |
| Bloke paralelo zuzena | || expr | Tupla bat itzultzen duen exekuzio paraleloa |
| Eragileak gainkargatzea | op :: type + type => type | Lehendik dauden eragileak gainkargatzen ditu mota berrietarako |
| Bool literalak | True, False | Balio primitibo boolearrak |
| Eragile logikoak | and, or, xor, not | Letra xehezko hitzez osatutako eragile logikoak |
| Sarrera-puntua | fn :: main => () | Programaren derrigorrezko sarrera-puntua |
Iturburu-kodearen formatu kanonikoa (stable format eta editore-tresnak)
Estetikoa soilik, ez da konpiladorearen baldintza (
FR-TOOL-001): Ridgunen analizatzaile lexikoari eta sintaktikoari ez die eragiten zutabeen lerrokatze horizontalak. Lerrokatu gabeko eta zutabetan lerrokatutako.rgiturburu-fitxategiak % 100 baliokideak diraridgunc-entzat. Beheko arauekstable format-ek eta GNU Emacsridgun-mode-k (C-c C-f) aplikatzen duten antolaera estetiko kanonikoa definitzen dute.
- Lerrokatze-taldea sinadura bakoitzeko (
fn ::/op ::):
fn ::edoop ::deklarazio bakoitzak lerrokatze-talde bat hasten du, bere sinadura, eredu-klausulak eta|| expr -> varloturak hartzen dituena, eta hurrengo goi-mailako deklarazioan amaitzen da (fn,op,type,import,global,context,shared,hardware,@).
- Ezkerreko aldeko tokenen zutabe-lerrokatzea ($C_0 = 6$):
fn ::etaop ::6 karaktereko zabalera dute, beraz, sinaduraren ezkerreko aldeko $0$ tokena $C_0 = 6$ zutabean hasten da.=>/->aurreko $i \in [0, N-1]$ token-zirrikitu bakoitzak ("...",'...',[...]eta(...)token bakar gisa hartuta) $W_i = \max(\text{len}(\text{sig_tok}i), \max{\text{clause} : \text{len}(\text{clause_tok}_i) \le 18} \text{len}(\text{clause_tok}_i))$ zabalera du eta $C_i = C_{i-1} + W_{i-1} + 1$ zutabean hasten da.18karaktere baino zabalagoak diren klausula-ereduak muturreko balio gisa hartzen dira: ez dute $W_i$ handitzen taldearen gainerakorako, eta beren lerroan gainezka egiten dute zuriune batekin.- Dagozkien definizio-klausulak $6$ zutabera ($C_0$) koskatzen dira, funtzioaren izena edo eragile-hitzak eta argumentu-eredu guztiak sinadurako zirrikituen azpian bertikalki lerrokatzeko.
=>,=eta->ikurren lerrokatze bertikala ($C_{\text{arrow}}$):
- Izan bedi $C_{\text{arrow}} = \max\big(C_{N-1} + W_{N-1} + 1,; \max_{\text{pipe_bind}}(8 + 3 + \text{len}(\text{pipe_lhs}) + 1)\big)$ eta $C_{\text{ret}} = C_{\text{arrow}} + \text{len}(\text{arrow}) + 1$.
- Sinaduran,
=>$C_{\text{arrow}}$ zutabean jartzen da eta itzulera-mota $C_{\text{ret}}$ zutabean. - Lerro bakarreko klausuletan (
<lhs> = <rhs>), lerro anitzeko bloke-klausuletan (<lhs> =) eta zain-goiburuko klausuletan (<lhs> =eta atzetik| cond = ...),=$C_{\text{arrow}}$ zutabean jartzen da (=>-ren azpian zuzenean lerrokatuta); lerro bakarreko klausuletan,<rhs>$C_{\text{ret}}$ zutabean hasten da. - DAG lotura paraleloetan (
|| <lhs> -> <rhs>),||$8$ zutabean hasten da (6 + 2),->$C_{\text{arrow}}$ zutabean jartzen da eta<rhs>$C_{\text{ret}}$ zutabean hasten da. - Ordezko forma trinkoa (
> 4parametro edo> 80zutabe): Deklarazio batek4parametro-zirrikitu baino gehiago baditu edo haren sinadura lerrokatuak80karaktere gainditu baditzake, zutabeen betegarri horizontala desgaitu egiten da talde horretan eta tokenak zuriune bakarrez (" ") bereizten dira, klausulen 6 zutabeko koska mantenduta.
- Egitura-koska (2 zuriuneko desplazamendua):
- Goi-mailako deklarazioak (
fn,op,type,import,global,context,shared,hardware,@):0zutabea. - Funtzio- edo eragile-klausulak sinadura baten azpian:
6zutabea. - Zainak (
| cond = expr) eta hodi paraleloak (|| expr/|| expr -> var):prev_indent + 2(8zutabea klausula baten barruan, edoindent + 2lotura lokal baten edo zain habiaratu baten barruan). =-rekin amaitzen den lerro baten atzeko bloke sekuentzialaren gorputz-lerroak:prev_indent + 2.
Goi-mailako bilduma-eragiketa sekuentzialak eta paraleloak (FR-COMP-001, FR-COMP-014)
Ridgunek bilduma-konbinatzaile sekuentzial estandarrak (map, filter, fold) eskaintzen ditu, || aurrizkidun nukleo anitzeko konbinatzaile paralelo esplizituekin batera (||map, ||filter). Bost konbinatzaileek onartzen dituzte bai ezkerretik eskuinerako hodi edo infix sintaxi idiomatikoa (xs map f -> filter g -> fold 0 h -> res) bai ohiko aurrizki-sintaxia (map f xs):
| Integratua | Aurrizki- eta hodi-formak | Exekuzio-eredua |
|---|---|---|
map | xs map f / xs -> map f / map f xs | Sekuentziala: f x ezkerretik eskuinera ebaluatzen du, zorrotz, deitzen duen harian. |
| ` | map` | |
filter | xs filter p / xs -> filter p / filter p xs | Sekuentziala: p x predikatua ezkerretik eskuinera ebaluatzen du, zorrotz, deitzen duen harian. |
| ` | filter` | |
fold | xs fold init f / xs -> fold init f / fold f init xs | Ezkerreko tolestura sekuentziala: acc = f acc x metatzen du ezkerretik eskuinera, init-etik hasita. |
Hitzez hitzeko fitxategi-S/Ia, byte-korronteak eta POSIX integratuak (FR-VM-001, FR-VM-002)
- Hitzez hitzeko fitxategi- eta byte-korronte-S/Ia (
FR-VM-001):
read_file : String => String-k fitxategien edukia hitzez hitz irakurtzen du (\r\neta EOFeko lerro-jauzia dagoen ala ez zehazki mantenduta, eta konpiladorearen.rgimportaurreprozesadorea datu-fitxategietan inoiz exekutatu gabe).load_rg_source : String => Stringkonpiladorearen tresna-kateak bakarrik erabiltzen du,.rgiturburu-fitxategiakimporttxertaketarekin kargatzean.read_bytes : String => [Int]etawrite_bytes : String [Int] => ()byte-korronte bitar gordinak irakurri eta idazten dituzte (0..255,0x00NUL eta0x80..0xFFbarne).
- Fitxategi-sistemaren, prozesuen eta segurtasunaren POSIX integratuak (
FR-VM-002):
- Fitxategi-sistema:
list_dir,file_lstat,sha256_file,sys_mkdir,sys_chmod. - Prozesuak eta ingurunea:
sys_exec,sys_chdir,sys_getcwd,sys_getenv,sys_setenv,sys_exit. - Segurtasuna eta pribilegioen bereizketa:
sys_getuid,sys_getgid,sys_username,sys_user_groups,sys_lookup_uid_gid,sys_setresgid,sys_setgroups,sys_setresuid,sys_execve,sys_read_pass.
- Plataforma anitzeko PAL S/Ia, polling-a, prozesu-primitibak, helburu-ADTak eta
with timeoutkuota deklaratiboak (FR-COMP-007):
- Aurrez deklaratutako helburu-plataformaren ADTak:
type SysOs = Linux | MacOS | Windows(sys os => SysOs, hedagarriaexpand type SysOs = ...bidez)type SysArch = X86_64 | Arm64(sys arch => SysArch, hedagarriaexpand type SysArch = ...bidez)- Iraupen-unitateko literalak: Osoko literalek
_ms(* 1),_s(* 1000) eta_min(* 60000) atzizkiak onartzen dituzte (adibidez,500_ms,5_s,2_min), byte-unitateen atzizkiez gain (_KB,_MB,_GB). - 1. geruza — Plataforma anitzeko PAL primitibak
.rglibsistema-liburutegietarako (posix.rglib/io.rglib): sys os => SysOsetasys arch => SysArch(konpilazio-garaiko helburuko sistema eragilearen eta arkitekturaren batura-ADTak)sys open mode String String => Int(path,"r","w","a","rw","w+","a+"modu eramangarria -> deskribatzailea/handle-a>= 0edo-errno, sistema eragile helburu bakoitzerako itzulita)sys open String Int Int => Int(path, Ridgun PALflagsnormalizatuak (0= irakurri,1= idatzi,2= rdwr,64= sortu,512= moztu,1024= gehitu amaieran,2048= nonblock),mode->fd >= 0edo-errno)sys close Int => Int(fd->0edo-errno)sys read fd Int Int => String(fd,max_bytes->fd-tik irakurritako katea)sys write fd Int String => Int(fd,data-> idatzitako byteak edo-errno)sys poll Int Int Int => Int(fd, Ridgun PALeventsnormalizatuak (1=POLLIN/irakurri,4=POLLOUT/idatzi),timeout_ms->> 0revents prest dagoenean,0denbora-muga gainditzean,< 0-errnodenean;sys remaining mserabiltzen dutimeout_ms < 0deneanwith timeoutbarruan)sys terminate Int Bool => Int(pid,force-> prozesu-amaiera eramangarria, ordenatua edo behartua) etasys kill Int Int => Int(pid, seinale normalizatua ->0edo-errno)sys call Int Int Int Int Int Int Int => Int(nr,a1..a6-> helburuko sistema eragilearen ABIko maila baxuko sistema-dei ihesbidea)sys time ms => Intetasys sleep ms Int => ()(milisegundoko erloju monotonoa eta loa)sys deadline ms => Intetasys remaining ms => Int(denbora-muga lexiko aktiboaren epe-muga eta geratzen diren milisegundoak, edo-1mugarik ez dagoenean)- 2. geruza —
with timeout <duration> doexekuzio-kuota deklaratiboa: with region 64_KB do-k byte-kuota lexiko bat ezartzen duen bezala,with timeout 500_ms do-k (edowith region 64_KB, timeout 500_ms dokonbinazioak) exekuzio-epe-muga lexiko bat (sys_time_ms + duration_ms) ezartzen du uneko hariaren testuinguruan, eta aurreko epe-muga berrezartzen du blokeatik irtetean:
with timeout 500_ms do
rem = sys remaining ms
rc = sys poll fd 1 rem
rc
- Ikus
docs/lang/pal-and-system-libraries.mdPALaren eta sistema-liburutegien (.rglib) arkitekturaren espezifikazio osorako.
- Liburutegi berrerabilgarrien konpilazioa (
.rglibeta ELF64.so) etastablehedagarria (FR-COMP-006,FR-TOOL-003):
ridgunc build --lib <file.rg> -o <out.rglib>-ek etaridgunc build --so <file.rg> -o <lib.so>-k (edostable built lib/stable new --lib <name>komandoek) moduluak konpilatzen dituztefn :: main => ()behar izan gabe, eta esportatutako funtzio, eragile eta mota guztiak gordetzen dituzte.stable-kfn :: task <words...> => Stringkomando pertsonalizatuak etafn :: plugins => [String]hedapenak (plugins/*.rg,.stable/plugins/*.rg) aurkitzen ditu, etastable tasksetastable pluginsbidez zerrendatzen dira.
Ridgunen memoria-kudeaketa (RMM): RMM1 (CMM) eta RMM2 (FR-COMP-002)
Ridgunek heap memoria (String, [a], (a, b), ADTak, Tensor) modu deterministan kudeatzen du, arakatze bidezko zabor-biltzailerik (GC) gabe, Ridgun Memory Management (RMM) bidez:
RMM1politika — Memoria Kudeaketa Konpilatua (CMM Lineala eta Baldintzazkoa):
- Kontrol-fluxua eta deitutako funtzioak konpilazio-garaian estatikoki ezagunak direnean aplikatzen da, habiaratu gabeko loturen gainean:
- CMM Lineala (
rg_cmm_move/rg_cmm_drop): Konpiladoreak aldagai lokal bakoitzaren azken erabileraren sententzia zehatza zehazten du konpilazio-garaian, itzulitako aldagaiak mugitzen ditu (rg_cmm_move(&mut lv_x)) eta baldintzarik gabeko askapena igortzen du (rg_cmm_drop(&mut lv_x)) aldagaiaren azken erabileraren ondoren berehala, may-alias biziriak geratzen ez direnean. - CMM Baldintzazkoa (
rg_cmm_drop_unless/ptr(a) != ptr(c)): Adarkatze estatikoko dei batek (c = choose_list cond a b) hautagai diren sarreretako bat itzultzen duenean eta hautagai bat edo gehiagoc-rekin batera bizirik geratzen direnean, konpiladoreak arbasoen may-alias taula (RCmmAlias) eraikitzen du eta PUZ ziklo 1eko erakusle-identitatearen zain bat igortzen du aldagai bakoitzaren azken erabilera estatikoko sententzian:
a = make_a () -- Allocates M1
b = make_b () -- Allocates M2
c = choose_list cond a b -- b dies here while c is live -> if ptr(b) != ptr(c) { free(b) }
print_list a -- a dies here while c is live -> if ptr(a) != ptr(c) { free(a) }
consume_list c -- c dies here (no live peers) -> free(c) (unconditional)
RMM2politika — Esleipen bidezko kontaketa eta egituren kaskada (politika aktiboa):
- Memoria-kudeaketa bateratzen du funtzioetan, adarkatutako itzuleretan (
choose_list), edukiontzi habiaratuetan (xs = [a, b, ..., z],xs[3] = a), aldagai lokal aldakorretan (mut x = ...) eta hari anitzeko exekuzioan: - Eskalar primitiboak (
Int,Real,Bool,()): Ez dira inoiz zenbatzen; balioz kopiatzen dira pilan edo erregistroetan. - Funtzioaren sarrerako argumentuak (
pats): Ez dira inoiz ukitzen (+0sartzean,-0irtetean). - Barneko aldagai lokalak (
x = .../mut x = ...):+1jasotzen dute esleipenean (x = expr,xs[3] = a). Berresleipen aldakorrean (x = new_expr),new_expr-ek+1jasotzen duxzaharrak-1jaso aurretik. - Funtzioaren amaiera / esparrutik irtetea:
- Itzultzen ez diren barneko aldagai lokalek
-1jasotzen dute lehenik:rc == 0bada, bloke gurasoa askatzen da eta-1kaskadan hedatzen dio, banan-banan, bere seme-alaba zuzen bakoitzari (rc-a0-ra iristen zaion edozein seme-alaba errekurtsiboki askatuz). - Itzultzen den barneko aldagai lokal batek (
return a)-1jasotzen du (edorg_cmm_movebidez mugitzen da), eta bideanrc-a0izan arren, salbuetsi egiten da, deitzailearen esleipenak (c = make_pair ())+1gehi dezan (0 + 1 = 1). Sarrerako argumentu bat itzultzen denean (choose_list cond a b), funtzioaren barruan ukitu gabe egon da (rc = 1), beraz deitzailearenc = choose_list cond a b-k+1gehitzen du (1 + 1 = 2,a-ren etac-ren artean partekatuta).
RMM3politika (Erreserbatua):
- Etorkizuneko optimizazio estatiko oldarkor baterako erreserbatua.
- Ikus
docs/etc/cmm_architecture.md(Ridgun biltegian)RMM1etaRMM2-ren espezifikazio osorako.