Raku Programming Language

A powerful, feature-rich, multi-paradigm programming language

Download

Why Raku?

say 'Hello World';
# Multiple dispatch
multi sub fib (0 --> 0) {}
multi sub fib (1 --> 1) {}
multi sub fib (\n where * > 1) {
    fib(n - 1) + fib(n - 2)
}
say fib 10;
# OUTPUT: 55

# Roles and classes
role Shape {
    method area { ... }

    method print_area {
        say "Area of {self.^name} is {self.area}.";
    }
}

class Rectangle does Shape {
    has $.width is required;
    has $.height is required;

    method area {
        $!width * $!height
    }
}

Rectangle.new(width => 5, height => 7).print_area;
# OUTPUT: Area of Rectangle is 35.
# Inifinite and lazy list
my @fib = 0, 1, * + * ... ∞;
say @fib[^11];
# OUTPUT: (0 1 1 2 3 5 8 13 21 34 55)

# Feed operator
@fib[^20] ==> grep(&is-prime) ==> say();
# OUTPUT: (2 3 5 13 89 233 1597)

# Function composition
my &reverse_primes = &reverse&grep.assuming(&is-prime);
say reverse_primes ^20;
# OUTPUT: (19 17 13 11 7 5 3 2)

my @a = 1..4;
my @b = 'a'..'d';
# Zip two lists using Z meta operator
say @a Z @b;
# OUTPUT: ((1 a) (2 b) (3 c) (4 d))
say @a Z=> @b;
# OUTPUT: (1 => a 2 => b 3 => c 4 => d)

# Hyper Operators
say @b «~» @a;
# OUTPUT: [a1 b2 c3 d4]

# Junctions
say 'Find all the words starting with a lowercase vowel'.words.grep: *.starts-with: any <a e i o u>;
# OUTPUT: (all a)
grammar INIParser {
    token TOP { <block> <section>* }
    token section { <header> <block> }
    token header { '[' ~ ']' \w+ \n+ }
    token block { [<pair> | <comment>]* }
    rule pair { <key> '=' <value> }
    token comment { ';' \N* \n+ }
    token key { \w+ }
    token value { <-[\n ;]>+ }
}

my $match = INIParser.parse: q:to/END/;
; Comment
key1=value1
key2 = value2

; Section 1
[section1]
key3=value3
END


say $match<block><pair>[0]<value>;
# OUTPUT: 「value1」

say $match<section>[0]<block><pair>[0]<value>;
# OUTPUT: 「value3」
# Promise
my $promise = start {
    my $i = 0;
    for 1 .. 10 {
        $i += $_
    }
    $i
}
my $result = await $promise;
say $result;
# OUTPUT: 55

# Supply
my $bread-supplier = Supplier.new;
my $vegetable-supplier = Supplier.new;

my $supply = supply {
    whenever $bread-supplier.Supply {
        emit("We've got bread: " ~ $_);
    };
    whenever $vegetable-supplier.Supply {
        emit("We've got a vegetable: " ~ $_);
    };
}
$supply.tap(-> $v { say "$v" });

$vegetable-supplier.emit("Radish");
# OUTPUT: «We've got a vegetable: Radish␤» 
$bread-supplier.emit("Thick sliced");
# OUTPUT: «We've got bread: Thick sliced␤» 
$vegetable-supplier.emit("Lettuce");
# OUTPUT: «We've got a vegetable: Lettuce␤» 
say '🦋'.chars;
# OUTPUT: 1
say '🦋'.codes;
# OUTPUT: 1
say '🦋'.encode.bytes;
# OUTPUT: 4

my $raku = 'راکو';
say $raku.chars;
# OUTPUT: 4
say $raku.uninames;
# OUTPUT: (ARABIC LETTER REH ARABIC LETTER ALEF ARABIC LETTER KEHEH ARABIC LETTER WAW)
say $raku.comb;
# OUTPUT: (ر ا ک و)
say +$raku.comb;
# OUTPUT: 4
subset  of Int where * > 0;

sub f ( $a,  $b --> Array of ) {
    Array[].new: $a², $b²;
}

say f 1,2;
# OUTPUT: [1 4]

# Native Types
my int @a = ^10_000_000;
say [+] @a;
# OUTPUT: 49999995000000
sub MAIN(
    Str   $file where *.IO.f = 'file.dat',  #= an existing file to frobnicate 
    Int  :size(:$length) = 24,              #= length/size needed for frobnication 
    Bool :$verbose,                         #= required verbosity 
) {
    say $length if $length.defined;
    say $file   if $file.defined;
    say 'Verbosity ', ($verbose ?? 'on' !! 'off');
}

# $ script-name
# Usage:
# script-name [--size|--length=<Int>] [--verbose] [<file>]
   
#    [<file>]                 an existing file to frobnicate
#    --size|--length=<Int>    length/size needed for frobnication
#    --verbose                required verbosity

# $ perl6 frobnicate.p6 --verbose
# 24
# file.dat
# Verbosity on

# Another example with multi MAIN
multi MAIN ('install', Str $something, Bool :$force) {
    say "Installing $something {'by force' if $force}";
}

multi MAIN ('run', Str $something) {
    say "Running $something";
}

# $ script-name
# Usage:
# script-name [--force] install <something>
# script-name run <something>

# $ script-name --force install raku
# Installing raku by force
# Using NativeCall to access libnotify and show a notification
use NativeCall;

sub notify_init (str $appname --> int32) is native('notify') { * }
sub notify_uninit is native('notify') { * }
class NotifyNotification is repr('CPointer') { * }
sub notify_notification_new (str $summary, str $body, str $icon --> NotifyNotification) is native('notify') { * }
sub notify_notification_show (NotifyNotification) is native('notify') { * }

if notify_init 'MyApp' {
    notify_notification_show notify_notification_new 'My Notification', 'Notification Body', Str;
    notify_uninit;
}

# Using Inline::Python to access python and its libraries
use Inline::Python;
my $py = Inline::Python.new();
$py.run('print "hello world"');
# OUTPUT: hello world

# Or
say EVAL('1+3', :lang<Python>);
# OUTPUT: 4

use string:from<Python>;
say string::capwords('foo bar');
# OUTPUT: Foo Bar
use v6.c;
# TODO: Add operator, slang, macro examples
say Date.today.year;
# Output: 2020
say Date.today.later(:2years).year;
# Output: 2022

# TODO: Add more examples
sub add (Int $a, Int $b) {
    $a + $b
}

add 'string';
# ===SORRY!=== Error while compiling error.p6
# Calling add(Str) will never work with declared signature (Int $a, Int $b)
# at file.p6:5
# ------> <BOL>⏏add 'string';

Resources

Guides

Examples

Books

New to programming?

Try Online

Coming from another programming language?

If you are coming from another programming language, these documentations may be of help to you:
Python, JavaScript, Ruby, Haskell, Perl

If you want to use other programming languages and their libraries inside Raku, you can use Inline::* modules, such as:
Inline::Python, Inline::Perl, Inline::Go, Inline::Ruby, Inline::Lua

Community

Social Media

Language