Raku (korábban Perl 6) | |
---|---|
Nyelvóra | Több paradigma |
Megjelent | A fejlesztés 2000 óta folyik. Az első megjelenésre 2015. december 25-én került sor |
Szerző | Larry Wall |
Fejlesztő | Larry Wall és Audrey Tan |
Fájlkiterjesztés _ | .raku, .rakumod, .rakudoc, .rakutestvagy.t |
Kiadás | 6.d (2020. február 24. ) |
Típusrendszer | dinamikus, statikus |
Befolyásolva |
haskell , JavaScript , Perl , Ruby , Smalltalk , J |
befolyásolta | Perl , Haskell , AntLang |
Engedély | GNU általános nyilvános licenc , művészi licenc |
Weboldal | raku.org |
OS | platformközi |
A Raku ( japánul 楽土, ejtsd : rakudo - Paradise , [1] [2] és 楽, ejts. raku - boldogság, könnyűség, sukha [3] [4] ) egy programozási nyelv a Perl - szerű nyelvek családjából. . A Perl nyelv tervezésének és megvalósításának jelentős átalakítása, megszakítva a vele való kompatibilitást , bár a kompatibilitási módnak 2010-ig még léteznie kellett volna. [5]
A Perl nyelvhez hasonlóan a Raku is nagy szabadságot hagy a programozóknak . Továbbra is lehetővé teszi, hogy tömören fejezze ki magát, beleértve az egysoros szövegek írását is, de a statikus gépelésnek és a továbbfejlesztett OOP támogatásnak köszönhetően a nagy programok írását is leegyszerűsíti .
Raku korábbi neve Perl 6 volt . [6] Sok éven át viccek folynak a Perl közösségben a megjelenés dátumával kapcsolatban. Arra a kérdésre, hogy "mikor jelenik meg a Perl 6", a szokásos válasz az volt, hogy "karácsonykor", de év nélkül. [7] [8] 2015-ben, azaz tizenöt év várakozás után végre bejelentették az úgynevezett "karácsonyi" verziót. [9] [10] [11]
A Perl 6-ban úgy döntöttünk, hogy jobb a nyelvet javítani, mint a felhasználót.Larry Wall [12]
A Perl 6 fejlesztését először Larry Wall jelentette be 2000. július 19-én, az idei Perl Konferencia negyedik napján [13] a Hagyma állapota című előadásában . [14] Akkoriban a prioritások a következők voltak: a „történelmi szemölcsök” eltávolítása a nyelvből; "az egyszerű dolgoknak egyszerűnek kell maradniuk, a bonyolultaknak egyszerűbbé kell válniuk, a lehetetleneknek pedig bonyolultaknak kell lenniük"; belső kialakítás és API általános tisztítása . A folyamat egy sor RFC -vel kezdődött . Ez a folyamat minden résztvevő számára nyitva állt, és a nyelv egyetlen aspektusa sem maradt zárva a változtatásra. [tizenöt]
361 kérés érkezett be, a Wall mindegyiket felülvizsgálta. Ezután elkezdte több „Apokalipszis” megírásának folyamatát, ami egy keresztény kifejezés, ami azt jelenti, hogy „jó hírt kell közölni a jó embereknek”. [16] Bár az eredeti cél az volt, hogy az en:Programming Perl könyv minden fejezetéhez írjanak egy Apokalipszist , nyilvánvalóvá vált, hogy minden Apokalipszis írásakor a korábbi Apokalipsziseket felülírták a későbbi változtatások. Emiatt megjelentek a Szinopszisok, amelyek mindegyike egyetlen Apokalipszisre vonatkozik, de tartalmazott az új Apokalipszisek javításait is. Ma a Raku specifikációt a "sült" tesztcsomag vezérli, [17] míg a szinopszisokat történelmi referenciaként tartják nyilván. [tizennyolc]
Damian Conway írt egy Exegézis-sorozatot is, amely a gyakorlati felhasználás szempontjából elmagyarázza az egyes Apokalipszisek tartalmát. Minden Exegézis kódpéldákból áll, amelyek használatukat és jelentésüket tárgyalják. [19]
Az eredeti beszédében Wall által javasolt fő cél a „történelmi szemölcsök” eltávolítása volt. Ezek közé tartozott a tömbök és hash-ek jeleinek zavara, a függvények kétértelműsége, aselect csupasz [20] (központozás nélkül [21] ) fájlleírók használatával kapcsolatos problémák. Wall sok más problémát is megemlített beszédében, amelyekről a Perl programozói évek óta beszélnek.
Ezeknek a céloknak a következménye a visszafelé kompatibilitás elvesztése volt. Mivel a visszafelé kompatibilitást rendszerint a szoftver fejlesztése jelenti, a Perl 6-ban az azt megszakító változtatásokat kifejezetten ki kellett volna mondani. Fokozatosan a különbség a Perl 5 és a Perl 6 között olyan nagy lett, hogy a Perl 6 átnevezték Raku -ra 2019. október 12-én . [6]
Az évek során a Raku fejlődési vektora többször változott. A Python és a Ruby fogalmak bevezetése korai hatást gyakorolt. [22] [23] [24] Ezenkívül a Pugs, az első Raku interpreter a Haskell funkcionális nyelven íródott, és a funkcionális programozás számos elemét átvette a Raku fejlesztőcsapata. [25] [26]
A nyelv kabalája a Camellia rovar. [27] Neve a perl nyelvi emblémára utal, a tevére ("Camel"), alakja pedig a szójátékot kedvelő Perl közösség hagyományai szerint a " bug " szót visszhangozza . A pillangószerű szárnyaiba írt spirális minták a "P6" karakterekre emlékeztetnek, az egymástól eltérő kancsalság pedig szándékos szójáték a "falszemű". [28]
Az élénk és színes logótervezés egyik célja az volt, hogy visszaszorítsa a nőgyűlöletet a közösségben, és lehetővé tegye a "férfias meggyőződésű" emberek számára, hogy megmutassák érzékeny oldalukat. [29]
A Rakudo a legfejlettebb implementáció, [30] amely nem teszi a nyelv hivatalos változatává, as a nyelvet nem az implementáció határozza meg, hanem a tesztcsomag. [31]
A Rakudo lehetővé teszi [32] kód futtatását MoarVM, JVM és Node.js virtuális gépeken . [33] A MoarVM egy virtuális gép, amely kifejezetten a Rakudo és az NQP fordító számára készült. [34] [35] Az NQP (Not Quite Perl 6 ) fordítója a nyelv egy részhalmazát valósítja meg, amely Raku-szabályokat tartalmaz a forráskód-elemzéshez, az absztrakt szintaktikai fa kezeléséhez és a háttér-specifikus kódgeneráláshoz . A Rakudo nagy része Raku és NQP nyelven íródott. A Rakudo nem önálló fordító, és jelenleg nem tervezik a fordító népszerűsítését .
A "2015.02" verzió után a Rakudo megszüntette a Parrot virtuális gép [36] (a MoarVM elődje) támogatását, amely arra a téves feltételezésre épült, hogy a Perl 6 hasonló lesz a Perl 5-höz. [37] [38]
A Raku első implementációja a Pugs [39] volt , egy Haskell nyelven írt értelmező és fordító . Ez volt a legfejlettebb megvalósítás, azonban 2007 óta csak minimális javítások történtek, hogy lépést tartsanak a GHC új verzióival , és 2014 novemberétől a Pugs nem támogatott. [40] 2006 augusztusában Yichun Zhang töredékekre bontotta a Pugs tesztfájlokat, hozzácsatolva a megfelelő Synapsis bekezdéseket, [41] [42] és 2008 januárjában ezeket a teszteket beépítették a nyelv hivatalos tesztjébe ("sült"). ”). [43] [44] 2015 februárjában a közösség specifikációnak nyilvánította a nyelvvizsgákat. [45]
A Raku és a Perl alapvetően különböznek egymástól, bár a szándék az volt, hogy Raku maradjon Perlként. A legtöbb változtatás célja a nyelv normalizálása, hogy a kezdő és a tapasztalt programozók számára is könnyebben érthető legyen, valamint hogy "egyszerűbb dolgokat és bonyolultabb dolgokat tegyenek lehetővé".
A fő nem technikai különbség az, hogy a Raku specifikációként indult. [31] Ez azt jelenti, hogy a Raku szükség esetén újra implementálható, és azt is, hogy a programozóknak nem kell beolvasniuk a forráskódot ahhoz, hogy teljes irányítást szerezzenek bármely funkciója felett. A Perl nyelv esetében a hivatalos dokumentáció csak az aktuális tolmács viselkedését írja le. A dokumentáció és a megvalósítás között talált eltérések az egyik vagy a másik megváltoztatását eredményezhetik, ami a Perl-kiadások folyamatos fejlesztésének és javításának hajtóereje.
A Rakuban a dinamikus típusrendszert statikus típusokkal egészítették ki . [46] Például:
my Int $i = 0 ; az én Patkányom $r = 3,142 ; my Str $s = "Hello, world" ;A statikus típusok azonban opcionálisak maradnak, így a programozók a legtöbb dolgot megtehetik anélkül, hogy kifejezetten megadnák a típusokat.
én $i = "25" + 10 ; #$i 35 évesA Perlben a szubrutinoknak nincsenek formális paraméterei , bár a paraméterek számának és típusának egyszerű ellenőrzése lehetséges szubrutin prototípusok használatával. [47]@_ Ehelyett a referenciaként átadott tényleges paraméterek a szubrutin törzsében lévő tömbelemek mögé rejtőznek .
A valódi formális paraméterek a Rakuban jelennek meg. [48] Például:
sub do_something ( Str $thing , Int $egyéb ) { ... }Csakúgy, mint a Perlben, a Rakuban is referenciaként adják át a paramétereket, de a Rakuban alapértelmezés szerint állandóak , pl. értékeik nem változtathatók. Kifejezetten deklarálhatók, hogy lehetővé tegyék az eredeti érték megváltoztatását ( is rw), vagy másolatként ( is copy), ami egyenértékű az érték átadásával.
A paraméterek átadásának módjaiHárom módja van a paraméterek átadásának a Rakuban: pozicionális, elnevezett és slurpy .
A pozícióparaméterek csak egy rendezett lista, mint a legtöbb programozási nyelvben. Még ők is tetszőleges sorrendben adhatók át, amennyiben a nevüket megadják. A csak névvel átadható :paramétereket a formális paraméter jele előtt egy szimbólum jelöli. A paraméterek összehúzása egy módja annak, hogy változó függvényeket hozzunk létre a Rakuban. Ezeket egy szimbólum jelzi *a formális paraméter jele előtt. A slurpy hash a szubrutin deklarációjában nem említett paramétereket fogja rögzíteni, a slurpy tömb pedig a későbbi tényleges helyzeti paramétereket.
A következő példában mindhárom metódus jelen van, beleértve a slurpy tömböt is.
sub somefunction ( $a , $b , : $c , : $d , * @e ) { ... } valamilyen függvény ( 1 , 2 , : d ( 3 ), 4 , 5 , 6 ); # $a=1, $b=2, $d=3, @e=(4,5,6)A pozícióparaméterek alapértelmezés szerint kötelezőek, kivéve, ha a paraméter nevét követi kérdőjel. A megnevezett alapértelmezett paraméterek viszont nem kötelezőek, kivéve, ha a nevet követi felkiáltójel. A Squishy paraméterek mindig nem kötelezőek.
Blokkok és lezárásokA paraméterek átadhatók minden olyan kódblokknak is, amely zárásként viselkedik . Különösen például a ciklusok testei forzárások while. A következő példában a ciklus egyszerre három elemet vesz fel a listából, és átadja őket a blokknak változóként $a, $bés $c. [49]
@list - > $a , $b , $c { ... }Ezt "pointy sub"-nak vagy "pointy block"-nak hívják, és a benne lévő nyíl valamelyest kulcsszóként viselkedik sub, névtelen lezárást (vagy a Perl terminológiájában egy névtelen szubrutint) vezet be. [48]
A Perlben a jelek (a változónevek előtt megjelenő írásjelek) a változó használatától függően változnak.
# Perl kód my @ array = ('a', 'b', 'c'); én $elem = $ tömb[1]; # 'b'-t adja vissza, my @extract = @tömb [ 1, 2]; # visszatér ('b', 'c') my $elem = @tömb [1]; # „b”-t ad vissza figyelmeztetéssel (5.10 óta)A Rakuban a jelek változatlanok: mind a tömbnek, mind a tömbelemnek ugyanaz a jele. [46]
# Raku kód my @ array = 'a', 'b', 'c'; my $elem = @tömb [1]; # $elem 'b' my @extract = @tömb [ 1]; # @extract ("b") my @extract = @tömb [ 1, 2]; # @kivonat van írva ('b', 'c')A Perlben a jelek változékonyságát az angol és sok más természetes nyelv számkonvenciója ihlette .
– Ez egy alma. # $a igaz – Ezek az almák. # @egy igaz – Ez a harmadik alma. # $a[3] igaz – Ez a harmadik alma. # @a[3] nem helyesEz a koncepció azonban megszakad, amikor a hivatkozások szóba kerülnek, mivel ezek skalárként hivatkozhatnak adatstruktúrákra. Így a beágyazott adatszerkezetekkel való munkavégzés megkövetelheti, hogy az egyes és többes számot is ugyanabban a kifejezésben fejezzük ki:
# Perl kód: tömb lekérése hash elemből. # Ez a hash tömböket tartalmazó kivonatokat tárol. my @trans_verbs = @ { $szótár { 'ige' }{ 'tranzitív' } };Az ilyen konstrukcióknak nincs analógja a közönséges természetes nyelvekben, ami nagy kognitív terhelést okoz a kódírás során. Ugyanaz a Raku kód:
# Raku kód: tömb lekérése hash elemből. # Ez a hash tömböket tartalmazó kivonatokat tárol. my @trans_verbs = %dictionary<verb><transitive><> ;A Perl nyelvben az objektum-orientált programozást egy olyan függvény támogatja, amely bármely változót egy bizonyos osztály objektumává változtat, amelyből az osztályban deklarált metódusokbless hívhatóvá válnak . [ötven]
Bár rendkívül erős, ez a mechanizmus ugyanakkor még a legalapvetőbb OOP leírását is megnehezíti – az egyszerű szerkezetszerű objektumok és a kapcsolódó eljárások leírását. Továbbá, mivel a Perl nem tesz feltételezéseket az objektummodellről, a metódushívásokat a fordító nem tudja optimalizálni.
A Raku megtartja az alacsony szintű metódust bless, de korlátozóbb objektummodellt is biztosít a gyakori használati esetekre. [51] [52] Például egy olyan osztály, amely egy pontot foglal egy derékszögű koordinátarendszerbe , a következőképpen definiálható:
class Pont rw { $ .x ; _ rendelkezik $.y ; metódus távolság ( $p pont ) { sqrt (( $!x - $p . x ) ** 2 + ( $!y - $p . y ) ** 2 ) } metódus távolság-középpont { self . távolság: Pont . új ( x => 0 , y => 0 ) } } én $pont = Pont . új ( x => 1,2 , y => - 3,7 ); mondd : "Point position: (" , $point . x , ', ' , $point . y , ')' ; # Pontpozíció: (1,2, -3,7) # X és y módosítása (az "x" és "y" metódusokkal): $point . x = 3 ; $pont . y = 4 ; mondd : "Point position: (" , $point . x , ', ' , $point . y , ')' ; # Pontpozíció: (3, 4) my $other-point = Pont . új ( x => - 5 , y => 10 ); $pont . távolság ( $más-pont ); #=> 10 $pont . távolság a központtól ; #=> 5Perlben a metódusokat egy nyíllal hívják meg: $object->method(). A Raku egy pontot használ nyíl helyett, mint sok más nyelv (például a Java és a Python).
A Raku terminológiában $.xattribútumnak nevezik. Az attribútum eléréséhez használt módszert accessornak [53] nevezzük (az angol access - access szóból). Automatikusan jön létre (amikor egy attribútumot egy ponttal deklarálunk [54] ), és ugyanaz a neve, mint az attribútum. Úgy működik, mint egy getter , és amikor egy osztály vagy attribútum is rwfelveszi a setter tulajdonságait, és használható a hozzárendelés bal oldalán. Az automatikus hozzáférések helyett a programozó saját egyéni metódusokat határozhat meg. Ezenkívül az osztály törzsében minden attribútum, függetlenül attól, hogy hogyan vannak deklarálva, közvetlenül elérhető a $!.
Öröklődés, szerepek és osztályokAz öröklődés egy olyan technika, amelyben az objektumok vagy típusok más objektumok vagy típusok logikáját vagy definícióit használják fel. Például egy programozó létrehozhat egy szabványos típust egy opcionális attribútummal. Az olyan nyelvekben, mint a Java, az öröklődést osztályok biztosítják, amelyek más meglévő osztályok alosztályai lehetnek.
A Raku az osztályokon keresztül is biztosítja az öröklődést, hasonlóan más programozási nyelvek osztályaihoz, valamint szerepek révén.
A Rakuban a szerepek a Java nyelvben az interfészek , a Rubyban a mixinek, a PHP -ben a [55] tulajdonságok és a Squeak (a Smalltalk nyelv egyik dialektusa ) funkcióját töltik be. Hasonlóak az osztályokhoz, de biztonságosabb összeállítási mechanizmust biztosítanak, mint az öröklődés, amely megakadályozza az attribútum- és metódusnevek ütközését. [56] [57] A szerepek nincsenek beépítve az öröklési láncba. A szerepek a névleges típusú rendszerre vonatkoznak (lásd en:Nominal type system ), nem pedig a szerkezeti típusrendszerre, amelyet például a Go -ban használnak . Szemantikai neveket adnak a viselkedések és állapotok halmazainak. A szerepek és az osztályok közötti alapvető különbség az, hogy a szerepek nem példányosítanak objektumokat. [58]
Bár a szerepek különböznek az osztályoktól, lehetséges olyan kódot írni, amely egy szerepkörből objektumot hoz létre. Ha egy szerepkört próbál meg létrehozni egy objektum létrehozásához, az azonos nevű osztály létrehozását eredményezi. A Raku dokumentációja ezt a mechanizmust automatikus szereposztásnak nevezi. a generált osztály szójáték. [59]
A szerepek alapvetően attribútumok és potenciálisan absztrakt metódusok kötegei, amelyek öröklődés nélkül adhatók hozzá egy osztályhoz. Egy szerepkör akár egyetlen objektumhoz is hozzáadható. Az utóbbi esetben a Raku létrehoz egy anonim alosztályt, hozzáad egy szerepet, és lecseréli az objektum osztályát erre a névtelen alosztályra.
Például a kutya emlős , mert a kutyák bizonyos tulajdonságokat örökölnek az emlősöktől, például az emlőmirigyeket és gerinces őseik révén a gerincet . Másrészt a kutyák különböző típusú viselkedést mutathatnak, amelyek idővel változhatnak. Például egy kutya lehet házi, kóbor, lehet vezető . Ezeket a további viselkedési formákat hozzá lehet adni a kutyához. Leírhatod őket úgy, hogy más állatokra is alkalmazhasd. Például egy macska lehet házias és kóbor. A kutya és a macska különbözik egymástól, de az emlősök általános kategóriájába tartoznak. Tehát Млекопитающее ez egy osztály, Собакаés Кошка egy emlőstől örökölt osztályok. A fenti viselkedések azonban olyan szerepkörök, amelyek osztályokhoz vagy osztályokból létrehozott objektumokhoz adhatók.
osztály Az emlős gerinces { ... } osztály Kutya emlős { _ ... } szerep Pet { ... } szerep hajléktalan { ... } szerep útmutató { ... }A szerepek az osztályokhoz és objektumokhoz adhatók hozzá a does. Az öröklődéshez a kulcsszót használjuk is. Ezek a szavak e nyelvi sajátosságok értelmének különbségét tükrözik: egy szerep hozzárendelése egy szerep viselkedését adja az osztálynak , de nem jelenti azt, hogy az osztály szó szerint ugyanaz lesz, mint az a szerep.
osztály vakvezető kutya vakvezető kutya vakvezető kutya { ... } # Az alosztály szerepkört csatol. my $dog = Kutya . új (); $dog csinál vakvezető kutyát ; # Az objektum hozzárendeli a szerepet.Mind a szerepek, mind az osztályok típusok. Egy szerep változó deklarációban használható. Például egy szerepkör Незрячийtartalmazhat egy típusú attribútumot Поводырь, amely lehet vakvezető kutya, vakvezető ló, vezető személy vagy akár vakvezető autó.
class Ember { van Kutya $kutya ; # Bármilyen kutyát tartalmazhat - ... # mindegy, hogy vakvezető kutya-e vagy sem. } role Blind { has Guide $guide ; # Tartalmazhat bármilyen tárgyat, amelynek szerepe ... # Útmutató - nem számít, hogy kutya-e vagy sem. }A reguláris kifejezések és a karakterlánc-kezelés mindig is a Perl egyik meghatározó jellemzője volt. [60] Mivel a Perl mintái valamikor meghaladták a reguláris kifejezéseket, [61] a Raku-dokumentáció egyszerűen regexeknek nevezi őket , elhatárolva magát a reguláris kifejezések formális definíciójától.
A Raku kiterjeszti a Perl szolgáltatáskészletét a reguláris kifejezések köré azáltal, hogy beágyazza őket egy nagyobb keretbe az elemzők , úgynevezett szabályok létrehozásához . [62] A szabályok környezetérzékeny elemzési lehetőségeket biztosítanak (például a PEG és az ANTLR szintaktikai predikátuma ), és lexikális hatókörük lezárásaként viselkednek . [63] A szabályokat a kulcsszó használatával kell megadni , ami hasonló az alprogram meghatározásához. Az anonim szabályok beírhatók a (vagy ) kulcsszó használatával , vagy leírhatók reguláris kifejezésekként a Perlben a (match) vagy (replace) operátorok használatával. ruleregexrxms
Az Apokalipszis 5 -ben Larry Wall 20 problémát sorol fel a jelenlegi "regex kultúrával". Többek között a Perl reguláris kifejezései "túl kompaktak és "aranyosak" voltak", "túl kevés speciális karakterre támaszkodtak", "gyenge elnevezési támogatással", "gyenge nyelvtani támogatással" és "rossz nyelvi integrációval" rendelkeztek. . ". [64]
A Raku néhány Perl-konstrukciója megváltozott, és más szintaktikai kifejezésekhez optimalizálva lett. Például a zárójelek használata, amelyekre a végrehajtási sorrend utasításaiban volt szükség , most nem kötelezőek. [49]
if -true () { for @array { ... } }A ,(vessző) operátor most egy listakészítő, így a listák körül nem szükséges zárójeleket tenni.
@tömb = 1 , 2 , 3 , 4 ;A Raku a következő kifejezéseket engedélyezi:
if 20 <= $hőmérséklet <= 25 { mondd "A szoba hőmérséklete 20 és 25 fok között van!" }Ezt a balról jobbra történő szekvenciális összehasonlításoknak tekintjük, majd ezt követi a logikai ÉS egy unió .
A Raku egy lusta listaértékelési technikát használ, amely hasonló néhány funkcionális nyelvhez, mint például a Haskell : [65]
@integers = 0 .. inf ; # egész szám nullától a végtelenigEz a kód nem okoz hibát a végtelen lista tömbbe helyezésekor @integers, és nem fog lefagyni, ha a lista korlátlanul bővíti, ha véges számú elemet kérnek.
Ez leegyszerűsíti a Raku számos gyakori feladatát, beleértve az I/O műveleteket, a listaátalakításokat és a paraméterek átadását.
gatherLehetőség van lusta listák létrehozására is a és kulcsszavak használatával take. Hasonlóak az Icon és Python generátoraihoz .
én $négyzetek = lusta gyûjteni 0 -ért .. Inf { take $_ * $_ ; };Itt van a természetes számok négyzeteinek$squares végtelen listája (beleértve a nullát is), de a lista lusta jellege miatt az elemek csak elérésekor kerülnek kiértékelésre. [66]
Raku bevezeti a csomópontok fogalmát [67] ( eng. junction - kapcsolat, metszés; Rakuban ez a kifejezés a konjunkcióhoz és a diszjunkcióhoz is kapcsolódik [65] ). Ez több érték szuperpozíciója . [65] A legegyszerűbb formájában egy metszéspontot a metszéspont operátorok hoznak létre :
# Példa a | típusú keresztezésre ("bármilyen"): my $color = 'fehér' ; hacsak nem $szín eq 'fehér' | 'fekete' | 'grey' { die "Az ebben a színben történő nyomtatás nem támogatott.\n" ; } # Példa egy keresztre, mint a & ("all"): my $password = 'titkos!123' ; if $password ~~ /<:alpha>/ & / <:digit> / & / <:punct> / { mondd "A jelszavad elég erős." ; }Az operátor |olyan értéket fejez ki, amely megegyezik a bal vagy a jobb oldali argumentummal, az operátor & - a bal és a jobb oldallal. Ezek az értékek a kódban használhatók, ahol egy értéknek szemantikailag kellene lennie. A keresztezéssel végzett műveletek egyidejűleg hatnak az összes összetevőjére, és az eredményt a keresztezés kezelője kombinálja. Igen, vissza ("apple"|"banana") ~ "s"fog térni "apples"|"bananas". Logikai kontextusban azonban a keresztek csak egy értéket adnak vissza, igaz vagy hamis: anyigazat ad vissza, ha az összehasonlítás legalább egy elemre igaz; alligazat ad vissza, ha az összehasonlítás minden elemre igaz. [68]
Crossoverek használatával lehetőség van a típusrendszer kiegészítésére valamilyen általános programozással , amely a változókat a typecrossokra korlátozza.
részhalmaz Színe Bármilyen , ahol RGB_Color | CMYK_Color ; sub get_tint ( Color $color , Num $ opacity ) { ... }A keresztezések olyan speciális objektumok, amelyek a kódvégrehajtást potenciálisan párhuzamos szálakra osztják . Kifejezetten logikai kontextusban való használatra készültek: nem érheti el közvetlenül a tartalmukat anélkül, hogy ne konvertálná azokat karakterláncsá, ami megkülönbözteti őket például a halmazoktól és más gyűjteményektől. [68]
Az alacsony szintű nyelveken a makrók a forráskódban a szövegcsere szinonimájává váltak a C előfeldolgozóval való társítás miatt . Azonban a magas szintű nyelvekben, mint például a Lisp , amely a C előtt volt, a makrók erősebbek voltak. [69] Raku ezt a Lisp-szerű makrók koncepciót használta ki. [48] Az ilyen típusú makró ereje a program magas szintű adatstruktúraként való működtetésén alapul, nem pedig szövegként, valamint a nyelv összes funkciójához való hozzáférésen.
A Raku makródefiníciója úgy néz ki, mint egy szubrutin vagy metódusdefiníció. És egy ilyen makró működhet mind a forráskóddal, mind az absztrakt szintaxisfával és e két dolog kombinációjával.
macro hello ( $mit ) { quasi { mondd: "Hello { {{$what}}} }" }; }A fenti példában a makró argumentumot a makró végrehajtása előtt elemzi, ami informatívabb fordítódiagnosztikai üzenetekhez vezet. Mivel azonban a makrótörzs végrehajtása a fordítási időben történik (minden használati esetre), sokféle optimalizálási technika alkalmazható . A makrók segítségével bizonyos programok munkájának nagy részét még a végrehajtás megkezdése előtt is elvégezhetjük .
A Rakuban az azonosítók a betűk, számok és aláhúzásjelek mellett aposztrófokat és kötőjeleket is tartalmazhatnak, feltéve, hogy betűk követik őket. A betűk tartalmazzák a "megfelelő" (megvalósítástól függő) Unicode karaktereket , amelyek a Rakudo és a MoarVM rendszerben az "L" kategória összes Unicode karaktereként vannak definiálva. [70]
A kötőjelek használatát aláhúzás helyett „ kebabdoboznak ” nevezik . [71] [72] [73]
A metaoperátorok olyan operátorok, amelyeket más operátorok paraméterezhetnek, ahogy a függvények is vehetnek paraméterként más függvényeket . [74]
Hozzárendelés metaoperátorA Perl örökölte a C nyelvi operátorokat, mint például a +=, *=és így tovább. Raku általánosítja őket egy meta operátorra. Bármely bináris operátorra a opkövetkezőket írhatjuk:
$x op = $y ; # vagy $x [op]= $yMit jelent:
$x = $x op $y ;Ráadásul ez a felhasználó által definiált operátoroknál is működik.
HiperoperátorokHasonlóak a mapPerl operátorához. Kényszerítse az operátorokat, hogy az összes tömbértékkel működjenek. Alkalmazható bináris és unáris operátorokra is. [75]
Például a következő kód létrehoz egy tömböt, amely a tömb összes elemét tartalmazza @aeggyel növelve:
my @aPlusOne = @a "+" 1 ; # vagy @a >>+>> 1A szögletes zárójelek iránya befolyásolja a viselkedést, amikor különböző hosszúságú tömböket adunk át paraméterként. [75] Ezek a "nyilak" mutatják, honnan származik a művelet eredményének hossza.
Példa hiperoperátor használatára unáris operátorral:
az én @a = 1 , 2 , - 3 ; én @b = -<< @a ; # [-1 -2 3]A hiperoperátorok nem csak lapos, hanem beágyazott tömbök esetén is működnek. [76]
Redukciós meta operátorA redukciós meta operátor bármely infix operátorral használható, átalakítva azt listaredukciós operátorrá . Olyan, mintha az operátort az első két elemre alkalmaznák, majd a kapott értékre és a harmadik elemre, és így tovább, amíg csak egy érték marad. Az összeg, szorzat, maximum, minimum stb. operátor-paraméterként működhet. Ez egy rendkívül hatékony mechanizmus, amely például az operátort +listaösszeg operátorrá fordítja, mint az alábbi példában.
mondd: "A 0 és 99 közötti egész számok összege: " , [+] ^ 100 ; Kereszt operátorOperátorként és metaoperátorként is viselkedik. [77]
A keresztoperátor [75] megkeresi az oly módon rendezett listák közvetlen szorzatát, hogy a jobb oldali operandusból gyorsabb az elemek felsorolása, mint a bal oldali operandusból, [77] a listák sorozatát adja vissza:
1 .. 3 X <ab c> X <de f> ; # ((1 ad) (1 ae) (1 af) # (1 bd) (1 be) (1 bf) # (1 cd) (1 ce) (1 cf) # (2 ad) (2 ae) ( 2 af) # (2 bd) (2 be) (2 bf) # (2 cd) (2 ce) (2 cf) # (3 ad) (3 ae) (3 af) # (3 bd) (3 be ) (3 bf) # (3 cd) (3 ce) (3 cf))A meta operátor összecsukja a belső listákat a paraméter operátor használatával: [77]
1 .. 3 X ~ <ab c> X ~ <de f> ; # (1ad 1ae 1af 1bd 1be 1bf 1cd 1ce 1cf # 2ad 2ae 2af 2bd 2be 2bf 2cd 2ce 2cf # 3ad 3ae 3af 3bd 3be 3bce 3cdf3) Zip operátorAngolból . cipzár - cipzár . [78]
A kereszt operátorhoz hasonlóan a listák elemeit kombinálja, [75] de olyan sorozatot ad vissza, amely először az egyes listák első elemeit tartalmazza, majd az egyes listák második elemeit, és így tovább. [79]
<ab c> Z <1 2 3 4> ; # ((a 1) (b 2) (c 3)) 100 , 200 Z + 42 , 23 ; # (142 223) Inverz operátorokA meta operátor R( eng. reverse ) lehetővé teszi az eredeti operátor argumentumainak felcserélését .
mondd: "Egy osztva hárommal egyenlő" , 3 R / 1 ; Meta-operátorok egymásba ágyazásaHa metaoperátort alkalmazunk egy operátorra, akkor egy másik operátor jön létre, amelyre a metaoperátor újra alkalmazható, és így tovább. A szintaxis egyértelművé tétele érdekében a szögletes zárójelek megengedettek. [80]
az én @a = 1 , 2 , 3 ; az én @b = 5 , 6 , 7 ; @a >>>>> @b ; # Elemzési hiba. @a >>[>]>> @b ; # [False False False] # Itt a hiperoperátor >> >> kerül alkalmazásra az összehasonlító operátorra. # A keresztmeta-operátor alkalmazza # az addíciós operátor által paraméterezett # meta-hozzárendelés operátort: @a X [+=] @b ; # (6 12 19 7 13 20 8 14 21) # A keresztmeta operátor miatt a hozzárendelés # az @a tömb minden eleméhez # a @b tömb minden elemével történt, # ami egyenértékű azzal, hogy az @a tömb minden eleméhez # hozzáadjuk a tömb elemeinek összegét @b: mondd [+] @b ; #18 mondd @a ; # [19 20 21]A többi modern nyelvhez hasonlóan a Rakut is úgy tervezték, hogy támogassa a párhuzamosságot és az aszinkron programozást.
A Raku egy egyszerű, moduláris , magas szintű API -t biztosít egyidejű kód írásához, függetlenül attól, hogy a virtuális gép hogyan valósítja meg ezt az API-t. Ezenkívül egyes nyelvi funkciók implicit módon aszinkron módon működhetnek. A kezelhetőség és a funkciók közötti kompatibilitás biztosítása érdekében a felhasználói kódnak lehetőség szerint kerülnie kell az alacsony szintű interfészek ( szálak , ütemezők, zárolások ) használatát. [81]
Az ígéretek [82] [83] a központi magas szintű mechanizmus , amelyek a tényleges befejezésük előtt kapott számítások eredményei. Adhatók, teljesíthetők és megsérthetők. Így három lehetséges állapotuk van. Ennek a mechanizmusnak az erőssége abban rejlik, hogy képes ezeket kombinálni és láncokba kapcsolni:
my $p1 = Ígéretem . új (); én $p2 = $p1 . then ({ mondd: "A második ígéret eredménye." });Itt csak a végrehajtása után thenbiztosítja a végrehajtást . $p2$p1
Van angol is. Kellékek ("készletek") és eng. Szállítók ("beszállítók") - aszinkron adatfolyamok létrehozására szolgáló mechanizmus, amely képes minden egyes üzenetet egyszerre több címzettre feldolgozni, hasonlóan ahhoz, ahogyan az eseménykezelők más programozási nyelvekben működnek . [81] Ez a mechanizmus eseményvezérelt programozáshoz használható .
Végül a csatornák ( angol csatornák ) szálbiztos FIFO - sorok , hasonlóak az operációs rendszerek elnevezett folyamataihoz , de a jelenlegi folyamaton belül működnek. A legfontosabb különbség az Supply, hogy a csőből történő olvasás kimaradás, [81] azaz. egy érték csak egyszer olvasható ki.
Program "Hello World!" gyakran használják egy nyelv alapvető szintaxisának bemutatására. Rakuban így néz ki:
mondd : „Helló, világ” ;Bár természetesen többféleképpen is kifejezhető. [84]
Tényezőszámítás , többféleképpen meghatározva :
# Rekurzió használata "if-else" konstrukcióval. rész tény ( UInt $n --> UInt ) { if $n == 0 { 1 } else { $n * tény ( $n-1 ) } } # Rekurzió használata "if" # kifejezésmódosítóként. sub fact ( UInt $n --> UInt ) { return 1 if $n == 0 ; return $n * tény ( $n-1 ); } # Rekurzió használata a "when" konstrukcióval. sub fact ( UInt $n --> UInt ) { when $n == 0 { 1 } default { $n * fact ( $n-1 ) } } # A háromtagú operátor használata. rész tény ( UInt $n --> UInt ) { $n == 0 ?? 1 !! $n * tény ( $n-1 ) } # Többszörös küldés használata. több tény ( 0 ) { 1 } több tény ( UInt $n --> UInt ) { $n * tény ( $n - 1 ) } # A redukciós meta operátor használata. rész tény ( UInt $n --> UInt ) { [*] 1 .. $n } # A faktoriális operátor meghatározása, # a redukciós meta-operátoron keresztül megvalósítva. sub postfix: <!>( UInt $n --> UInt ) { [*] 1 .. $n } # Az "állapot" kulcsszó használata az emlékezéshez. rész tény ( UInt $n --> UInt ) { állapot %ismert = 0 => 1 ; %known { $n } visszaküldése , ha %known { $n }: létezik ; %ismert { $n } = $n * tény ( $n-1 ); return %known { $n }; }A QuickSort egy jól ismert rendezési algoritmus. A funkcionális paradigma segítségével való megvalósítása tömören [a] így írható le:
# A rendezett üres lista üres lista. több gyors rendezés ([]) { () } # Ellenkező esetben vegye fel az első elemet pivotnak... több gyorsrendezés ([ $pivot , * @rest ]) { # Ossza fel az elemeket egy listára, amely # kisebb, mint a pivot és # nagyobb, mint a pivot. én @előtte = @pihenés . grep (* $pivot előtt ); my @after = @pihenés . grep (* a $pivot után ); # Rendezze ezeket az allistákat, és fűzze össze az eredményt. lapos ( gyorsrendezés ( @előtte ), $pivot , gyorsrendezés ( @utána )) }Ezt a rejtvényt gyakran használják a rekurzió bevezetésére a számítástechnikában . Ez a megvalósítás olyan multimetódusokat használ , amelyek egy literált 0 tartalmaznak a .
multi sub hanoi ( 0 , $, $, $) { } # Nincs lemez. Nincs mit átvinni. több sub hanoi ( $n , $a = 'A' , $b = 'B' , $c = 'C' ) { # $n lemez és három rúd: A, B, C. hanoi $n - 1 , $ a , $c , $b ; # Mozgassa ($n - 1) meghajtókat A-ból B-be, és mondja azt , hogy "Move $n drive from $a to $c." ; # Az utolsó lemez áthelyezése A-ból C-be. hanoi $n - 1 , $b , $a , $c ; # Helyezzen át ($n - 1) lemezt B-ből C-be. } hanoi ( 5 ); # Megoldás öt lemezre.Perl | |
---|---|
Emberek |
|
Dolgok | |
Keretrendszerek |
|
|