FAQ
General
What's the difference between Raku, Rakudo and Perl 6?
Properly speaking, Rakudo is an implementation of Raku. It's currently the one that's being developed, but there have been other implementations in the past and there will likely be others in the future. Raku is the definition of the language. When talking about the current interpreter, Rakudo and Raku can be used interchangeably. "Perl 6" is the name that was used for "Raku" before October 2019.
When was Raku released?
The Rakudo 2015.12 implementation version was released on December 25th 2015, which implemented the v6.c Raku specification, released at the same time.
Is there a Raku version 6.0.0?
No. The first stable language specification version is v6.c ("Christmas"). Future versions of the spec may have point releases (e.g., v6.d.2) or major releases (e.g., v6.e).
Running raku -v
will display the language version your compiler
implements, e.g.:
$ raku -v
Welcome to Rakudoâą v2022.04.
Implementing the RakuÂź Programming Language v6.d.
Built on MoarVM version 2022.04.
When was v6.d released?
The v6.d Specification was released on Diwali 2018, which was November 6â7 2018, in a convenient time zone. 6.d was enabled by default in the Rakudo compiler release of 2018.11.
The vast majority of 6.d features were already implemented and available
in the Rakudo compiler without requiring any special pragmas, as they
did not conflict with the 6.c specification. A smaller set of features
and behaviors is available automatically if you have the use
v6.d
pragma at the top of the file. The rest of about 3100 new
commits to the language specification simply clarify previously
undefined behavior.
As a Raku user, what should I install?
Mac users can use the latest Rakudo Star DMG binary installer at https://rakudo.org/downloads/star
Windows users can use the Rakudo Star MSI binary installer. You will need Windows Git and Strawberry Perl to use zef to install library modules.
Linux users probably want to download Rakudo Star and follow the compilation instructions at https://www.raku.org/downloads/.
There should be Linux and Mac binaries available from vendors and third parties, although vendor versions may be outdated. Versions before Rakudo release of 2015.12 should be avoided.
There's an official Rakudo Star docker image at https://hub.docker.com/_/rakudo-star/
As an advanced user I want to track Rakudo development.
An option is to clone the repository and build it. This will install work in progress which is minimally-tested and may contain severe bugs. If you're interested in contributing to the Rakudo Raku compiler, you may find the Z-Script helper tool useful.
To install the last official monthly release, check out the tag visible at https://raw.githubusercontent.com/rakudo/rakudo/master/VERSION or set up a helper command.
Some users choose to use rakubrew, which allows quick installation of multiple versions of Rakudo in parallel.
In either case you will probably need to also install zef and rakudoc from the ecosystem.
Where can I find good documentation on Raku?
See the official documentation website (especially its "Introduction" section) as well as the Resources page. You can also consult this great cheatsheet.
perl6book.com contains a list of dead tree and electronic books.
Be mindful of publication dates when reading third-party articles. Anything published before December, 2015 likely describes a pre-release version of Raku.
You can always get help from a live human in our help chat or search the chat logs to find previous conversations and discussions.
Can I get some books about Raku?
Here are some available books, in alphabetical order:
Learning Raku, by brian d foy
Learning to program with Raku: First Steps, by JJ Merelo
Metagenomics, by Ken Youens-Clark
Parsing with Perl 6 Regexes and Grammars, by Moritz Lenz
Perl 6 at a Glance, by Andrew Shitov
Raku Fundamentals, by Moritz Lenz
Perl 6 Deep Dive, by Andrew Shitov
Think Perl 6: How to Think Like a Computer Scientist, by Laurent Rosenfeld.
A list of books published or in progress is maintained in raku.org.
What is the Raku specification?
The specification refers to the official test suite for Raku. It's called roast and is hosted on github. Any compiler that passes the tests is deemed to implement that version of the Raku specification.
Roast's master
branch corresponds to the latest development that isn't
necessarily part of any specification yet. Other branches
correspond to specific versions; for example, "6.c-errata".
So 6.c-errata
is a released language version we don't change other than to
fix errors in tests (the "errata") whereas master is the unreleased
work-in-progress that may become the next language version. Its current state
is not necessarily prescriptive of the next language version's behavior since
new additions will be reviewed for inclusion into the release.
Is there a glossary of Raku related terms?
Yes, see glossary.
I'm a Perl programmer. Where is a list of differences between Perl and Raku?
There are several Perl to Raku guides in the Introduction section of the documentation, most notable of which is the Overview.
I'm a Ruby programmer looking for quickstart type docs?
See the rb-nutshell guide.
Modules
Is there a repository of third party library modules for Raku?
Yes. As a user, the
zef module installer will
automatically install the version of a module with the highest
version number. If you want a specific version and/or a version
from a specific author, you can also specify that with zef
.
As a new module author, you can use the fez module uploader to upload your module to the Raku ecosystem. There are also a number of helper modules that help you set up a skeleton of a distribution, such as App::Mi6, which will also help you with uploading once your module is ready for distribution.
Historically, you could also upload a Raku module to CPAN by using PAUSE to upload a module. And before that, there was a way of using Github/Gitlab to make your module available for download. These are now considered to not be the best way for new module authors to start with.
Is there a perldoc (command line documentation viewer) for Raku?
Yes, it's called rakudoc
and is present in the ecosystem under that name. It
comes bundled in with Rakudo Star but needs to be manually installed with zef
if you are using a Rakudo monthly release.
Can I use Perl modules from Raku?
Yes, with Inline::Perl5, which works well with most Perl modules. It can even run Perl Catalyst and DBI.
Can I use C and C++ from Raku?
Nativecall makes this particularly easy.
Nativecall can't find libfoo.so
and I only have libfoo.so.1.2
!
In most Linux systems, shared libraries will be installed in such a way that,
for a specific libfoo
, there will be a libfoo.so.x.y.z
real file, and
then a set of symlinks libfoo.so
and libfoo.so.x
. for instance, ls
/usr/local/lib/libxxhash.so*
returns:
/usr/local/lib/libxxhash.so -> libxxhash.so.0.6.5
/usr/local/lib/libxxhash.so.0 -> libxxhash.so.0.6.5
/usr/local/lib/libxxhash.so.0.6.5
In general, installing a libfoo-dev
or libfoo-devel
(depending on the
distro) in Linux will install the shared library and set up those symlinks
for you. But in some cases, you will only have, as in the question,
libfoo.so.1.2
.
In that case, just use the version of is native
that explicitly sets the
ABI/API version, as indicated in
the manual:
sub call-foo() is native('foo',v1.2);
Where have all the traditional UNIX library functions gone?
It's fairly easy to use NativeCall to access them.
An ecosystem module POSIX is also available.
Does Rakudo have a core standard library?
Rakudo Star distribution does come with many useful modules.
Rakudo compiler-only release includes only a couple of the most basic modules.
Many more modules can be found in the ecosystem.
Is there something like B::Deparse
/How can I get hold of the AST?
Use --target=optimize
command line option to view the AST of your program,
e.g., raku --target=optimize -e 'say "hi"'
The target optimize
gives the AST after the static optimizer does its job,
while target ast
gives the AST before that step. To get the full list of
available targets, run raku --stagestats -e ""
What is precompilation?
When you load a module for the first time, Rakudo compiles it into bytecode. Then, Rakudo both stores the compiled bytecode on disk and uses it, because that tends to be significantly faster.
Can I have circular dependencies between modules?
No, you can't have circular dependencies, and you should
get a Circular module loading detected
error if you have them between your
modules.
Very likely you can accomplish what you are trying to do using
roles. Instead of A.rakumod
depending on
B.rakumod
and B.rakumod
depending on A.rakumod
, you can have A-Role.rakumod
and B-Role.rakumod
and classes in A.rakumod
and B.rakumod
implementing these
roles respectively. Then you can depend on A-Role.rakumod
and
B-Role.rakumod
without the need for the circular dependency.
One of the reasons why circular dependencies do not work in Raku is one pass parsing. We have to know what A means when we parse B, and we have to know what B means when we parse A, which is clearly an infinite loop.
Note that Raku has no â1 file = 1 classâ limitation, and circular dependencies within a single compilation unit (e.g., file) are possible through stubbing. Therefore another possible solution is to move classes into the same compilation unit.
Common operations
String: How can I parse and get a number from a string?
Use the + prefix:
say "42.123456789123456789"; # OUTPUT: «42.123456789123456789â€Â»
say +"42.4e-2"; # OUTPUT: «0.424â€Â»
This example of contextualization can numify any string you could enter as a literal number. val routine converts it to allomorph. unival routine converts one unicode codepoint.
String: How can I check if a string contains a substring and if so, how can I get indices of matches?
"az and az and az again".contains("az"); # OUTPUT: «Trueâ€Â»
"az and az and az again".indices("az"); # OUTPUT: «(0 7 14)â€Â»
String: How can I get the hexadecimal representation of a string?
To get a hexadecimal list of each byte of a string (i.e. hex encoder), first convert the string to a Blob with .encode.
say "I †đŠ".encode>>.base(16); # OUTPUT: «(49 20 E2 9D A4 20 F0 9F A6 8B)â€Â»
Note that .gist or .raku methods can be useful for variable introspection:
say "I †đŠ".encode.raku; # OUTPUT: «utf8.new(73,32,226,157,164,32,240,159,166,139)â€Â»
say "I †đŠ".encode.gist; # OUTPUT: «utf8:0x<49 20 E2 9D A4 20 F0 9F A6 8B>â€Â»
String: How can I remove from a string some characters by index?
Use .comb to transform it to a Seq, then the (-) infix to remove the unwanted indices:
say '0123456789'.comb[(^* (-) (1..3, 8).flat).keys.sort].join; # OUTPUT: «045679â€Â»
If the string is large, .comb can take time. In which case, .substr-rw is faster:
multi postcircumfix:<[- ]> (Str:D $str is copy, +@indices) {
for @indices.reverse {
when Int { $str.substr-rw($_,1) = '' }
when Range { $str.substr-rw($_ ) = '' }
}
return $str;
}
say '0123456789'[- 1..3, 8 ]; # OUTPUT: «045679â€Â»
String: How can I split a string in equal parts?
.comb is accepting an optional Int:
.say for 'abcdefghijklmnopqrstuvwxyz'.comb: 8; # OUTPUT: «abcdefghâ€ijklmnopâ€qrstuvwxâ€yz»
Language features
How can I dump Raku data structures (like Perl Data::Dumper and similar)?
Typical options are to use the say routine that uses
the gist method which gives the "gist" of the object being
dumped. More detailed output can be obtained by calling the
perl method (soon to be deprecated in favor of $obj.raku
,
available since the Rakudo 2019.11 release) that typically returns an object's
representation in EVAL-able code.
If you're using the rakudo implementation, you can use the rakudo-specific dd routine for dumping, whose output is similar to raku, but with more information.
Examples:
my $foo = %( foo => 'bar' );
say $foo.raku; # OUTPUT: «${:foo("bar")}â€Â»
say $foo; # OUTPUT: «{foo => bar}â€Â»
# non-standard routine available in rakudo implementation:
dd $foo; # OUTPUT: «Hash $foo = ${:foo("bar")}â€Â»
There are also several ecosystem modules that provide more control over how data structures are dumped, including support for colored output.
Why is the Rakudo compiler so apologetic?
If SORRY! is present in the output, the error is a compile time error. Otherwise, it's a runtime error.
Example:
sub foo( Int $a, Int $b ) {...}
foo(1) # ===SORRY!=== Error while compiling ...
say 1/0; # Attempt to divide 1 by zero using div
What is (Any)
?
Any is a top level class most objects inherit from.
The Any type object is
the default value on variables and
parameters without an explicit type constraint, which means you'll
likely see (Any)
printed when you output a gist of
a variable without any value by using, for instance, the
say routine:
my $foo;
say $foo; # OUTPUT: «(Any)â€Â»
my Int $baz;
say $baz; # OUTPUT: «(Int)â€Â»
my $bar = 70;
say $bar; # OUTPUT: «70â€Â»
To test whether a variable has any defined values, see DEFINITE and defined routines. Several other constructs exist that test for definiteness, such as with, orwith, and without statements, //, andthen, notandthen, and orelse operators, as well as type constraint smileys.
What is so
?
so
is a loose precedence operator that coerces to Bool.
It has the same semantics as the ?
prefix operator, just like
and
is the low-precedence version of &&
.
Example:
say so 1|2 == 2; # OUTPUT: «Trueâ€Â»
In this example, the result of the comparison (which is a Junction), is converted to Bool before being printed.
What are those :D
and :U
things in signatures?
In Raku, classes and other types are objects and pass type checks of their own type.
For example, if you declare a variable
my Int $x = 42;
then not only can you assign integers (that is, instances of class Int) to it, but the Int type object itself:
$x = Int
If you want to exclude type objects, you can append the :D
type smiley,
which stands for "definite":
my Int:D $x = 42;
$x = Int;
# dies with:
# Type check failed in assignment to $x;
# expected Int:D but got Int
Likewise, :U
constrains to undefined values, that is, type objects.
To explicitly allow either type objects or instances, you can use :_
.
What is the -->
thing in the signature?
-->|/language/signatures#Constraining_return_types is a return constraint, either a type or a definite value.
Example of a type constraint:
sub divide-to-int( Int $a, Int $b --> Int ) {
return ($a / $b).narrow;
}
divide-to-int(3, 2)
# Type check failed for return value; expected Int but got Rat
Example of a definite return value:
sub discard-random-number( --> 42 ) { rand }
say discard-random-number;
# OUTPUT: «42â€Â»
In this case, the final value is thrown away because the return value is already specified in the signature.
How can I extract the values from a Junction?
If you want to extract the values (eigenstates) from a Junction, you are probably doing something wrong and should be using a Set instead.
Junctions are meant as matchers, not for doing algebra with them.
If you want to do it anyway, you can abuse autothreading for that:
sub eigenstates(Mu $j) {
my @states;
-> Any $s { @states.push: $s }.($j);
@states;
}
say eigenstates(1|2|3).join(', ');
# prints 1, 2, 3 or a permutation thereof
If Str is immutable, how does s///
work? If Int is immutable,
how does $i++
work?
In Raku, values of many basic types are immutable, but the variables holding
them are not. The s///
operator works on a variable, into which it puts a
newly created string object. Likewise, $i++
works on the $i
variable, not
just on the value in it.
Knowing this, you would not try to change a literal string (e.g. like
'hello' ~~ s/h/H/;
), but you might accidentally do something equivalent
using map
as follows.
my @foo = <hello world>.map: { s/h/H/ };
# dies with
# Cannot modify an immutable Str (hello)
my @bar = <hello world>».subst-mutate: 'h', 'H';
# dies with
# Cannot resolve caller subst-mutate(Str: Str, Str);
# the following candidates match the type but require
# mutable arguments: ...
Instead of modifying the original value in place, use a routine or operator that returns a new value:
my @foo = <hello world>.map: { S/h/H/ }; # ['Hello','world']
my @bar = <hello world>».subst: 'h', 'H'; # ['Hello','world']
See the documentation on containers for more information.
What's up with array references and automatic dereferencing?
Do I need the @
sigil?
In Raku, nearly everything is a reference, so talking about taking references doesn't make much sense. Scalar variables can also contain arrays directly:
my @a = 1, 2, 3;
say @a; # OUTPUT: «[1 2 3]â€Â»
say @a.^name; # OUTPUT: «Arrayâ€Â»
my $scalar = @a;
say $scalar; # OUTPUT: «[1 2 3]â€Â»
say $scalar.^name; # OUTPUT: «Arrayâ€Â»
The big difference is that arrays inside a scalar act as one value in list context, whereas arrays will be happily iterated over.
my @a = 1, 2, 3;
my $s = @a;
for @a { ... } # loop body executed 3 times
for $s { ... } # loop body executed only once
my @flat = flat @a, @a;
say @flat.elems; # OUTPUT: «6â€Â»
my @nested = flat $s, $s;
say @nested.elems; # OUTPUT: «2â€Â»
You can force list context with @( ... )
or by calling the
.list
method on an expression, and item context with
$( ... )
or by calling the .item
method on an expression.
See the Perl 6: Sigils, Variables, and Containers|https://perl6advent.wordpress.com/2017/12/02/ article to learn more.
Why sigils? Couldn't you do without them?
There are several reasons:
they make it easy to interpolate variables into strings
they form micro-namespaces for different variables and twigils, thus avoiding name clashes
they allow easy single/plural distinction
they work like natural languages that use mandatory noun markers, so our brains are built to handle it
they aren't mandatory, since you can declare sigilless names (if you don't mind the ambiguity)
"Type Str does not support associative indexing."
You likely tried to mix string interpolation and key characters, like HTML tags:
my $foo = "abc";
say "$foo<html-tag>";
Raku thinks $foo
is a Hash and <html-tag>
is a string literal
hash key. Use a closure to help it to understand you.
my $foo = "abc";
say "{$foo}<html-tag>";
Does Raku have coroutines? What about yield
?
Raku has no yield
statement like Python does, but it does offer similar
functionality through lazy lists. There are two popular ways to write
routines that return lazy lists:
# first method, gather/take
my @values = gather while have_data() {
# do some computations
take some_data();
# do more computations
}
# second method, use .map or similar method
# on a lazy list
my @squares = (1..*).map(-> \x { xÂČ });
Why can't I initialize private attributes from the new method, and how can I fix this?
The say
statement in the following code sample
class A {
has $!x;
method show-x {
return $!x;
}
}
say A.new(x => 5).show-x;
does not print 5. Private attributes are private, which means invisible to
the outside world. If the default constructor could initialize them, they would
leak into the public API. Thus, in this particular code sample the attribute
$!x
isn't initialized during object construction by the default
constructor.
If you still want to initialize private attributes with the default constructor,
you can add a submethod BUILD
to achieve such task:
class B {
has $!x;
submethod BUILD(:$!x) { }
method show-x {
return $!x;
}
}
say B.new(x => 5).show-x;
BUILD
is called by the default constructor (indirectly, see
Object Construction
for more details) with all the named arguments that the user passes to the
constructor. :$!x
is a named parameter with name x
, and when called
with a named argument of name x
, its value is bound to the attribute $!x
.
However, you shouldn't do that. If the attribute is declared as private,
then it shouldn't be exposed to the environment outside the class (e.g.,
during object construction). On the other hand, if the attribute is public,
there is no downside to declaring it that way with $.x
since the external
view is read-only by default, and you can still access it internally with $!x
.
How and why do say
, put
and print
differ?
The most obvious difference is that say
and put
append
a newline at the end of the output, and print
does not.
But there's another difference: print
and put
convert their
arguments to a string by calling the Str method on each item
passed to them while say
uses the gist
method. The gist
method,
which you can also create for your own classes, is intended to create a
Str for human interpretation. So it is free to leave out information
about the object deemed unimportant to understanding the essence of the object.
Or phrased differently, $obj.Str
gives a string representation,
$obj.gist
provides a short summary of that object suitable for
fast recognition by a human, and $obj.raku
gives a Raku-ish
representation from which the object could be re-created.
For example, when the Str method is invoked on a type object, also known
as an "undefined value", the type is stringified to an empty string
and a warn
ing is thrown. On the other hand, the gist
method returns the
name of the type between parentheses (to indicate there's nothing in that
value except the type).
my Date $x; # $x now contains the Date type object
print $x; # empty string plus warning
say $x; # OUTPUT: «(Date)â€Â»
If you'd like to show a debugging version of an object, it is probably better
to use the rakudo-specific dd routine.
It essentially does $obj.raku
and shows that on STDERR rather than
STDOUT, so it won't interfere with any "normal" output of your program.
In short, say
is optimized for casual human interpretation, dd
is optimized
for casual debugging output and print
and put
are more generally suitable
for producing output.
put
is thus a hybrid of print
and say
; like print
, it calls the
Str method on the object. And like say
, it adds a newline at the end
of the output.
What's the difference between token
and rule
?
regex
, token
and rule
introduce regexes, but with
slightly different semantics.
token
implies the :ratchet
or :r
modifier, which prevents the
rule from backtracking.
rule
implies both the :ratchet
and :sigspace
(short :s
)
modifier, which means a rule doesn't backtrace, and it treats
whitespace in the text of the regex as <.ws>
calls (i.e.,
matches whitespace, which is optional except between two word
characters). Whitespace at the start of the regex and at the start
of each branch of an alternation is ignored.
regex
declares a plain regex without any implied modifiers.
What's the difference between die
and fail
?
die
throws an exception.
fail
returns a Failure object. (If the caller has declared use fatal;
in the calling lexical scope, fail
throws an exception instead of
returning it.)
A Failure is an "unthrown" or "lazy" exception. It's an object that contains the exception, and throws the exception if you try to use the Failure as an ordinary object or ignore it in sink context.
A Failure returns False
from a defined
check, and you can extract
the exception with the exception
method.
What's the difference between Pointer
and OpaquePointer
?
OpaquePointer
is deprecated and has been replaced with Pointer
.
You can have colonpairs in identifiers. What's the justification?
Identifiers can include colon pairs, which become part of their name. According to Larry Wall's answer to the issue, We already had the colon pair mechanism available, so it was a no-brainer to use that to extend any name that needs to be able to quote uniquefying but non-standard characters (or other information with a unique stringification to such characters).
How do most people enter unicode characters?
It depends on the operating system, windowing environment and/or editors. This page on entering Unicode characters specifies how it is done in the most popular operating systems and editors.
Raku implementation
What Raku implementations are available?
Currently the best developed is Rakudo (using multiple Virtual Machine backends). Historic implementations include Niecza (.NET) and Pugs (Haskell). Others are listed at Raku Compilers
What language is Rakudo written in?
A short answer is that Rakudo is written almost entirely in Raku. A more detailed answer is that Rakudo is written in a mixture of Raku and NQP ("Not Quite Perl"). NQP is a lightweight Raku-like environment for virtual machines; it's designed to be a high-level way to create compilers and libraries for virtual machines (such as MoarVM and JVM) using Raku syntax.
What language is NQP written in?
NQP is a mixture of (1) NQP code, (2) whatever language the underlying virtual machine is using, (3) some third-party C and Java libraries, and (4) some bootstrapping files created by earlier runs of the build process.
Is Raku Lisp?
(not (not Nil))
Can I compile my script to a standalone executable?
Tools like App::InstallerMaker::WiX allow you to create an installer that will package the compiler and your script. However, the currently available compilers do not support creating a standalone executable yet.
If you wish to help out, the Rakudo compiler on MoarVM backend has https://github.com/MoarVM/MoarVM/issues/875 issue opened as a place to discuss this problem.
Raku distribution
When will the next version of Rakudo Star be released?
A Rakudo Star release is typically produced quarterly, with release announcements posted on rakudo.org.
Metaquestions and advocacy
Why was Raku originally called Perl 6?
⊠As opposed to some other name that didn't imply all the things that the higher number might indicate on other languages.
The short answer is that it was Larry's choice under Rule 1.
The community considers Perl and Raku sister languages - they have a lot in common, address many of the same problem spaces, but Raku is not intended to replace Perl. In fact, both languages interoperate with each other.
When will Raku be ready? Is it ready now?
Readiness of programming languages and their compilers is not a binary decision. As the language and the implementations evolve, they grow steadily more usable. Depending on your needs, Raku and its compilers may or may not be ready for you.
That said, version 6.c (Christmas 2015) is the first official release of Raku as a language, along with a validation suite and a compiler that passes it.
Why should I learn Raku? What's so great about it?
Raku unifies many great ideas that aren't usually found in other programming languages. While several other languages offer some of these features, none of them offer all of them.
Raku offers procedural, object-oriented AND functional programming methodologies.
Easy to use consistent syntax, using invariable sigils for data-structures.
Full grapheme based Unicode support, including Annex #29.
Clean, more readable regular expressions; taken to the next level of usability, with a lot more functionality. Named regular expressions improve ease of use.
Junctions allowing easy checking of multiple possibilities; e.g.,
$a == 1|3|42
(Is$a
equal to 1 or 3 or 42?).Dynamic variables provide a lexically scoped alternative to global variables.
Emphasis on composability and lexical scoping to prevent âaction at a distanceâ; e.g., imports are always lexically scoped.
Easy to understand consistent scoping rules and closures.
Powerful object orientation, with classes and roles (everything can be seen as an object). Inheritance. Subtyping. Code-reuse.
Introspection into objects and metaobjects (turtles all the way down).
MetaObject Protocol allowing for metaprogramming without needing to generate or parse code.
Subroutine and method signatures for easy unpacking of positional and named parameters.
Multi-dispatch for identically named subroutines/methods with different signatures, based on arity, types and optional additional code.
Compile time error reporting on unknown subroutines or impossible dispatch.
Optional gradual type-checking at no additional runtime cost. With optional type annotations.
Advanced error reporting based on introspection of the compiler/runtime state. This means more useful, more precise error messages.
Phasers (like
BEGIN
/END
) allow code to be executed at scope entry / exit, loop first / last / next and many more special contexts.High level concurrency model, both for implicit as well as explicit multi-processing, which goes way beyond primitive threads and locks. Raku's concurrency offers a rich set of (composable) tools.
Multiple-core computers are getting used more and more, and with Raku these can be used thanks to parallelism, both implicit (e.g., with the
>>
. method) and explicit (start { code }
). This is important, because Moore's Law is ending.Structured language support is provided to enable programming for asynchronous execution of code.
Supplies allow code to be executed when something happens (like a timer, or a signal, or a filesystem event).
react
/whenever
/supply
keywords allows easy construction of interactive, event driven applications.Lazy evaluation when possible, eager evaluation when wanted or necessary. This means, for example, lazy lists, and even infinite lazy lists, like the Fibonacci sequence, or all prime numbers.
Native data types for faster, closer-to-the-metal, processing.
Interfacing to external libraries in C and C++ is fairly easy with NativeCall.
Interfacing with Perl (CPAN) and Python modules is fairly easy with Inline::Perl5 and Inline::Python
Can have multiple versions of a module installed and loaded simultaneously.
System administration simplified due to simpler update and upgrade policies.
Simple numeric computation without precision loss because of Rats (rational numbers).
Extensible grammars for parsing data or code (which Raku uses to parse itself).
Raku is a very mutable language (define your own functions, operators, traits and data-types, which modify the parser for you).
Large selection of data-types, plus the possibility to create your own types.
Multi-dimensional shaped or native arrays with proper bounds checking.
Execute code at any time during parsing of a grammar, or when a certain match occurred.
Adding a custom operator or adding a trait is as simple as writing a subroutine.
Automatic generation of hyper-operators on any operator (system or custom added).
Runs on a variety of back-ends. Currently MoarVM and JVM, JavaScript in development, more may follow.
Runtime optimization of hot code paths during execution (JIT).
Runs on small (e.g., Raspberry Pi) and large multi-processor hardware.
Garbage collection based: no timely destruction, so no reference-counting necessary. Use phasers for timely actions.
Methods can be mixed into any instantiated object at runtime; e.g., to allow adding out-of-band data.
Easy command-line interface accessible by
MAIN
subroutine with multiple dispatch and automated usage message generation.Fewer lines of code allow for more compact program creation. Huffman-coding of names allows for better readability.
Lazy lists defined with a simple iterator interface, which any class can supply by minimally supplying a single method.
Ability to use hyphens and other non-alphanumeric ASCII characters as well as certain Unicode characters in identifiers. (Using hyphens instead of underscores in test is commonly called "kebab case" among its users. See also "camel case" and "snake case": https://en.wikipedia.org/wiki/Letter_case#Special_case_styles.)
Raku's mottos remain the same as they have been for Perl all along: âPerl is different. In a nutshell, Perl is designed to make the easy jobs easy, without making the hard jobs impossible.â and âThere Is More Than One Way To Do Itâ. Now with even more -Ofun added.
Is Raku fast enough for me?
That depends on what you are doing. Rakudo has been developed with the philosophy of "make it work right then make it work fast." It's fast for some things already but needs work for others. Since Raku provides lots of clues to the JIT that other dynamic languages don't, we think we'll have a lot of headroom for performance improvements.
The following crude benchmarks, with all the usual caveats about such things, show that Raku can be faster than Perl for similar tasks if the big weaponry is included, that is, if Raku features are used to its full extent; at the same time, Perl can be faster if only the bare bones are included. Similar situations can be observed when comparing Raku to other languages.
Try it on your system. You may be pleasantly surprised!
Examples:
# Raku version
class Foo { has $.i is rw };
for 1..1_000_000 -> $i {
my $obj = Foo.new;
$obj.i = $i;
}
# Perl version
package Foo;
use Moose;
has i => (is => 'rw');
__PACKAGE__->meta->make_immutable;
for my $i (1..1_000_000) {
my $obj = Foo->new;
$obj->i($i);
}
1;
# Another Perl version that offers bare-bones set of features
# compared to Moose/Raku's version but those are not needed in this
# specific, simple program anyway.
package Foo;
use Mojo::Base -base;
has 'i';
for my $i (1..1_000_000) {
my $obj = Foo->new;
$obj->i($i);
}
1;
You might want to use this program for comparing performance, too. It works
under both languages, as long as perl -Mbigint
is used for invocation for
Perl.
my ($prev, $current) = (1, 0);
for (0..100_000) {
($prev, $current) = ($current, $prev + $current);
}
print $current;