Archive for the ‘Raku’ Category


November 5, 2021 1 comment

On Discord flirora wished for a way to merge list elements conditional. In this instance the condition is that any element that starts with a space is part of a group.

    my @a = ("apple", " banana", " peach", "blueberry", "pear", " plum", "kiwi");

    multi sub merge-spacy([]) { () }
    multi sub merge-spacy([$x is copy, *@xs]) {
        if @xs[0].?starts-with(' ') {
            $x ~= @xs.shift;
            merge-spacy([|$x, |@xs])
        } else {
            $x, |merge-spacy(@xs)

    dd merge-spacy(@a);
# OUTPUT: ("apple banana peach", "blueberry", "pear plum", "kiwi")

This functional version is neat but slow. Rakudo can’t inline recursion and doesn’t do any other optimisations yet.

my @a = ("apple", " banana", " peach", "blueberry", "pear", " plum", "kiwi");

sub merge-with(@a, &c) {
    gather while @a.shift -> $e {
        if @a && &c(@a.head) {
            @a.unshift($e ~ @a.shift)
        } else {
            take $e;

dd @a.&merge-with(*.starts-with(' '));

# OUTPUT: ("apple banana peach", "blueberry", "pear plum", "kiwi").Seq

With gather/take we don’t have to worry about recursion and the returned Seq is lazy be default. This can provide a big win if the list gets big and is not wholly consumed.

my @a = ("apple", " banana", " peach", "blueberry", "pear", " plum", "kiwi");

multi sub join(*@a, :&if!) {
    class :: does Iterable {
        method iterator {
            class :: does Iterator {
                has @.a;
                has &.if;
                method pull-one {
                    return IterationEnd unless @!a;

                    my $e = @!a.shift;
                    return $e unless @!a;

                    while &.if.(@!a.head) {
                        $e ~= @!a.shift;

                    return $e;
            }.new(a => @a, if => &if)

.say for join(@a, if => *.starts-with(' '));

This version should please lizmat as it uses iterators. The conditional is also factored out and CORE will use the Iterator lazily wherever possible. In production code I would get rid of the return-statements and replace them with ternary operators to get a little extra performance.

The original question (that clearly got me carried away) asked for the groups to be join. Once we lost a structure it can be difficult to reconstruct it.

my @a = ("apple", " banana", " peach", "blueberry", "pear", " plum", "kiwi");

#| &c decides if the group is finished
sub group-list(@a, &c) {
   my @group;
   gather while @a {
       my $e = @a.shift;
       my $next := +@a ?? @a.head !! Nil;
       if !c($e, $next) {
           take @group.clone;
           @group = ();

dd @a.&group-list(-> $left, $right { $right && $right.starts-with(' ')});

Here the conditional gets two elements to decide if they belong to the same group. It is also the first time I used .clone.

Thanks to a simple question I learned quite a bit. It forced me to think about the disadvantages of my first idea. Maybe code challenges should explicitly asked for more then one answer for the same question.

Categories: Raku

Double inspiration

October 9, 2021 2 comments

Quite a few of the posts prior to this one where inspired by a post of fellow blogger. I would like to double down on that today. Vadim wrangled with symbols and Fabio enjoyed renaming them. Having struggled with packages in the past, Vadim’s post was very helpful in making me realise, .HOW is how I can get hold of the object that is the package. And if Perl can do it, there is surely no way to stop Raku to have the same capability.

We want to re-export functions while changing their name. Just adding a prefix will do for now. That presents the first problem. Currently, there is no way to get named arguments to use handed to sub EXPORT. Any Hash will also be gobbled up. All we have are positional parameters. Since Raku is omni-paradigmatic, that wont pose a challenge.

use Transport {'WWW', :prefix<www->};

We can execute that block and use destructuring to get hold of the positional and any colonpair.

use v6.d;

sub EXPORT(&args) {
    my ($module-name, *%tags) = args;

    my \module = (require ::($module-name));
    my %exports = module.WHO<EXPORT>.WHO<DEFAULT>.WHO.&{.keys Z=> .values};
    my %prefixed-exports = { .key.substr(0, 1) ~ %tags<prefix> ~ .key.substr(1..*) => .value };


The only trouble I had was with .WHO being a macro and not a method of Mu. So we need a symbol to hold the package, which is returned by require.

dd &www-jpost;
# OUTPUT: Sub jpost = sub jpost (|c) { #`(Sub|94403524172704) ... }

I didn’t turn this into a proper module, yet. This needs more reading (what the Sub::Import is actually being used for) and thinking. A 1:1 translation from Perl seems to be the easy way and thus is likely not the most correct.

Categories: Raku


September 24, 2021 1 comment

Flavio wrote a straightforward solution to PWC-131-1 and wondered if there is a idiomatic way. Assuming, that “idiomatic” means to use language features which lesser languages refuse to require, I’m happy to deliver convoluted code.

use v6.d;

sub consecutive-a(*@a) {
    my @ret;

    gather {
        for (|@a, |@a.tail).rotor( 2 => -1 ) -> [$a, $b] {
            @ret.push: $a;
            unless $b == $a + 1 {
                take @ret;
                @ret = [];

sub consecutive-b(*@a) {
    my @gaps = @a.rotor(2 => -1).kv.grep(-> $index, [$a, $b] { $b !== $a + 1 })[*;0];
    return @a unless @gaps;
    @gaps = (@gaps Z @gaps »+» 1).flat;
    my $ranges := (0, @gaps, (@a - 1))> \l, \r { l .. r });


sub MAIN() {
    my @examples := (1, 2, 3, 6, 7, 8, 9)
                  ,(11, 12, 14, 17, 18, 19)
                  ,(2, 4, 6, 8)
                  ,(1, 2, 3, 4, 5);

    .&consecutive-a.say for @examples;
    .&consecutive-b.say for @examples;

Both exibits use .rotor to create easily comparable pairs of numbers. The first variant uses gather/take to return the by PWC requested sublists lazily. If we spot a gap take the list and empty the Array-container. If numbers are consecutive we add them to the return buffer. The laziness may help with very large lists.

The 2nd version creates a list of gaps. Since we can’t point in-between two elements, we first take the last index of the last element of a sub-list and then zip the following element, hoping the Array not to contain holes. The first and last index of @a are added. We now have a list of begin- and end-indices of the sub-lists. Those are composes to Range-objects. Such a list (Rakudo doesn’t like an Array in this case) can be used in Positional-subscripts to gain the desired sub-list of consecutive Ints. This solution can take a shortcut if no gaps are found.

I’m not entirely sure if this is better then a boring way to solve the task. It does provide a reason for another blog post, though. Quite helpful to reach 150 posts before the end of the year.

Categories: Raku

Calling by name

September 3, 2021 1 comment

While looking for something completely different, I found that Roast really likes named callable placeholder variables.

dex@dexhome:~/projects/raku/roast$ ack -l  '&\:'

That is hardly a surprise, given that the specs are composed of short snippets of code. Placeholder variables fit right in!

sub foo { "Good &:greeting(now.DateTime.hour) $:name!" };
say foo :name<Paul>, :greeting{$_ < 12 ?? 'morning' !! 'day'};
say &foo.signature;

# OUTPUT: Good day Paul!
          (:&greeting!, :$name!)

It’s really nice how interpolation and placeholders work together here. I have reported the ENODOC.

Even after years and years of being a Raku beginner, I still find new stuff when digging deep enough. Maybe it’s a good thing that we don’t have a Raku book. It would surely be backbreaking.

Categories: Raku

Dynamic declaration

August 24, 2021 1 comment

Shortly after my last blog post, Stashes raised a question. Coincidence? Conspiracy? You decide! Anyway, the EVAL caught my eye, because with it we can dynamically create compile time constructs such as a package.

our package EXPORTHOW {

sub EXPORT($declarator-name = 'registered') {
        package DECLARE {
            constant $declarator-name = MetamodelX::RegisteredHOW;

Thanks to be our-scoped, the package EXPORTHOW can be modified at runtime. The EVAL allows to define a constant at runtime. Runtime in this context, is when the use statement of a consuming module is executed.

use Registered 'remembered', :recall-types;

remembered Foo {
    method answer { 42 }
    method common { self.^name }

With this technique, we allow the user of a module to decide what symbols are being used for a declarator. Pretty handy, if a module is added late to a project, which might have occupied a given symbol already. Quite some time ago, I lamented a little lizmats decision to modify class with InterceptAllMethods. This is now a solvable problem.

I once believed Raku to be less dynamic then Perl. Looks like I have to reconsider.

Categories: Raku

Most fancy

August 17, 2021 Leave a comment

On Discord (yes, we are that cool) MrDispatch wished for a way to collect a bunch of classes right after their declaration. I believe, with the power of the MOP, we can go a step further and register the type-object even before the definition is finished.

class MetamodelX::RegisteredHOW is Metamodel::ClassHOW {
    our @registered;

    method new_type(|) {
        my \type = callsame;


    method remember_type(Mu \type) {
        @registered.push: type

    method recall-types {

sub recall-types is export(:recall-types) {

my package EXPORTHOW {
    package DECLARE {
        constant registered = MetamodelX::RegisteredHOW;

We introduce a new declarator registered that hooks up a new meta-class. It would be possible to overload class to register all classes in a compilation unit. For now, doing so would not be good conduct, because playing with EXPORTHOW is not quite lexical yet. The list of declared type objects will reside as a class-attribute inside the meta-class. We can access it through any type object or instance via .HOW or with the exported sub recall-types.

use v6.*;

use Registered :recall-types;

registered Foo {
    method answer { 42 }
    method common { self.^name }

registered Bar {
    method ohai { ‚Hello Universe!‘ }
    method common { self.^name }

say recall-types; # requires the import adverb :recall-types;
say recall-types».common;

# OUTPUT: [(Foo) (Bar)]
#         [(Foo) (Bar)]
#         [(Foo) (Bar)]
#         [Foo Bar]

There are plenty of other ways to implement a registry of types. Using a custom meta-class is the most fancy and flexible way. We could hook into many other things here too. Rakudo is a dynamic compiler for a dynamic language. It uses introspection much more then you do. Sometimes it introspects a package called EXPORTHOW for a key called DECLARE to create a keyword that is more classy then class.

Categories: Raku


August 13, 2021 2 comments

As stated before, I like to read code I didn’t write myself. Flavio had trouble with triples. One line stood out to me.

take @triple if $N == @triple.any;

This looks like a set-operation to me. But using $N ∈ @triple dropped one result. After some debugging I found the culprit.

.map({($_, $n / $_)});  # take it and its counterpart

This might look like a division but is actually a type cast to Rat.

say 1 ∈ (1/1, );
# OUTPUT: False

Rakudo implements set-operations as equivalence checks, not numerical equality. Quite in contrast to ==, eqv does a type check and Int aint’t Rat. This might explain that the mathematical inclined don’t use Set as much as I did expect them to. The type mismatch simply produces a result that is not useful to mathematicians.

As implemented right now, we can’t tell the set operators what we consider equality . With meta-operators and junctions, we can specify what operator we actually want to use. The set-operators are not meta-operators and at least for now, we can’t user define new meta-operators. However, we can lexically redefine ordinary operators.

proto sub infix:<(elem)>($, $, *% --> Bool:D) is pure {*}
multi sub infix:<(elem)>(Numeric:D \a, Iterable:D \listy --> Bool:D) {'∈', '') if;

    for listy -> \b {
        return True if a == b;


constant &infix:<∈> := &infix:<(elem)>;

proto sub infix:<(&)>(|) is pure {*}
multi sub infix:<(&)>(Iterable:D \lhs, Iterable:D \rhs) {'∩', '') if ||;

    my @result;

    for lhs -> \l {
        for rhs -> \r {
            @result.push: r if l == r;

    +@result ?? @result !! ∅

constant &infix:<∩> := &infix:<(&)>;

say 1 ∈ (1/1, );
say (42, 42/2, 42/3) ∩ (1, 21, 3);
# OUTPUT: True
#         Set(21)

The proto is needed, because we need to get rid of multi-candidates that are already present. A more general approach might be to have a &*SET-COMPARATOR that defaults to &infix:<cmp>. This would slow down a fairly simple operator by a factor of 13. I may still be able to write a module that takes a comparator and returns a host of operators. With proper macros this would be easy. Maybe next year.

For now I shall be evil and report back with success.

Categories: Raku

They returned an empty package

August 7, 2021 1 comment

I don’t like to solve maths-puzzles. I do like to read other folks solutions thought. You never know where to spot a new idiom. A good way to find them is to look for code that feels unusual.

method normalize (Numeric:D $sum = 1) {
  my $total = or return;
  my $factor = $sum / $total;
  %!pmf.values »*=» $factor;

I have never seen the construct in the first line, at least not in a method. The return is triggered when returns something falsesy, like 0. It protects the 2nd line from a division by zero by returning Nil. Let’s see if that actually works.

$cookie.multiply('Bowl 1', 0);
$cookie.multiply('Bowl 2', 0);
say 'probability it came from Bowl 1: ', $cookie.P('Bowl 1');

# OUTPUT: Attempt to divide by zero when coercing Rational to Str
            in sub MAIN at tbr-pmf.rakumod line 73
            in block <unit> at tbr-pmf.rakumod line 3

Well, it does blow up some place else. This is not an unreasonable scenario either. When I’m around, the likelihood of a cookie to come from bowl1 or bowl2 is indeed 0. Returning to normalize we can check what happens when a method that should return self returns Nil.

class C {
    method foo { Nil }


The cause of this mis-dispatch can be found in src/core.c/Nil.pm6:16:

method FALLBACK(| --> Nil) { }

Nil is the baseclass of Failure and as such will only throw when assigned to or used to gain values from a list. It’s purpose is to revert containers to their default value. In a numeric context it will warn and turn into 0. Eventually it might end up in a division and cause much grief. Dealing with a depressing lack of cookies could be done with a multi-method.

   multi method P ($key where { == 0 } ) {
   multi method P ($key) {
      die "no key '$key' in PMF" unless %!pmf{$key}:exists;
      return %!pmf{$key} /;

This works because self is an implicit part of the signature of a method (sans an explicit invocant).

Another thing I never seen before is the following gist method.

method gist () {
  return gather {
    take '---';
    for %!pmf.keys.sort -> $key {
      take "  «$key» {%!pmf{$key}}";

Using take to prefix the resulting list is quite neat. Using a gather-block avoids any nesting that might need flattening afterwards. In a gist-method it’s a bit wasteful though. We like to truncate lists after 100 elements in say. This could be done with a .head(100) after .keys. Or we skip the rather slow gather-block altogether (each take fires a control exception and Rakudo can not optimise those away yet).

method gist () {
  ( |'---', |%! { "  «$_» %!pmf{$_}" } ).head(100).join($?NL)

I like to avoid explicit flattening by using Slips. If the map-block gets complicated, this allows to sneak a .hyper in to gain some speed on large lists.

Please keep in mind that cookies are nice and Nil is shifty.

Categories: Raku

Only infinite elements

August 2, 2021 2 comments

Flavio solved a puzzle with an implementation that puzzled me. The following code appears not as idiomatic as such a simple problem should require.

sub simulation-round () {
   return [+] gather {
      loop {
         my $value = roll-die();
         take $value;
         last if $value < 3;

We tend to do our dice rolls with a simpler construct.

sub simulation-round () {
    [+] (1..6).roll(*).map({ last .Int if .Int < 3; .Int });

# OUTPUT: Cannot .sum a lazy list onto a Seq
#           in sub simulation-round at ETOOBUSY-2.raku line 4
#           in block <unit> at ETOOBUSY-2.raku line 7

Rakudo assumes that a lazy list must be infinite. This would catch many bugs but is not what I want in this case. Sadly we don’t have a build-in to say .lazy-but-finite. Neither do we got roles we could mixin. This might be the reason why it took me 10 minutes of staring‑at‑the‑code to find a solution.

[+] (1..6).roll(*).map({ last if .Int < 3; .Int })[^∞]

So we are asking for up to infinite elements of this infinite list to defuse the laziness. This smells of bad design and may warrant a problem solving issue.

The rest of my version is quite different because I wanted to shoehorn a .hyper in.

use v6.*;

unit sub MAIN($rounds = 1_000_000);

sub term:<🎲>() { (1..6).roll(*) };

sub simulation-round () {
    [+] 🎲.map({ last .Int if .Int < 3; .Int })[^∞];

my $total = (0..^$rounds).hyper(:degree(12), :batch(10000)).map({ simulation-round }).sum;

put ‚average gain: ‘, $total / $rounds;

I believe there is a life‑lesson to be learned. Laziness can be problematic if the compiler is less then virtuos.


As lizmat pointed out, last .Int requires v6.e.PREVIEW (v6.* will work too). Instead of [^∞] a simple .eager will do (but will break the title of the blog post). We can also use ^$rounds instead of (0..^$rounds) if we disambiguate with a space before the method call.

my $total = ^$rounds .hyper(:degree(12), :batch(10000)).map({ simulation-round }).sum;

Categories: Raku

Contextual addition

July 11, 2021 1 comment

I took the absence of complaint as silent consent and set forth to implement HyperWhatever in associative subscripts. To do so I setup a little bit of tooling to lower cognitive load. When writing code I like to hit F1 in Vim and have it do the right thing depending on context. Since Vim is not self aware yet, we have to tell it what to do to help us. To specify context we can add a line to a source file to define a pseudo filetype.

use v6.*;
use Test;

# tests for the changes to Rakudo go here

# vim: ft=rakudotest

We can then define a filetype based mapping in ~/.vimrc.

autocmd FileType rakudotest nmap <F1> :w<CR>:!./testcase %<CR>

Since I change Rakudo I need to run a local copy by forking on Github and cloning into a fresh directory. There I can place a small shellscript.

#! /bin/sh

test 0 -lt $(find src/ -newer install/bin/raku -iname '*.pm6' | wc -l)\
&& make clean all test install

install/bin/raku $1

With this little chain I can edit Rakudo files and then hit F1 in the file with the tests. Rakudo will be rebuild and the test file executed with the local Rakudo instance. The latter needs to be prepared with perl ./ --gen-moar --gen-nqp.

Since I wanted to put the new operators into v6.e I had to hunt down the spots where Rakudo needs the information what to put where. The new operator candidate goes into its own file in src/core.e/ which then has to be made known in tools/templates/6.e/core_sources. There are sanity test to avoid features to bleed from one version into another in t/02-rakudo/03-corekeys.t. This provided me with some bafflement, as institutional knowledge tends to do. I was mostly guided by error messages, which shows how important LTA is.

A few days ago we had a discussion about the one argument rule, where I claimed to have little difficulties with it. While implementing %your-hash{**}:deepkv I had to change my mind. The reason why the rule doesn’t bite me in practical code, is actually rooted in good testing.

    my $seen-J;
    my $seen-E;
    for %hash{**}:deepkv -> @deepkey, $value {
        $seen-J++ if @deepkey ~~ <J> && $value == 7;
        $seen-E++ if @deepkey ~~ <A D E> && $value == 3;
    is $seen-J, 1, 'seen leaf in {**}:deepkv';
    is $seen-E, 1, 'seen deep leaf in {**}:deepkv';

Here the destructuring of the return value of %hash{**}:deepkv only works when the operator returns exactly the right thing.

multi sub postcircumfix:<{ }>( \SELF, HyperWhatever, :$deepkv!, *%other ) is raw {
    sub recurse(\v, @keys){
        if v ~~ Associative {
            for v.kv -> \k, \v {
                recurse v, [@keys.Slip, slip k]
            take slip(@keys, v)

    gather for SELF.kv -> \k, \v {
        if v ~~ Associative {
            recurse(v, [k])
        } else {
            take slip([k], v)

Getting the right amount of Slip into the right places took half an hour (building Rakudo takes about 60s) and plenty of cursing. I hope this is a case of torturing the implementer on behalf of the user. When using test driven code that seems to happen automatically. I’m to lazy too write a fancy test, so I have the testee to be clever enough to satisfy it.

Since I couldn’t find any documentation on how to add features in specific language versions, I hope this to be helpful to those who seek the same.

Categories: Raku