Raku (dříve Perl 6) | |
---|---|
Jazyková třída | Multi-paradigma |
Objevil se v | Vývoj probíhá od roku 2000. První vydání proběhlo 25. prosince 2015 |
Autor | Larry Wall |
Vývojář | Larry Wall a Audrey Tan |
Přípona souboru | .raku, .rakumod, .rakudoc, .rakutestnebo.t |
Uvolnění | 6.d (24. února 2020 ) |
Typový systém | dynamický, statický |
Byl ovlivněn |
haskell , JavaScript , Perl , Ruby , Smalltalk , J |
ovlivnil | Perl , Haskell , AntLang |
Licence | GNU General Public License , umělecká licence |
webová stránka | raku.org |
OS | multiplatformní |
Raku (z japonštiny 楽土, pron. rakudo - ráj , [1] [2] az 楽, pron. raku - štěstí, pohoda, sukha [3] [4] ) je programovací jazyk z rodiny jazyků podobných Perlu . . Zásadní přepracování návrhu i implementace jazyka Perl, prolomení zpětné kompatibility s ním, ačkoli režim kompatibility měl stále existovat až do roku 2010. [5]
Stejně jako jazyk Perl ponechává Raku programátorům velkou volnost . Stále vám umožňuje stručně se vyjádřit, včetně psaní jednoduchých řádků, ale také zjednodušuje psaní velkých programů díky statickému psaní a vylepšené podpoře OOP .
Rakuovo dřívější jméno bylo Perl 6. [6] Po mnoho let se v Perlské komunitě kolovaly vtipy o datu vydání. Na otázku „kdy Perl 6 vyjde“ byla obvyklá odpověď „o Vánocích“, ale bez roku. [7] [8] V roce 2015, tedy po patnácti letech čekání, byla konečně oznámena tzv. „vánoční“ verze. [9] [10] [11]
V Perlu 6 jsme se rozhodli, že je lepší opravit jazyk než opravit uživatele.Larry Wall [12]
Vývoj Perlu 6 byl poprvé oznámen Larrym Wallem 19. července 2000, čtvrtý den konference v Perlu, [13] ve svém State of the Onion talk . [14] V té době byly priority: odstranit z jazyka „historické bradavice“; „jednoduché věci musí zůstat jednoduché, složité věci se musí stát jednoduššími a nemožné věci se musí stát složitými“; generální čištění vnitřního designu a API . Proces začal sérií RFC . Tento proces byl otevřený všem účastníkům a žádný aspekt jazyka nebyl ponechán uzavřený, aby se mohl změnit. [patnáct]
Bylo přijato 361 žádostí, z nichž všechny byly přezkoumány Wallem. Poté začal psát několik „Apokalyps“, což je křesťanský termín, který znamená „odhalování dobré zprávy dobrým lidem“. [16] Přestože původním cílem bylo napsat jednu Apokalypsu pro každou kapitolu knihy en:Programming Perl , ukázalo se, že jak byla každá Apokalypsa napsána, předchozí Apokalypsy byly potlačeny pozdějšími změnami. Z tohoto důvodu byla vydána sada Synopsí, z nichž každá odkazuje na jednu Apokalypsu, ale obsahuje opravy z nových Apokalyps. Dnes je specifikace Raku řízena "pečenou" testovací sadou [17] , zatímco Synopses jsou zachovány jako historické reference. [osmnáct]
Existuje také série Exegesis napsaná Damianem Conwayem , která vysvětluje obsah každé Apokalypsy z hlediska praktického použití. Každá Exegesis se skládá z příkladů kódu s diskusí o jejich použití a významu. [19]
Hlavním cílem, který Wall navrhl ve svém původním projevu, bylo odstranění „historických bradavic“. Ty zahrnovaly zmatek v sigilech polí a hashů, nejednoznačnost ve funkcích select, problémy s použitím holých [20] (bez interpunkce [21] ) deskriptorů souborů. Wall ve svém projevu zmínil i mnoho dalších problémů, o kterých programátoři v Perlu diskutovali už léta.
Důsledkem těchto cílů byla ztráta zpětné kompatibility. Vzhledem k tomu, že zpětná kompatibilita je obvykle implikována při vylepšení softwaru, měly být výslovně uvedeny změny v Perlu 6, které ji porušují. Postupně byl rozdíl mezi Perlem 5 a Perlem 6 tak velký, že Perl 6 byl 12. října 2019 přejmenován na Raku . [6]
V průběhu let se vývojový vektor Raku několikrát změnil. Zavedení konceptů z Pythonu a Ruby bylo raným vlivem. [22] [23] [24] Kromě toho je Pugs, první interpret Raku, napsán ve funkcionálním jazyce Haskell a mnoho prvků funkcionálního programování bylo pohlceno vývojovým týmem Raku. [25] [26]
Maskotem jazyka je hmyz Camellia. [27] Jeho název je odkazem na znak jazyka Perl, velblouda ("Camel"), a jeho tvar, v tradici perlské komunity milující slovní hříčku , odráží slovo " chyba ". Spirálové vzory vepsané do jeho motýlovitých křídel připomínají znaky „P6“ a rozbíhající se šilhání je záměrná hříčka na „Wall-eyed“. [28]
Jedním z cílů živého a barevného designu loga bylo odradit od misogynie v komunitě a umožnit lidem s „mužským přesvědčením“ ukázat svou citlivou stránku. [29]
Rakudo je nejrozvinutější implementací, [30] což z něj nedělá oficiální verzi jazyka, as jazyk není definován implementací, ale testovací sadou. [31]
Rakudo vám umožňuje spouštět [32] kód na virtuálních strojích MoarVM , JVM a Node.js. [33] MoarVM je virtuální stroj vytvořený speciálně pro Rakudo a kompilátor NQP. [34] [35] Kompilátor NQP (Not Quite Perl 6 ) implementuje podmnožinu jazyka, která zahrnuje pravidla Raku pro analýzu zdrojového kódu, manipulaci se stromem abstraktní syntaxe a generování kódu specifického pro backend . Velká část Rakudo je napsána v Raku a NQP. Rakudo není samostatný kompilátor a v tuto chvíli nejsou žádné plány na propagaci kompilátoru .
Po verzi "2015.02" Rakudo upustilo od podpory virtuálního stroje Parrot [36] (předchůdce MoarVM), postaveného na mylném předpokladu, že Perl 6 bude podobný Perlu 5. [37] [38]
První implementací Raku byl Pugs [39] , interpret a kompilátor napsaný v Haskell . Byla to nejpokročilejší implementace, nicméně od roku 2007 byly provedeny pouze minimální opravy, aby udržely krok s novými verzemi GHC , a od listopadu 2014 nejsou Pugs podporovány. [40] V srpnu 2006 Yichun Zhang rozdělil testovací soubory Pugs na fragmenty a připojil k nim příslušné odstavce Synapsi [41] [42] a v lednu 2008 byly tyto testy začleněny do oficiálních testů jazyka („pečený “). [43] [44] V únoru 2015 komunita prohlásila jazykové testy za specifikaci. [45]
Raku a Perl se zásadně liší, i když záměrem bylo ponechat Raku jako Perl. Většina změn má za cíl normalizovat jazyk tak, aby byl srozumitelnější pro začínající i zkušené programátory, a aby byly „jednoduché věci jednodušší a složité věci snadnější“.
Hlavním netechnickým rozdílem je, že Raku začalo jako specifikace. [31] To znamená, že Raku lze v případě potřeby znovu implementovat a také to, že programátoři nemusí číst zdrojový kód, aby získali plnou kontrolu nad některou z jeho funkcí. V případě jazyka Perl popisuje oficiální dokumentace pouze chování aktuálního interpreta. Jakékoli nesrovnalosti mezi dokumentací a implementací mohou mít za následek změnu jednoho nebo druhého, což je hnací silou pokračujícího vývoje a zlepšování verzí Perlu.
V Raku byl dynamický typový systém doplněn o statické typy . [46] Například:
my Int $i = 0 ; moje Krysa $r = 3,142 ; my Str $s = "Ahoj světe" ;Statické typy však zůstávají volitelné, takže programátoři mohou dělat většinu věcí bez explicitního určení typů.
moje $i = "25" + 10 ; # $i je 35V Perlu nemají podprogramy žádné formální parametry , i když je možná jednoduchá kontrola počtu a typů parametrů pomocí prototypů podprogramů. [47] Místo toho jsou skutečné parametry předané odkazem skryty za prvky pole @_v těle podprogramu.
V Raku se objevují skutečné formální parametry. [48] Například:
sub do_something ( Str $thing , Int $other ) { ... }Stejně jako v Perlu jsou v Raku parametry předávány odkazem, ale ve výchozím nastavení jsou v Raku konstantní , tzn. jejich hodnoty nelze měnit. Mohou být explicitně deklarovány, aby bylo možné změnit původní hodnotu ( is rw) nebo jako kopie ( is copy), což je ekvivalentní předávání hodnoty.
Způsoby předání parametrůExistují tři způsoby, jak předávat parametry v Raku: poziční, pojmenované a slurpy .
Poziční parametry jsou pouze uspořádaný seznam, jako ve většině programovacích jazyků. Dokonce i oni mohou být předáni v libovolném pořadí, pokud jsou uvedena jejich jména. Parametry, které lze předávat pouze jménem, jsou označeny symbolem :před značkou formálního parametru. Squishing parametrů je způsob, jak vytvořit proměnné funkce v Raku. Jsou označeny symbolem *před znakem formálního parametru. Slurpy hash zachytí pojmenované parametry, které nejsou uvedeny v deklaraci podprogramu, a pole slurpy zachytí následné poziční skutečné parametry.
V následujícím příkladu jsou přítomny všechny tři metody, včetně slurpy array.
sub somefunction ( $a , $b , : $c , : $d , * @e ) { ... } nějaká funkce ( 1 , 2 ,: d ( 3 ), 4 , 5 , 6 ); # $a=1, $b=2, $d=3, @e=(4,5,6)Poziční parametry jsou standardně povinné, pokud za názvem parametru nenásleduje otazník. Pojmenované výchozí parametry jsou na druhou stranu volitelné, pokud za jménem nenásleduje vykřičník. Squishy parametry jsou vždy volitelné.
Bloky a uzávěryParametry lze také předat libovolným blokům kódu, které se chovají jako uzávěry . Zejména např. tělesa cyklů forjsou whileuzávěry. V následujícím příkladu smyčka vezme tři prvky ze seznamu najednou a předá je bloku jako proměnné $a, $ba $c. [49]
pro @list -> $a , $b , $c { ... }Toto se nazývá „pointy sub“ nebo „pointy block“ a šipka v něm se chová poněkud jako klíčové slovo sub, které představuje anonymní uzavření (nebo anonymní podprogram v terminologii Perlu). [48]
V Perlu se sigily (interpunkční znaménka, která se objevují před názvy proměnných) mění v závislosti na tom, jak se proměnná používá .
# Kód Perl moje pole @ = ('a', 'b', 'c'); můj $element = $ pole[1]; # vrátí 'b', můj @extrakt = @pole [ 1, 2]; # návratů ('b', 'c') můj $element = @array [1]; # vrátí 'b' s varováním (od 5.10)V Raku jsou sigila invariantní: pole i prvek pole budou mít stejné sigil. [46]
# kód Raku moje @ pole = 'a', 'b', 'c'; můj $element = @array [1]; # $element se píše 'b' můj @extrakt = @pole [ 1]; # je napsáno @extrakt ('b') můj @extrakt = @pole [ 1, 2]; # je napsáno @extrakt ('b', 'c')Variabilita sigil v Perlu je inspirována číselnou konvencí v angličtině a mnoha dalších přirozených jazycích .
" Je to jablko." # $a je pravda " Tato jablka." # @pravda " Toto je třetí jablko." # $a[3] je pravda " Tohle jsou třetí jablka." # @a[3] není správnéTento koncept je však narušen, když do hry vstupují odkazy, protože mohou odkazovat na datové struktury, zatímco jsou skalární. Práce s vnořenými datovými strukturami tedy může vyžadovat, aby bylo jednotné i množné číslo vyjádřeno stejným termínem:
# Kód Perl: získání pole z prvku hash. # Tento hash ukládá hash obsahující pole. my @trans_verbs = @ { $dictionary { 'sloveso' }{ 'tranzitivní' } };Takové konstrukce nemají v běžných přirozených jazycích obdoby, což způsobuje vysokou kognitivní zátěž při psaní kódu. Stejný kód Raku:
# Raku kód: získání pole z hash prvku. # Tento hash ukládá hash obsahující pole. my @trans_verbs = %slovnik<verb><tranzitiv><> ;V jazyce Perl je objektově orientované programování podporováno prostřednictvím funkce , která mění libovolnou proměnnou na objekt určité třídy, ze které se stanou metody deklarované ve třídě blessdostupné pro volání . [padesáti]
I když je tento mechanismus extrémně výkonný, zároveň ztěžuje popis i těch nejzákladnějších OOP - jednoduchých struktur podobných objektů s přidruženými procedurami. Také, protože Perl nečiní žádné předpoklady o objektovém modelu, volání metod nemůže být optimalizováno kompilátorem.
Raku zachovává nízkoúrovňovou metodu bless, ale také poskytuje restriktivnější objektový model pro běžné případy použití. [51] [52] Například třídu, která zapouzdřuje bod v kartézském souřadnicovém systému, lze definovat takto:
class Bod je rw { has $.x ; má $.y ; vzdálenost metody ( Bod $p ) { sqrt (( $!x - $p . x ) ** 2 + ( $!y - $p . y ) ** 2 ) } metoda distance-to-center { self . vzdálenost: Bod . nové ( x => 0 , y => 0 ) } } můj $bod = Bod . nové ( x => 1,2 , y => - 3,7 ); řekněte "Pozice bodu: (" , $bod . x , ', ' , $bod . y , ')' ; # Pozice bodu: (1,2, -3,7) # Změňte x a y (pomocí metod "x" a "y"): $point . x = 3 ; $bod . y = 4 ; řekněte "Pozice bodu: (" , $bod . x , ', ' , $bod . y , ')' ; # Pozice bodu: (3, 4) my $other-point = Point . nové ( x => -5 , y => 10 ); $bod . vzdálenost ( $other-point ); #=> 10 $ bodu . vzdálenost ke středu ; #=> 5V Perlu se metody vyvolávají pomocí šipky: $object->method(). Raku používá místo šipky tečku jako mnoho jiných jazyků (jako Java a Python).
V terminologii Raku se tomu $.xříká atribut. Metoda používaná pro přístup k atributu se nazývá přístupový objekt [53] (z anglického access - access). Je vytvořen automaticky (když je atribut deklarován tečkou [54] ) a jmenuje se stejně jako atribut. Funguje jako getter a když třída nebo atribut is rwpřevezme vlastnosti nastavovače a lze je použít na levé straně úkolu. Namísto automatických přístupových objektů může programátor definovat své vlastní uživatelské metody. Také v těle třídy lze ke všem atributům, bez ohledu na to, jak jsou deklarovány, přistupovat přímo pomocí $!.
Dědičnost, role a třídyDědičnost je technika, ve které objekty nebo typy znovu používají logiku nebo definice z jiných objektů nebo typů. Programátor může například vytvořit standardní typ s volitelným atributem. V jazycích, jako je Java, je dědičnost poskytována třídami, které mohou být podtřídami jiných existujících tříd.
Raku také poskytuje dědičnost prostřednictvím tříd, podobně jako třídy v jiných programovacích jazycích, a také prostřednictvím rolí.
Role v Raku přebírají funkci rozhraní v Javě, mixiny v Ruby, vlastnosti [55] v PHP a Squeak (dialekt jazyka Smalltalk ). Jsou podobné třídám, ale poskytují bezpečnější mechanismus složení než dědičnost, který zabraňuje konfliktům názvů atributů a metod. [56] [57] Role nejsou zabudovány do dědičného řetězce. Role se týkají systému jmenovitého typu (viz en: Systém jmenovitého typu ), nikoli systému konstrukčního typu, který se používá například v Go . Poskytují sémantická jména pro množiny chování a stavů. Základní rozdíl mezi rolemi a třídami je v tom, že role nevytvářejí instanci objektů. [58]
Přestože se role liší od tříd, je možné napsat kód, který vytvoří objekt z role. Pokus o použití role k vytvoření objektu povede k vytvoření třídy se stejným názvem. Dokumentace Raku nazývá tento mechanismus automatickým hraním rolí. vygenerovaná třída je slovní hříčka. [59]
Role jsou v podstatě svazky atributů a potenciálně abstraktních metod, které lze přidat do třídy bez použití dědičnosti. Roli lze dokonce přidat k jednomu objektu. V druhém případě Raku vytvoří anonymní podtřídu, přidá k ní roli a nahradí třídu objektu touto anonymní podtřídou.
Například pes je savec , protože psi dědí od savců určité vlastnosti, jako jsou mléčné žlázy a prostřednictvím svých předků obratlovců páteř . Na druhou stranu, psi mohou mít různé typy chování, které se mohou v průběhu času měnit. Pes může být například domácí, toulavý, průvodce . Tyto sady doplňkového chování lze psovi přidat. Můžete je popsat tak, abyste je mohli aplikovat na jiná zvířata. Například kočka může být domácí a toulavá. Pes a kočka se od sebe liší, ale zůstávají v obecné kategorii savců. Takže Млекопитающее je třída Собакаa Кошка jsou třídy zděděné od savce. Ale výše uvedená chování jsou role, které lze přidat do tříd nebo objektů vytvořených z tříd.
třída Savec je obratlovec { ... } třída Pes je savec { ... } role mazlíček { ... } role bezdomovec { ... } průvodce rolí { ... }Role se do tříd a objektů přidávají pomocí does. Pro dědění se používá klíčové slovo is. Tato slova odrážejí rozdíl ve smyslu těchto jazykových rysů: připojení role dává třídě chování role, ale neznamená, že se třída stává doslova stejnou jako tato role.
třída Vodicí pes je vodicí pes dělá vodícího psa { ... } # Podtřída připojí roli. můj $pes = Pes . nový (); $pes dělá vodícího psa ; # Objekt připojí roli.Role i třídy jsou typy. V deklaraci proměnné lze použít roli. Role Незрячийmůže například obsahovat atribut typu Поводырь, což může být vodicí pes, vodicí kůň, vodící osoba nebo dokonce vodicí vůz.
class Člověk { má Pes $pes ; # Může obsahovat jakýkoli druh psa - ... # nezáleží na tom, zda je to vodicí pes nebo ne. } role Blind { has Guide $guide ; # Může obsahovat jakýkoli předmět s rolí ... # Průvodce - bez ohledu na to, zda je to pes nebo ne. }Regulární výrazy a manipulace s řetězci byly vždy jednou z definujících vlastností Perlu. [60] Protože vzory Perlu v určitém okamžiku překonaly regulární výrazy, [61] dokumentace Raku je jednoduše označuje jako regexy , čímž se distancuje od formální definice regulárních výrazů.
Raku rozšiřuje sadu funkcí Perlu kolem regulárních výrazů tím, že je vnořuje do většího rámce pro vytváření analyzátorů nazývaných rules . [62] Pravidla poskytují možnosti kontextově citlivé analýzy (jako je syntaktický predikát z PEG a ANTLR ) a chovají se jako uzávěry o svých lexikálních rozsahech . [63] Pravidla se zadávají pomocí klíčového slova rule, což je podobné použití jako při definování podprogramu. Anonymní pravidla lze zadat pomocí klíčového slova regex(nebo ) rxnebo je lze popsat jako regulární výrazy v Perlu pomocí operátorů m(match) nebo s(nahradit).
Larry Wall v Apocalypse 5 vyjmenovává 20 problémů se současnou „kulturou regexů“. Regulární výrazy v Perlu byly mimo jiné „příliš kompaktní a „roztomilé“, „příliš se spoléhaly na příliš málo speciálních znaků“, měly „špatnou podporu pojmenovaného zachycení“, „slabou podporu gramatiky“ a „špatnou integraci jazyka“ ". [64]
Některé perlové konstrukty v Raku byly změněny a optimalizovány pro jiné syntaktické výrazy. Například závorky, které byly vyžadovány v příkazech provedení příkazu , jsou nyní volitelné. [49]
if is-true () { for @array { ... } }Operátor ,(čárka) je nyní konstruktorem seznamu, takže závorky kolem seznamů nejsou povinné.
@pole = 1 , 2 , 3 , 4 ;Raku umožňuje následující výrazy:
if 20 <= $teplota <= 25 { say "Teplota v místnosti je mezi 20 a 25 stupni!" }To je vnímáno jako sekvenční srovnání zleva doprava, po nichž následuje spojení pomocí logického AND .
Raku používá techniku hodnocení líného seznamu podobnou některým funkčním jazykům, jako je Haskell : [65]
@integers = 0 .. inf ; # celých čísel od nuly do nekonečnaTento kód nevyvolá chybu při pokusu vložit nekonečný seznam do pole @integersa nezasekne se při pokusu o neomezené rozšiřování seznamu, pokud je požadován konečný počet prvků.
To zjednodušuje mnoho běžných úloh v Raku, včetně I/O operací, transformací seznamů a předávání parametrů.
Je také možné vytvořit líné seznamy pomocí klíčových slov gathera take. Jsou podobné generátorům v Icon a Python .
moje $čtverce = líný sbírat za 0 .. Inf { vzít $_ * $_ ; };Zde $squaresje nekonečný seznam druhých mocnin přirozených čísel (včetně nuly), ale vzhledem k lenosti tohoto seznamu jsou prvky vyhodnoceny pouze tehdy, když se k nim přistupuje. [66]
Raku zavádí pojem junctions [67] ( angl. junction - spojení, průnik; v Raku tento termín souvisí i se spojením a disjunkcí [65] ). Jde o superpozici několika hodnot. [65] Ve své nejjednodušší podobě je křižovatka vytvořena operátory křižovatky :
# Příklad typového křížení | ("libovolná"): my $color = 'bílá' ; pokud $color eq 'bílá' | 'černý' | 'grey' { die "Tisk v této barvě není podporován.\n" ; } # Příklad křížku jako & ("vše"): my $password = 'secret!123' ; if $password ~~ /<:alpha>/ & / <:digit> / & / <:punct> / { řekni "Vaše heslo je dostatečně silné." ; }Operátor |vyjadřuje hodnotu rovnou levému nebo pravému argumentu, operátor & - levému i pravému. Tyto hodnoty lze v kódu použít všude tam, kde má být jedna hodnota sémanticky. Jakékoli operace s přejezdem působí současně na všechny jeho součásti a výsledek je slučován prostřednictvím provozovatele tohoto přejezdu. Ano, ("apple"|"banana") ~ "s"vrátí se "apples"|"bananas". V booleovském kontextu však křížky vrátí pouze jednu hodnotu, true nebo false: anyvrátí true, pokud je srovnání pravdivé pro alespoň jeden prvek; allvrátí hodnotu true, pokud je porovnání pravdivé pro všechny prvky. [68]
Pomocí křížení je možné rozšířit typový systém o nějakou formu obecného programování , které omezuje proměnné na typové kříže.
podmnožina Barva Any where RGB_Color | _ CMYK_Color ; sub get_tint ( Barva $color , Num $opacity ) { ... }Crossovery jsou speciální objekty, které rozdělují provádění kódu do potenciálně paralelních vláken . A jsou navrženy speciálně pro použití v booleovském kontextu: k jejich obsahu nemůžete přistupovat přímo, aniž byste je převedli na řetězec, který je odlišuje například od sad a jiných kolekcí. [68]
V nízkoúrovňových jazycích se makra stala synonymem pro nahrazování textu ve zdrojovém kódu kvůli asociaci s C preprocesorem . Nicméně v jazycích na vysoké úrovni, jako je Lisp , který předcházel C , byla makra výkonnější. [69] Byl to koncept maker podobný Lisp, kterého Raku využilo. [48] Síla tohoto typu maker je založena na provozování programu jako na vysokoúrovňové datové struktuře , nikoli jako textu, a na přístupu ke všem funkcím jazyka.
Definice makra v Raku vypadá jako definice podprogramu nebo metody. A takové makro může pracovat jak se zdrojovým kódem, tak s abstraktním stromem syntaxe a kombinací těchto dvou věcí.
makro ahoj ( $what ) { quasi { say "Ahoj {{{$what}}} }" }; }Ve výše uvedeném příkladu je argument makra analyzován před provedením makra, což vede k informativnějším diagnostickým zprávám kompilátoru. Protože však ke spuštění těla makra dochází v době kompilace (pro každý případ použití), lze použít širokou škálu optimalizačních technik . Pomocí maker je dokonce možné provést většinu práce některých programů ještě před jejich spuštěním .
V Raku mohou identifikátory kromě písmen, čísel a podtržítek obsahovat také apostrofy a pomlčky, pokud za nimi následují písmena. Písmena obsahují "odpovídající" (které závisí na implementaci) znaky Unicode , které jsou definovány v Rakudo a MoarVM jako všechny znaky Unicode kategorie "L". [70]
Použití pomlček místo podtržítek se nazývá „ kebab případ“. [71] [72] [73]
Metaoperátory jsou operátory, které mohou být parametrizovány jinými operátory, stejně jako funkce mohou brát jiné funkce jako parametry. [74]
Operátor metadat přiřazeníPerl zdědil operátory jazyka C jako +=, *=a tak dále. Raku je zobecňuje na meta operátor. Pro jakýkoli binární operátor opmůžeme napsat:
$x op = $y ; # nebo $x [op]= $yCo znamená:
$x = $x op $y ;Navíc to funguje i pro uživatelem definované operátory.
HyperoperátořiJsou podobné operátoru mapv Perlu. Přinutit operátory pracovat se všemi hodnotami pole. Lze použít pro binární i unární operátory. [75]
Například následující kód vytvoří pole obsahující všechny prvky pole @azvýšené o jednu:
můj @aPlusOne = @a "+" 1 ; # nebo @a >>+>> 1Směr lomených závorek ovlivňuje chování, když jsou jako parametry předávána pole různých délek. [75] Tyto „šipky“ ukazují, odkud pochází délka výsledku operace.
Příklad použití hyper operátoru s unárním operátorem:
moje @a = 1 , 2 , - 3 ; moje @b = -<< @a ; # [-1 -2 3]Hyperoperátory fungují nejen pro plochá pole, ale také pro vnořená pole. [76]
Operátor metadat redukceMetaoperátor redukce lze použít s jakýmkoli operátorem infix a převést jej na operátor redukce seznamu . Je to, jako by byl operátor aplikován na první dva prvky, poté na výslednou hodnotu a třetí prvek a tak dále, dokud nezůstane pouze jedna hodnota. Součet, součin, maximum, minimum atd. mohou fungovat jako operátor-parametr. Jedná se o extrémně výkonný mechanismus, který například převádí operátor +na operátor seznamového součtu, jako v příkladu níže.
řekni "Součet celých čísel od 0 do 99 je: " , [+] ^ 100 ; Křížový operátorChová se jako operátor i jako metaoperátor. [77]
Křížový operátor [75] najde přímý součin seznamů uspořádaných takovým způsobem, že výčet prvků z pravého operandu je rychlejší než z levého operandu, [77] vrací sekvenci seznamů:
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))Operátor meta sbalí interní seznamy pomocí operátoru parametru: [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 3bf 3cf 3ce 3ce Zip operátorZ angličtiny. zip - zip . [78]
Stejně jako křížový operátor kombinuje prvky seznamů [75] , ale vrací sekvenci obsahující nejprve první prvky každého seznamu, poté druhé prvky každého seznamu atd. [79]
<ab c> Z <1 2 3 4> ; # ((a 1) (b 2) (c 3)) 100 , 200 Z + 42 , 23 ; # (142 223) Inverzní operátoryOperátor meta R( eng. reversed ) umožňuje zaměnit argumenty původního operátoru.
řekněte "Jedna dělená třemi se rovná" , 3 R / 1 ; Vnoření meta-operátorůVýsledkem aplikace meta-operátora na operátora je další operátor, na který lze meta-operátor znovu aplikovat a tak dále. Pro zjednodušení syntaxe jsou povoleny hranaté závorky. [80]
moje @a = 1 , 2 , 3 ; moje @b = 5 , 6 , 7 ; @a >>>>> @b ; # Chyba analýzy. @a >>[>]>> @b ; # [False False False] # Zde je hyperoperátor >> >> aplikován na operátor porovnání. # Křížový meta-operátor platí # na operátor meta-přiřazení # parametrizovaný operátorem sčítání: @a X [+=] @b ; # (6 12 19 7 13 20 8 14 21) # Kvůli cross-meta operátoru bylo přiřazení provedeno # pro každý prvek pole @a s každým prvkem pole @b, # což je ekvivalentní přidání ke každému prvku pole @a # součtu prvků pole @b: řekněte [+] @b ; #18 řekni @a ; # [19 20 21]Stejně jako ostatní moderní jazyky je Raku navržen tak, aby podporoval souběžné a asynchronní programování.
Raku poskytuje jednoduché, modulární , vysokoúrovňové API pro psaní souběžného kódu, nezávisle na tom, jak virtuální stroj implementuje toto API. Kromě toho mohou některé jazykové funkce implicitně fungovat asynchronně. Aby byla zajištěna ovladatelnost a kompatibilita mezi těmito funkcemi, uživatelský kód by se měl pokud možno vyvarovat použití nízkoúrovňových rozhraní ( vlákna , plánovače, zámky ). [81]
Promises [82] [83] jsou centrálním mechanismem na vysoké úrovni , což jsou výsledky výpočtů získaných před jejich skutečným dokončením. Mohou být dány, provedeny a porušovány. Mají tedy tři možné stavy. Síla tohoto mechanismu spočívá ve schopnosti je kombinovat a spojovat do řetězců:
můj $p1 = Slib . nový (); můj $p2 = $p1 . then ({ řekni "Výsledek druhého slibu." });Zde thenzajišťuje provedení $p2až po provedení $p1.
Nechybí ani angličtina. Dodávky ("zásoby") a eng. Dodavatelé ("dodavatelé") - mechanismus pro vytváření asynchronních datových toků s možností zpracovat každou zprávu více příjemci najednou, podobně jako v jiných programovacích jazycích fungují obsluhy událostí. [81] Tento mechanismus lze použít pro programování řízené událostmi .
A konečně, kanály ( English Channels ) jsou vláknově bezpečné fronty FIFO , podobné pojmenovaným kanálům v operačních systémech, ale fungující v rámci aktuálního procesu. Klíčový rozdíl je v tom, že čtení z roury je dequeue, [81] tj. jednu hodnotu lze číst pouze jednou. Supply
Program "Ahoj světe!" často se používá k demonstraci základní syntaxe jazyka. V Raku to vypadá takto:
řekni 'Ahoj, světe' ;I když samozřejmě existuje více způsobů, jak to vyjádřit. [84]
Faktorový výpočet , definovaný několika způsoby:
# Použití rekurze s konstrukcí "if-else". dílčí fakt ( UInt $n --> UInt ) { if $n == 0 { 1 } else { $n * fakt ( $n-1 ) } } # Použití rekurze s "if" # jako modifikátor výrazu. sub fact ( UInt $n --> UInt ) { return 1 if $n == 0 ; návrat $n * fakt ( $n-1 ); } # Použití rekurze s konstrukcí "when". dílčí fakt ( UInt $n --> UInt ) { when $n == 0 { 1 } default { $n * fact ( $n-1 ) } } # Použití ternárního operátoru. dílčí fakt ( UInt $n --> UInt ) { $n == 0 ?? 1 !! $n * fakt ( $n-1 ) } # Použití vícenásobného odeslání. více faktů ( 0 ) { 1 } více faktů ( UInt $ n --> UInt ) { $ n * fakt ( $ n - 1 ) } # Použití meta operátoru redukce. sub fact ( UInt $n --> UInt ) { [*] 1 .. $n } # Definice faktoriálního operátoru, # implementovaná přes metaoperátor redukce. sub postfix: <!>( UInt $n --> UInt ) { [*] 1 .. $n } # Použití klíčového slova "stav" pro zapamatování. sub fact ( UInt $n --> UInt ) { stav %známý = 0 => 1 ; return %known { $n } if %known { $n }: existuje ; %známé { $n } = $n * fakt ( $n-1 ); return %known { $n }; }QuickSort je známý třídicí algoritmus. Jeho implementaci pomocí funkčního paradigmatu lze stručně napsat [a] takto:
# Seřazený prázdný seznam je prázdný seznam. vícenásobné rychlé třídění ([]) { () } # Jinak vezměte první prvek jako pivot... multi quicksort ([ $pivot , * @rest ]) { # Rozdělte prvky na seznam těch # menších než pivot a těch # větších než pivot. můj @před = @odpočinek . grep (* před $pivot ); můj @po = @odpočinek . grep (* za $pivot ); # Seřaďte tyto dílčí seznamy a spojte výsledek. plochý ( quicksort ( @before ), $pivot , quicksort ( @after )) }Tato hádanka se často používá k zavedení rekurze v informatice . Tato implementace používá multimetody s literálem 0 jako součást .
multi sub hanoi ( 0 , $, $, $) { } # Žádné disky. Není co přenášet. multi sub hanoi ( $n , $a = 'A' , $b = 'B' , $c = 'C' ) { # $n disky a tři tyče: A, B, C. hanoi $n - 1 , $ a , $c , $b ; # Přesunout ($n - 1) jednotky z A do B řekněte "Přesunout jednotku $n z $a na $c." ; # Přesuňte poslední disk z A do C. hanoi $n - 1 , $b , $a , $c ; # Přesuňte ($n - 1) disky z B do C. } Hanoj ( 5 ); # Řešení pro pět disků.Perl | |
---|---|
Lidé |
|
Věci | |
Rámce |
|
|