The Raku Programming Language

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

Download Getting started

Why Raku?

Say hello to the world!

# human-readable string with newline. Calls the gist method.
say 'Hello World'; 

# string representation without newline. Calls the Str method.
print 'Hello, World!', "\n";

# hybrid of say (adds newline) and print (calls Str method).
put 'Hello, World'; 

Using multi-dispatch, classes, and roles with a nice and familiar syntax.

# Multi-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
    }
}

my $obj = Rectangle.new(width => 5, height => 7);
$obj.print-area; # OUTPUT: «Area of Rectangle is 35.␤»

Lazy lists, infinite sequences, junctions and feed, function composition, meta and hyper operators.

# Infinite and lazy list
my @fib = 0, 1, * + * ... ∞;
say @fib[^6]; # OUTPUT: «(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)␤»

# Zip two lists using Z meta operator
my @a = 1..4;
my @b = 'a'..'d';
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)␤»

Grammars for easily parsing data with new re-thought regular expressions.

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」␤»

Using Promise, Supply, Channel types and supply, react and whenever blocks.

# 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␤» 

Full Grapheme based unicode support.

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␤»

Optional gradual typing and native data types.

sub static( Int $a, Int $b -> Int ) {
    $a + $b
}

sub dynamic( $a, $b ) {
    $a + $b
}

say static(2, 5);          # OUTPUT: «7␤»
static(2, 'oops');         # ERROR: ... will never work with declared signature ...
say dynamic(<a b>, <c d>); # OUTPUT: «4␤»
dynamic(2, 'oops');        # ERROR: Cannot convert string to number ...

# Subsets

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␤»

Easy command-line interface, accessible by MAIN subroutine with multiple dispatch and automated usage message generation.

# An example with a single subroutine MAIN 

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');
}

=begin comment
# Usage message:

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

# Usage:

$ raku script-name.raku --verbose
24
file.dat
Verbosity on
=end comment

# An example with multiple subroutines MAIN 

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

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

=begin comment
# Usage message:

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

# Usage:
$ script-name.raku --force install raku
Installing raku by force
=end comment

Interfacing with C/C++ via NativeCall. Also use other languages within Raku via Inline::* modules.

# 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␤»

Specify which version of the language to use.

# Language version

use v6.c;

# Module version

Define your own functions, operators, traits and data-types.

# TODO: Add operator, slang, macro examples

Large selection of available data-types and operators.

say Date.today.year;
# Output: 2020
say Date.today.later(:2years).year;
# Output: 2022

# TODO: Add more examples

Nice compile-time and run-time error messages.

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';

File-related input/output operations via the IO::Handle and IO::Path types.

# Reading from a file

# get a file handle for reading
my $fh = open "testfile", :r;

# get a file's contents
my $contents = $fh.slurp;

# close the file handle
$fh.close;

# alternatively, do everything at once by letting
# `slurp` to open and close the file for you
$contents = slurp "testfile"

# Writing to a file

# get the file handle for writing
$fh = open "testfile", :w;

# print content into file
$fh.say("New content with newline.");

# close the file handle
$fh.close;

# alternatively, do everything at once by letting
# `spurt` to open and close the file for you.
spurt "testfile", "More data\n", :append;

Resources

Guides

Books

New to programming?

Coming from another programming language?

If you are coming from another programming language, the Migration guides 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