زبان برنامه‌نویسی راکو

یک زبان برنامه‌نویسی قدرتمند، سرشار از ویژگی، چندالگویی

دانلود مشارکت کنید

چرا راکو؟

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

# Concurrency
react {
    my $current-proc;
    whenever $script.watch.unique(:as(*.path), :expires(1)) {
        .kill with $current-proc;
        $current-proc = Proc::Async.new($*EXECUTABLE, $script);
        my $done = $current-proc.start;
        whenever $done {
            $current-proc = Nil;
        }
    }
}

my $modules-load = start @files
    .grep(/ \.(yaml|yml) $/)
    .sort(-*.s)
    .race(batch => 1, degree => 6)
    .map(-> $file {
            my $yaml = self!load-yaml($file, $schema, $problems);
            with $yaml {
                Easii::Model::Module.new(parsed => $yaml, source => $file.basename)
            }
     })
    .eager;

# 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
subsetof 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

# $ raku frobnicate.raku --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
=begin pod

=head1 Documenting code in C<Raku>

=item L<Raku docs|https://docs.raku.org>

=end pod

=begin pod

=head1 Red

Take a look at our Documentation: L<https://fco.github.io/Red/>

=head2 Red - A **WiP** ORM for Raku

=head2 INSTALL
Install with (you need **rakudo 2018.12-94-g495ac7c00** or **newer**):

=begin code :lang<bash>
zef install Red
=end code

=head2 SYNOPSIS

=begin code :lang<raku>
use Red:api<2>;
model Person {...}
model Post is rw {
    has Int         $.id        is serial;
    has Int         $!author-id is referencing{ Person.id };
    has Str         $.title     is column{ :unique };
    has Str         $.body      is column;
    has Person      $.author    is relationship{ .author-id };
    has Bool        $.deleted   is column = False;
    has DateTime    $.created   is column .= now;
    has Set         $.tags      is column{
        :type<string>,
        :deflate{ .keys.join: "," },
        :inflate{ set(.split: ",") }
    } = set();
    method delete { $!deleted = True; self.^save }
}
model Person is rw {
    has Int  $.id            is serial;
    has Str  $.name          is column;
    has Post @.posts         is relationship{ .author-id };
    method active-posts { @!posts.grep: not *.deleted }
}
my $*RED-DB = database "SQLite";
Person.^create-table;
=end code

=begin code :lang<sql>
-- Equivalent to the following query:
CREATE TABLE person(
    id integer NOT NULL primary key
    AUTOINCREMENT,
    name varchar(255) NOT NULL
)
=end code

=begin code :lang<raku>
Post.^create-table;
=end code

=begin code :lang<sql>
-- Equivalent to the following query:
CREATE TABLE post(
    id integer NOT NULL primary key AUTOINCREMENT,
    author_id integer NULL references person(id),
    title varchar(255) NOT NULL,
    body varchar(255) NOT NULL,
    deleted integer NOT NULL,
    created varchar(32) NOT NULL,
    tags varchar(255) NOT NULL,
    UNIQUE (title)
)
=end code

=begin code :lang<raku>
my Post $post1 = Post.^load: :42id;
=end code

=begin code :lang<sql>
-- Equivalent to the following query:
SELECT
    post.id,
    post.author_id as "author-id",
    post.title,
    post.body,
    post.deleted,
    post.created,
    post.tags
FROM
    post
WHERE
    post.id = 42
=end code

=end pod
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.raku
# Calling add(Str) will never work with declared signature (Int $a, Int $b)
# at file.raku:5
# ------> <BOL>⏏add 'string';

منابع

راهنماها

دوره‌های آموزشی

مثالها

کتاب‌ها

ناآشنا به برنامه‌نویسی هستید؟

آنلاین امتحان کنید

از زبان برنامه‌نویسی دیگری می‌آیید؟

اگر از زبان برنامه‌نویسی دیگری می‌آیید، این مستندات ممکن است به شما کمک کنند:
پایتون, جاوااسکریپت, روبی, هسکل, پرل

اگر می‌خواهید از زبان‌های برنامه‌نوسی دیگر و کتابخانه‌های آنها داخل راکو استفاده کنید، می‌توانید از ماژول‌های Inline::* استفاده کنید، مانند:
Inline::Python, Inline::Perl, Inline::Go, Inline::Ruby, Inline::Lua