Raku (programmeringsspråk) - Raku (programming language)

Raku
Camelia.svg
Camelia, Raku -maskoten
Paradigme Multiparadigme
Familie Perl
Designet av Larry Wall
Utvikler Raku -samfunnet
Første gang dukket opp 25. desember 2015 ; 5 år siden ( 2015-12-25 )
Stabil utgivelse
6.d 'Diwali' / 24. oktober 2020 ; 11 måneder siden ( 2020-10-24 )
Skrive disiplin Dynamisk , gradvis
OS Kryssplattform
Tillatelse GNU General Public License eller Artistic License 2
Filnavnutvidelser .p6, .pm6, .pod6, .t6, .raku, .rakumod, .rakudoc, .rakutest
Nettsted raku .org
Store implementeringer
Rakudo
Påvirket av
Perl , Ruby , Smalltalk , Haskell , JavaScript
Påvirket
Perl , Haskell , AntLang

Raku er medlem av Perl -familien av programmeringsspråk . Tidligere kjent som Perl 6 , ble det omdøpt i oktober 2019. Raku introduserer elementer fra mange moderne og historiske språk. Kompatibilitet med Perl var ikke et mål, selv om kompatibilitetsmodus er en del av spesifikasjonen. Designprosessen for Raku begynte i 2000.

Historie

I Perl 6 bestemte vi oss for at det ville være bedre å fikse språket enn å fikse brukeren.

-  Larry Wall

Raku -designprosessen ble først kunngjort 19. juli 2000, på den fjerde dagen i årets Perl -konferanse , av Larry Wall i sitt State of the Onion 2000 -foredrag. På den tiden var hovedmålene å fjerne "historiske vorter" fra språket; "enkle ting skal forbli enkle, harde ting skal bli enklere, og umulige ting skal bli harde"; en generell opprydding av det interne designet og API -ene . Prosessen begynte med en rekke forespørsler om kommentarer eller "RFC". Denne prosessen var åpen for alle bidragsytere, og etterlot ingen sider ved språket stengt for endring.

Når RFC -prosessen var fullført, gjennomgikk og klassifiserte Wall hver forespørsel (361 ble mottatt). Deretter begynte han prosessen med å skrive flere "Apokalypser", ved å bruke den opprinnelige betydningen av begrepet "avslørende". Selv om det opprinnelige målet var å skrive en apokalypse for hvert kapittel i Programming Perl , ble det åpenbart at etter hvert som hver apokalypse ble skrevet, ble tidligere apokalypser ugyldiggjort av senere endringer. Av denne grunn ble det publisert et sett med synopser, som hver relaterte innholdet i en apokalypse, men med senere endringer gjenspeilet i oppdateringer. I dag administreres Raku -spesifikasjonen gjennom "stek" -testpakken, mens synopsene beholdes som en historisk referanse.

Det er også en serie eksegeser skrevet av Damian Conway som forklarer innholdet i hver apokalypse når det gjelder praktisk bruk. Hver eksegese består av kodeeksempler sammen med diskusjon av bruken og implikasjonene av eksemplene.

Det er tre primære kommunikasjonsmetoder som brukes i utviklingen av Raku i dag. Den første er raku IRC -kanalenLibera Chat . Den andre er et sett med adresselisterThe Perl Foundation sine servere på perl.org . Den tredje er Git -kildekodelageret som ligger på https://github.com/raku .

Innledende mål og implikasjoner

Det viktigste målet Wall foreslo i sin første tale var fjerning av historiske vorter. Disse inkluderte forvirringen rundt sigilbruk for containere, tvetydigheten mellom selectfunksjonene og den syntaktiske virkningen av bareword -filhåndteringer. Det var mange andre problemer som Perl -programmerere hadde diskutert å fikse i årevis som Wall eksplisitt tok opp i sin tale.

En implikasjon av disse målene var at Perl 6 ikke ville ha bakoverkompatibilitet med den eksisterende Perl -kodebasen. Dette betydde at noen kode som ble tolket riktig av en Perl 5 -kompilator ikke ville bli akseptert av en Perl 6 -kompilator. Siden bakoverkompatibilitet er et vanlig mål for forbedring av programvare, må endringene i Perl 6 eksplisitt angis. Skillet mellom Perl 5 og Perl 6 ble så stort at til slutt ble Perl 6 omdøpt til Raku.

Gjennom årene har Raku gjennomgått flere endringer i retning. Innføringen av konsepter fra Python og Ruby var tidlig påvirkning. Siden Pugs - den første tolken som kunne kjøre Raku - ble skrevet på Haskell programmeringsspråk , ble mange funksjonelle programmeringspåvirkninger absorbert av Raku designteam.

Maskot

Larry Wall og Camelia

Språkets maskot er "Camelia, den Raku bug". Navnet hennes nikker til kamelmaskoten knyttet til Perl , og formen hennes, i ordspill-elskende tradisjon i Perl-samfunnet, er et skuespill om " programvarefeil ". Spiraldesigner som er innebygd i hennes sommerfugllignende vinger, ligner karakterene "P6", det foretrukne kallenavnet for Perl 6, og øyemålingen utenfor midten er en forsettlig ordspill på "Wall-eyed".

Et av målene bak den livlige og fargerike utformingen av logoen var å motvirke misogyni i samfunnet og at det skulle være en mulighet for de av "maskulin overtalelse" til å vise sin sensitive side.

Implementeringer

Fra og med 2017 er bare Rakudo -implementeringen under aktiv utvikling. Ingen implementering vil bli utpekt som den offisielle Raku -implementeringen; heller, "Raku er alt som består den offisielle testsuiten."

Rakudo Perl 6 retter seg mot en rekke virtuelle maskiner, for eksempel MoarVM , Java Virtual Machine og JavaScript . MoarVM er en virtuell maskin bygget spesielt for Rakudo og NQP Compiler Toolchain. Det er et lag mellom Raku og de virtuelle maskinene kalt Not Quite Perl 6, eller NQP, som implementerer Raku-regler for analyse av Raku, i tillegg til et abstrakt syntaks-tre og backend-spesifikk kodegenerering . Store deler av Rakudo er skrevet i selve Raku, eller i undersettet NQP. Rakudo er ikke en helt selvlagrende gjennomføring , eller er det konkrete planer på dette punktet for å gjøre Rakudo en bootstrapping kompilatoren.

Historiske implementeringer

Pugs var en første implementering av Perl 6 skrevet i Haskell . Pugs pleide å være den mest avanserte implementeringen av Perl 6, men siden midten av 2007 er den stort sett sovende (med oppdateringer bare for å spore den nåværende versjonen av GHC ). Fra november 2014 ble Pugs ikke aktivt vedlikeholdt.

I 2007 ble v6-MiniPerl6 ("mp6") og dens reimplementering, v6-KindaPerl6 ("kp6") skrevet som et middel for å bootstrap Perl-6.0.0 STD, ved hjelp av Perl 5. STD er en full grammatikk for Perl 6 og er skrevet i Perl 6. I teorien er alt som er i stand til å analysere STD og generere kjørbar kode et passende bootstrapping -system for Perl 6. kp6 er for øyeblikket kompilert av mp6 og kan fungere med flere backends. mp6 og kp6 er ikke fulle Perl 6 -implementeringer og er kun designet for å implementere minimumssettet som kreves for å starte en full Perl 6 -kompilator.

Yapsi var en Perl 6 -kompilator og kjøretid skrevet i Perl 6 selv. Som et resultat krevde det en eksisterende Perl 6 -tolk, for eksempel en av Rakudo Star -utgivelsene, for å kjøre.

Niecza, en annen stor Perl 6 -implementeringsinnsats, fokuserte på optimalisering og effektiv implementeringsforskning. Den er rettet mot felles språkinfrastruktur .

Modulsystem

Raku -spesifikasjonen ber om at modulene identifiseres med navn, versjon og autoritet. Det er mulig å bare laste inn en bestemt versjon av en modul, eller til og med to moduler med samme navn som er forskjellige i versjon eller autoritet. Som en bekvemmelighet tilbys aliasing til et kort navn.

CPAN , Perl -modulens distribusjonssystem, håndterer ennå ikke Raku -moduler. I stedet er et prototypemodulsystem i bruk.

Store endringer fra Perl

Perl og Raku er fundamentalt forskjellige, men generelt har intensjonen vært å "beholde Raku Perl", slik at Raku tydeligvis er "et Perl -programmeringsspråk". De fleste endringene er ment å normalisere språket, gjøre det lettere for både nybegynnere og eksperter å forstå, og å gjøre "enkle ting lettere og vanskelige ting mer mulig".

En spesifikasjon

En stor ikke-teknisk forskjell mellom Perl og Raku er at Raku begynte som en spesifikasjon. Dette betyr at Raku kan implementeres på nytt om nødvendig, og det betyr også at programmerere ikke trenger å lese kildekoden for den ultimate autoriteten på en gitt funksjon. Den offisielle dokumentasjonen anses ikke som autoritativ og beskriver bare oppførselen til den faktiske Perl -tolken uformelt. Eventuelle avvik mellom dokumentasjonen og implementeringen kan føre til at de enten endres for å gjenspeile den andre, en dynamikk som driver den videre utviklingen og foredlingen av Perl -utgivelsene.

Et typesystem

I Raku har det dynamiske typesystemet til Perl blitt forsterket med tillegg av statiske typer . For eksempel:

my Int $i = 0;
my Rat $r = 3.142;
my Str $s = "Hello, world";

Imidlertid er statisk skriving fortsatt valgfritt , så programmerere kan gjøre det meste uten eksplisitt å skrive i det hele tatt:

my $i = "25" + 10; # $i is 35

Raku tilbyr et gradvis skrivesystem , der programmereren kan velge å bruke statisk skriving, bruke dynamisk skriving eller blande de to.

Formelle lister over subrutiner

Perl definerer subrutiner uten formelle parameterlister i det hele tatt (selv om enkel parametertelling og noen veldig løse typekontroller kan utføres ved hjelp av Perls "prototyper"). Subrutine -argumenter som sendes inn, aliases til elementene i matrisen @_ . Hvis elementene i @_ endres, gjenspeiles endringene i de originale dataene.

Raku introduserer sanne formelle parametere for språket. I Raku ser en underprogrammerklæring slik ut:

sub do_something(Str $thing, Int $other) {
    ...
}

Som i Perl, er de formelle parametrene (dvs. variablene i parameterlisten) aliaser til de faktiske parameterne (verdiene som sendes inn), men som standard er aliasene konstante, slik at de ikke kan endres. De kan erklæres eksplisitt som lese-skrive-alias for den opprinnelige verdien eller som kopier ved hjelp av henholdsvis is rweller is copy-direktivene hvis programmereren krever at de endres lokalt.

Parameter bestått moduser

Raku tilbyr tre grunnleggende parametere for passering: posisjonelle parametere, navngitte parametere og slurpy -parametere.

Posisjonsparametere er den typiske ordnede listen over parametere som de fleste programmeringsspråk bruker. Alle parametere kan også passeres ved å bruke navnet deres på en uordnet måte. Bare navngitte parametere (angitt med a :før parameternavnet) kan bare sendes ved å angi navnet, det vil si at den aldri fanger et posisjonsargument. Slurpy -parametere (angitt med et *før parameternavnet) er Rakus verktøy for å lage variadiske funksjoner . En slurpy hash vil registrere gjenværende parametere for pass-by-name, mens en slurpy array vil fange gjenværende parametere som er passert-by-position.

Her er et eksempel på bruk av alle tre parameterpasseringsmodusene:

sub somefunction($a, $b, :$c, :$d, *@e) {
    ...
}

somefunction(1, 2, :d(3), 4, 5, 6); # $a=1, $b=2, $d=3, @e=(4,5,6)

Posisjonsparametere, som de som er brukt ovenfor, er alltid påkrevd med mindre de følges av for ?å indikere at de er valgfrie. Navngitte parametere er valgfrie som standard, men kan merkes som nødvendig ved å legge til !etter variabelnavnet. Slurpy -parametere er alltid valgfrie.

Blokker og nedleggelser

Parametere kan også overføres til vilkårlige blokker, som fungerer som nedleggelser . Dette er hvordan, for eksempel, forog whileer sløyfe iteratorer navngitt. I det følgende eksempel er en liste løpes, 3-elementer på en gang, og føres til loop blokk som variablene $a, $b, $c.

for @list -> $a, $b, $c {
    ...
}

Dette blir vanligvis referert til som en "spiss sub" eller "spiss blokk", og pilen oppfører seg nesten akkurat som subsøkeordet, og introduserer en anonym nedleggelse (eller anonym subrutine i Perl -terminologi).

Sigil uforanderlighet

I Perl endres sigiler - skilletegnene som går foran et variabelnavn - avhengig av hvordan variabelen brukes:

# Perl code
my @array = ('a', 'b', 'c');
my $element = $array[1];    # $element equals 'b',
my @extract = @array[1, 2]; # @extract equals ('b', 'c')
my $element = @array[1];    # 'b' comes with a warning (5.10 option)

I Raku er sigiler invariante, noe som betyr at de ikke endres basert på om det er matrisen eller matriseelementet som er nødvendig:

# Raku code
my @array = 'a', 'b', 'c';
my $element = @array[1];    # $element equals 'b'
my @extract = @array[1];    # @extract equals ('b')
my @extract = @array[1, 2]; # @extract equals ('b', 'c')

Variansen i Perl er inspirert av tallavtale på engelsk og mange andre naturspråk:

"This apple."                    # $a        CORRECT
"These apples."                  # @a        CORRECT
"This third apple."              # $a[3]     CORRECT
"These third apple."             # @a[3]     WRONG

Denne konseptuelle kartleggingen brytes imidlertid ned når referanser spiller inn, siden de kan referere til datastrukturer selv om de er skalarer. Dermed kan behandling av nestede datastrukturer kreve uttrykk for både entall og flertall i et enkelt begrep:

# Perl code: retrieve a list from the leaf of a hash containing hashes that contain arrays
my @trans_verbs = @{ $dictionary{ 'verb' }{ 'transitive' } };

Denne kompleksiteten har ingen tilsvarende verken ved vanlig bruk av naturlig språk eller i andre programmeringsspråk, og den forårsaker høy kognitiv belastning når du skriver kode for å manipulere komplekse datastrukturer. Dette er den samme koden i Raku:

# Raku code: retrieve a list from the leaf of a hash containing hashes that contain arrays
my @trans_verbs = %dictionary<verb><transitive><>;

Objektorientert programmering

Perl støtter objektorientert programmering via en mekanisme kjent som velsignelse . Enhver referanse kan velsignes til å være et objekt for en bestemt klasse. Et velsignet objekt kan få metoder påberopt på det ved hjelp av "pilsyntaksen" som vil føre til at Perl finner eller "sender" en passende underprogram med navn, og kaller det med den salige variabelen som sitt første argument.

Selv om det er ekstremt kraftig, gjør det det vanligste tilfellet av objektorientering, et strukturlignende objekt med noen tilknyttet kode, unødvendig vanskelig. I tillegg, fordi Perl ikke kan gjøre noen forutsetninger om objektmodellen som er i bruk, kan fremkalling av metode ikke optimaliseres veldig godt.

I ånden om å gjøre de "enkle tingene enkle og vanskelige tingene mulige", beholder Raku velsignelsesmodellen og leverer en mer robust objektmodell for vanlige saker. For eksempel kan en klasse for å innkapsle et kartesisk punkt defineres og brukes på denne måten:

class Point is rw {
    has $.x;
    has $.y;
    
    method distance( Point $p ) {
        sqrt(($!x - $p.x) ** 2 + ($!y - $p.y) ** 2)
    }
    
    method distance-to-center {
        self.distance: Point.new(x => 0, y => 0)
    }
}

my $point = Point.new( x => 1.2, y => -3.7 );
say "Point's location: (", $point.x, ', ', $point.y, ')';
# OUTPUT: Point's location: (1.2, -3.7)

# Changing x and y (note methods "x" and "y" used as lvalues):
$point.x = 3;
$point.y = 4;
say "Point's location: (", $point.x, ', ', $point.y, ')';
# OUTPUT: Point's location: (3, 4)

my $other-point = Point.new(x => -5, y => 10);
$point.distance($other-point); #=> 10
$point.distance-to-center;     #=> 5

Prikken erstatter pilen i et nikk til de mange andre språkene (f.eks. C ++ , Java , Python , etc.) som har samlet seg rundt prikken som syntaksen for metodeinnkallelse.

I terminologien til Raku $.xkalles det et "attributt". Noen språk kaller disse feltene eller medlemmene . Metoden som brukes for å få tilgang til et attributt kalles en "accessor". En metode for automatisk tilgang er en metode som er opprettet automatisk og oppkalt etter attributtets navn, slik metoden xer i eksemplet ovenfor. Disse accessor -funksjonene returnerer verdien av attributtet. Når en klasse eller et individuelt attributt deklareres med is rwmodifikatoren (forkortelse for "lese/skrive"), kan auto-accessorene sendes en ny verdi å sette attributtet til, eller det kan tilordnes direkte som en l-verdi (som i eksempelet). Auto-accessors kan erstattes av brukerdefinerte metoder, hvis programmereren ønsker et rikere grensesnitt til et attributt. Attributter kan bare nås direkte fra en klassedefinisjon via $!syntaksen, uavhengig av hvordan attributtene deklareres. All annen tilgang må gå gjennom tilgangsmetodene.

Raku -objektsystemet har inspirert Moose -rammeverket som introduserer mange av Rakus OOP -funksjoner for Perl.

Arv, roller og klasser

Arv er teknikken som et objekt eller en type kan gjenbruke kode eller definisjoner fra eksisterende objekter eller typer. For eksempel kan en programmerer ha en standardtype, men med et ekstra attributt. Arv på andre språk, for eksempel Java, er gitt ved å la klasser være underklasser av eksisterende klasser.

Raku sørger for arv via klasser, som ligner klasser på andre språk, og roller.

Roller i Raku tar på seg funksjonen til grensesnitt i Java , mixins i Ruby og egenskaper i PHP og i Smalltalk -varianten Squeak . Disse er omtrent som klasser, men de gir en sikrere sammensetningsmekanisme. Disse brukes til å utføre komposisjon når de brukes med klasser i stedet for å legge til i arvskjeden . Roller definerer nominelle typer; de gir semantiske navn for samlinger av atferd og tilstand. Den grunnleggende forskjellen mellom en rolle og en klasse er at klasser kan instantieres; roller er ikke.

Selv om roller er forskjellige fra klasser, er det mulig å skrive Raku -kode som direkte instanser en rolle eller bruker en rolle som et typeobjekt, vil Raku automatisk opprette en klasse med samme navn som rollen, noe som gjør det mulig å bruke en rolle transparent som om det var en klasse.

I hovedsak er en rolle en bunt med (muligens abstrakte) metoder og attributter som kan legges til en klasse uten å bruke arv. En rolle kan til og med legges til et individuelt objekt; i dette tilfellet vil Raku opprette en anonym underklasse, legge til rollen i underklassen og endre objektets klasse til den anonyme underklassen.

For eksempel er en hund et pattedyr fordi hunder arver visse egenskaper fra pattedyr, for eksempel brystkjertler og (gjennom pattedyrs forelder, virveldyr ) en ryggrad . På den annen side kan hunder også ha en av flere forskjellige typer oppførsel, og denne atferden kan endres over tid. For eksempel kan en hund være et kjæledyr , en herreløs (et forlatt kjæledyr vil oppnå atferd for å overleve uten tilknytning til et kjæledyr), eller en guide for blinde (førerhunder er opplært, slik at de ikke starter livet som førerhunder) . Dette er imidlertid sett med ytterligere atferd som kan legges til en hund. Det er også mulig å beskrive denne oppførselen på en slik måte at de kan brukes på andre dyr, for eksempel kan en katt like godt være et kjæledyr eller en villfarlig. Derfor er både hund og katt forskjellige fra hverandre, mens begge forblir innenfor den mer generelle kategorien Pattedyr. Så pattedyr er en klasse, og hund og katt er klasser som arver fra pattedyr. Men oppførselen knyttet til Pet, Stray og Guide er roller som kan legges til klasser, eller objekter som er installert fra klasser.

class Mammal is Vertebrate {
    ...
}
class Dog is Mammal {
    ...
}
role Pet {
    ...
}
role Stray {
    ...
}
role Guide {
    ...
}

Roller legges til i en klasse eller et objekt med doessøkeordet. For å vise arv fra en klasse, er det et annet søkeord is. Søkeordene gjenspeiler de forskjellige betydningene av de to funksjonene: rollesammensetning gir en klasse oppførselen til rollen, men indikerer ikke at det virkelig er det samme som rollen.

class GuideDog is Dog does Guide {
    ...
}   # Subclass composes role

my $dog = new Dog;
$dog does Guide;       # Individual object composes role

Selv om roller er forskjellige fra klasser, er begge typer, så en rolle kan vises i en variabel erklæring der man vanligvis ville plassert en klasse. For eksempel kan en blind rolle for et menneske inneholde et attributt av typen Guide; denne egenskapen kan inneholde en førerhund, en guidehest , et guide menneske eller til og med en guidemaskin.

class Human {
    has Dog $dog;      # Can contain any kind of Dog, whether it does the
    ...                # Guide role or not
}
role Blind {
    has Guide $guide;  # Can contain any object that does the Guide role,
    ...                # whether it is a Dog or something else
}

Vanlig uttrykk

Perls vanlige uttrykk og støtte for strengbehandling har alltid vært en av de definerende funksjonene. Siden Perls mønstermatchende konstruksjoner har overgått evnene til vanlige språkuttrykk en stund, vil Raku-dokumentasjon utelukkende referere til dem som regekser , og distansere begrepet fra den formelle definisjonen.

Raku gir et supersett av Perl-funksjoner med hensyn til regexes, og bretter dem inn i et større rammeverk som kalles " regler " som gir mulighetene for kontekstsensitive analyseringsformalismer (for eksempel de syntaktiske predikatene for analyse av uttrykks grammatikk og ANTLR ), samt handling som en avslutning med hensyn til deres leksikalske omfang . Regler blir introdusert med rulenøkkelordet som har en bruk som ligner ganske på underrutine -definisjon. Anonyme regler kan også introduseres for regex(eller rx) søkeordet, eller de kan ganske enkelt brukes inline som regexps var i Perl via m(matchende) eller s(substitutt) operatører.

I Apocalypse 5 regnet Larry Wall opp 20 problemer med "nåværende regex -kultur". Blant disse var at Perls regexes var "for kompakte og" søte "", hadde "for stor avhengighet av for få metategn", "lite støtte for navngitte fangster", "lite støtte for grammatikk" og "dårlig integrasjon med" ekte " Språk".

Syntaktisk forenkling

Noen Perl -konstruksjoner er endret i Raku, optimalisert for forskjellige syntaktiske tegn for de vanligste tilfellene. For eksempel er parentesene (runde parenteser ) som kreves i kontrollflytkonstruksjoner i Perl nå valgfrie:

if is-true() {
    for @array {
        ...
    }
}

Dessuten er ,(komma) -operatoren nå en listekonstruktør, så det er ikke lenger nødvendig med omsluttende parenteser rundt lister. Koden

@array = 1, 2, 3, 4;

lager nå @arrayen matrise med nøyaktig elementene '1', '2', '3' og '4'.

Kjedelige sammenligninger

Raku tillater sammenligninger med "kjede". Det vil si at en sekvens av sammenligninger som følgende er tillatt:

if 20 <= $temperature <= 25 {
    say "Room temperature is between 20 and 25!"
}

Dette behandles som om hver sammenligning fra venstre til høyre ble utført alene, og resultatet kombineres logisk via andoperasjonen.

Lat evaluering

Raku bruker teknikken for lat evaluering av lister som har vært et trekk ved noen funksjonelle programmeringsspråk som Haskell :

@integers = 0..Inf; # integers from 0 to infinity

Koden ovenfor krasjer ikke ved å prøve å tilordne en liste med uendelig størrelse til matrisen @integers, og den vil heller ikke henge på ubestemt tid i et forsøk på å utvide listen hvis et begrenset antall spor blir søkt.

Dette forenkler mange vanlige oppgaver i Raku, inkludert input/output -operasjoner, listetransformasjoner og parameteroverføring.

Samle

Relatert til lat evaluering er konstruksjonen av late lister som bruker gatherog takeoppfører seg litt som generatorer på språk som Icon eller Python .

my $squares = lazy gather for 0..Inf {
    take $_ * $_;
};

$squaresvil være en uendelig liste over kvadratnumre, men lat evaluering av gathersikrer at elementene bare blir beregnet når de er tilgjengelige.

Veikryss

Raku introduserer begrepet veikryss : verdier som er sammensetninger av andre verdier. I sin enkleste form er veikryss skapt ved å kombinere et sett av verdier med junctive operatører :

# Example for | ("any") Junction:
my $color = 'white';
unless $color eq 'white' | 'black' | 'gray' | 'grey' {
    die "Color printing not supported\n";
}

# Example for & ("all") Junction:
my $password = 'secret!123';
if $password ~~ /<:alpha>/ & /<:digit>/ & /<:punct>/ {
    say "Your password is reasonably secure";
}

|indikerer en verdi som er lik enten den til venstre eller til høyre for argumentene. &indikerer en verdi som er lik både venstre og høyre argument. Disse verdiene kan brukes i hvilken som helst kode som bruker en normal verdi. Operasjoner utført på et kryss virker på alle medlemmer av krysset likt, og kombineres i henhold til forbindelsesoperatøren. Så ("apple"|"banana") ~ "s"ville gi etter "apples"|"bananas". I sammenligninger returnerer veikryss et enkelt sant eller usant resultat for sammenligningen. " any" kryss returnerer sant hvis sammenligningen er sant for et av elementene i krysset. " all" kryss går tilbake sant hvis sammenligningen er sann for alle elementene i krysset.

Kryss kan også brukes til å forsterke typesystemet mer rikelig ved å introdusere en stil med generisk programmering som er begrenset til veikryss av typer:

subset Color of Any where RGB_Color | CMYK_Color;
sub get_tint(Color $color, Num $opacity) {
    ...
}

Makroer

På lavnivåspråk har makrobegrepet blitt synonymt med tekstlig substitusjon av kildekoden på grunn av den utbredte bruken av C-preprosessoren . Imidlertid daterte språk på høyt nivå som Lisp C på sin bruk av makroer som var langt kraftigere. Det er dette Lisp-lignende makrokonseptet som Raku vil dra fordel av. Kraften til denne typen makro stammer fra det faktum at den fungerer på programmet som en datastruktur på høyt nivå , i stedet for som enkel tekst, og har alle programmeringsspråkets evner til rådighet.

En makro-definisjon av Raku vil se ut som en subrutine eller metode definisjon, og den kan operere på ikke -analyserte strenger, en AST som representerer forhåndsanalysert kode eller en kombinasjon av de to. En makrodefinisjon vil se slik ut:

macro hello($what) {
    quasi { say "Hello { {{{$what}}} }" };
}

I dette eksemplet er makroen ikke mer kompleks enn en tekstlig substitusjon i C-stil, men fordi analysering av makroparameteren skjer før makroen opererer på ringekoden, ville diagnostiske meldinger være langt mer informative. Men fordi makroens kropp blir utført ved kompileringstidspunktet hver gang den brukes, kan mange optimaliseringsteknikker brukes. Det er til og med mulig å eliminere komplekse beregninger fra resulterende programmer ved å utføre arbeidet ved kompileringstid.

Identifikatorer

I Perl kan identifikatornavn bruke ASCII -alfanumerikken og understreker også tilgjengelig på andre språk. I Raku kan alfanumerikken inneholde de fleste Unicode -tegn. I tillegg kan bindestreker og apostrofer brukes (med visse begrensninger, for eksempel å ikke bli fulgt av et siffer). Å bruke bindestreker i stedet for understreker for å skille ord i et navn, fører til en navngivningsstil som kalles " kebab case ".

Eksempler

Hei Verden

Den Hello World-programmet er et felles program som brukes til å introdusere et språk. I Raku er hei verden:

say 'Hello, world';

- selv om det er mer enn én måte å gjøre det på .

Faktorisk

Den faktoriell funksjon i Raku, definert i et par forskjellige måter:

# Using recursion (with `if\else` construct)
sub fact( UInt $n --> UInt ) {
    if $n == 0 { 1 }
    else       { $n * fact($n-1) }
}

# Using recursion (with `if` as statement modifier)
sub fact( UInt $n --> UInt ) {
    return 1 if $n == 0;
    return $n * fact($n-1);
}

# Using recursion (with `when` construct)
sub fact( UInt $n --> UInt ) {
    when $n == 0 { 1 }
    default      { $n * fact($n-1) }
}

# Using the ternary operator
sub fact( UInt $n --> UInt ) {
    $n == 0 ?? 1 !! $n * fact($n-1)
}

# Using multiple dispatch
multi fact(0) { 1 }
multi fact( UInt $n --> UInt ) {
    $n * fact($n - 1)
}

# Using the reduction metaoperator
sub fact( UInt $n --> UInt ) {
    [*] 1..$n
}

# Creating a factorial operator and using the reduction metaoperator
sub postfix:<!>( UInt $n --> UInt ) { [*] 1..$n }

# Using `state` declarator to create a memoized factorial
sub fact( UInt $n --> UInt ) {
    state %known = 0 => 1;
    return %known{$n} if %known{$n}:exists;
    %known{$n} = $n * fact($n-1);
    return %known{$n};
}

Quicksort

Quicksort er en velkjent sorteringsalgoritme. En fungerende implementering ved bruk av det funksjonelle programmeringsparadigmet kan kortfattet skrives i Raku:

# Empty list sorts to the empty list
multi quicksort([]) { () }

# Otherwise, extract first item as pivot...
multi quicksort([$pivot, *@rest]) {
    # Partition.
    my @before = @rest.grep(* before $pivot);
    my @after  = @rest.grep(* after $pivot);

    # Sort the partitions.
    flat (quicksort(@before), $pivot, quicksort(@after))
}

Tower of Hanoi

Tower of Hanoi brukes ofte til å introdusere rekursiv programmering innen informatikk. Denne implementeringen bruker Rakus multi-dispatch-mekanisme og parametriske begrensninger:

multi sub hanoi(0, $, $, $) { }                         # No disk, so do not do anything
multi sub hanoi($n, $a = 'A', $b = 'B', $c = 'C') {     # Start with $n disks and three pegs A, B, C
    hanoi $n - 1, $a, $c, $b;                           # firstly move top $n - 1 disks from A to B
    say "Move disk $n from peg $a to peg $c";           # then move last disk from A to C
    hanoi $n - 1, $b, $a, $c;                           # lastly move $n - 1 disks from B to C
}

Bøker

I historien til Raku var det to bølger med bokskriving. Den første bølgen fulgte den første kunngjøringen av Perl 6 i 2000. Disse bøkene gjenspeiler tilstanden til utformingen av språk på den tiden, og inneholder stort sett utdatert materiale. Den andre bølgen, som fulgte kunngjøringen av versjon 1.0 i 2015, inkluderer flere bøker som allerede er utgitt og noen andre som er i ferd med å bli skrevet.

Bøker utgitt før Perl 6 versjon 1.0 (kjent som versjon 6.c)

  • A. Randal, D. Sugalski, L. Totsch. Perl 6 og Parrot Essentials , 1. utgave, 2003, ISBN  978-0596004996
  • A. Randal, D. Sugalski, L. Totsch. Perl 6 og Parrot Essentials , andre utgave 2004. ISBN  978-0596007379
  • S. Walters. Perl 6 Now: The Core Ideas Illustrated with Perl 5. 2004. ISBN  978-1590593950

En bok dedikert til en av de første Perl 6 virtuelle maskinene, Parrot, ble også utgitt i 2009.

Bøker utgitt etter Perl 6 versjon 1.0 (kjent som versjon 6.c)

Bøker utgitt med det nye Raku -navnet

Bøker som skal utgis

Det er noen få rapporter fra forskjellige forfattere om de nye bøkene som kommer til å bli utgitt snart, alle basert på den nåværende versjonen 1.0 (kjent som versjon 6.c) av Perl 6.

Referanser

Eksterne linker