Perl & Raku: Best frenemies
Tags: perl, raku, rakulang, rss
Published: 2021-08-17 18:03:24

---
title: Perl & Raku: Best frenemies
published: true
date: 2021-08-17 14:00:00 UTC
tags: Perl,Raku,RakuLang,RSS
canonical_url: https://phoenixtrap.com/2021/08/17/perl-raku-best-frenemies/
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nwdmnh3mhnzd8617ixi5.jpg
series: Perl and Raku
---

The Perl and Raku programming languages have a complicated history together. The latter was [envisioned in the year 2000](https://www.perl.com/pub/2000/07/perl6.html/) as Perl 6, a complete redesign and rewrite of Perl to solve its problems of difficult maintenance and the burden of then-13 years of backward compatibility. Unfortunately, the development effort towards a first major release dragged on for ten years, and some developers began to believe the delay contributed to the decline of Perl’s market- and mindshare among programming languages.

In the intervening years [work continued on Perl 5](https://phoenixtrap.com/2021/05/25/perl-can-do-that-now/), and eventually, Perl 6 was [positioned](https://www.perl.org/) as “a sister language, part of the Perl family, not intended as a replacement for Perl.” Two years ago it was [renamed Raku](https://lwn.net/Articles/802329/) to better indicate it as a different project.

Although the two languages aren’t source-compatible, the [Inline::Perl5](https://modules.raku.org/dist/Inline::Perl5:cpan:NINE) module does enable Raku developers to run Perl code and use Perl modules within Raku, You can even subclass Perl classes in Raku and call Raku methods from Perl code. I hadn’t realized until recently that the Perl support was so strong in Raku despite them being so different, and so I thought I’d take the opportunity to write some sample code in both languages to better understand the Raku way of doing things.

Rather than a simple [“Hello World” program](https://en.wikipedia.org/wiki/%22Hello,_World!%22_program), I decided to write a simple syndicated news reader. The [Raku modules directory](https://modules.raku.org/) didn’t appear to have anything comparable to Perl’s [WWW::Mechanize](https://metacpan.org/pod/WWW::Mechanize) and [XML::RSS](https://metacpan.org/pod/XML::RSS) modules, so this seemed like a great way to test Perl-Raku interoperability.

## Perl Feed Finder

First, the Perl script. I wanted it smart enough to either directly fetch a news feed or find it on a site’s HTML page.

{% gist https://gist.github.com/mjgardner/a654985916476b0608ffd497e19d998b %}

In the beginning, you’ll notice there’s a bit of boilerplate: `use v5.24` ([released in 2016](https://perldoc.perl.org/perl5240delta)) to enable [restricting unsafe code](https://perldoc.perl.org/strict), the [`say`](https://perldoc.perl.org/functions/say) function, and [postfix dereferencing](https://perldoc.perl.org/perlref#Postfix-Dereference-Syntax) to reduce the noise from nested curly braces. I’m also bringing in the [`first`](https://metacpan.org/pod/List::Util#first) and [`none`](https://metacpan.org/pod/List::Util#none) [list processing](https://phoenixtrap.com/2021/05/18/a-list-of-perl-list-processing-modules/) functions from [List::Util](https://metacpan.org/pod/List::Util) as well as the WWW::Mechanize web page retriever and parser and the XML::RSS feed parser.

Next is an array of possible [media (formerly MIME) types](https://www.iana.org/assignments/media-types/media-types.xhtml) used to serve the [RSS news feed format](https://en.wikipedia.org/wiki/RSS) on the web. Like Perl and Raku, RSS formats have a [long and sometimes contentious history](https://en.wikipedia.org/wiki/History_of_web_syndication_technology), so a newsreader needs to support several different ways of identifying them on a page.

The program then creates new WWW::Mechanize (called a _mech_ for short) and XML::RSS objects for use later and gets a URL to browse from its command-line argument, defaulting to [my blog](https://phoenixtrap.com) if it has none. _(My site, my rules, right?)_ It then retrieves that URL from the web. If mech believes that the URL [contains an HTML page](https://metacpan.org/pod/WWW::Mechanize#%24mech-%3Eis_html()) and can find `link` tags with `rel="alternate"` attributes possibly identifying any news feeds, it then goes on to check the media types of those links against the earlier list of RSS types and retrieves the first one it finds.

Next comes the only error checking done by this script: checking if the retrieved feed’s media type actually matches the list defined earlier. This prevents the RSS parser from attempting to process plain web pages. This isn’t a large and complicated program, so the die function is called with a trailing newline character (`\n`) to suppress reporting the line on which the error occurred.

Finally, it’s time to output the headlines and links, but before that happens Perl has to be told that they may contain so-called “wide characters” found in the [Unicode standard](https://home.unicode.org/) but not in the plain [ASCII](https://en.wikipedia.org/wiki/ASCII) that it normally uses. This includes things like the typographical ‘curly quotes’ that I sometimes use in my titles. The last two lines of the script loop through the parsed items in the feed, extracting their titles and links and printing them out with a tab (`\t`) separator between them:

![Output from feed_finder.pl](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/epa9p1qtjaijhce65tfz.jpeg)

## Raku Feed Finder

Programming is often just stitching libraries and APIs together, so it shouldn’t have been surprising that the Raku version of the above would be so similar. There are some significant (and sometimes welcome) differences, though, which I’ll go over now:

{% gist https://gist.github.com/mjgardner/094b6c90e5957b5d336aa2dc3496f826 %}

The first thing to notice is there’s a bit less boilerplate code at the beginning. Raku is a younger language and doesn’t have to add instructions to enable less backward-compatible features. It’s also a larger language with functions and methods built-in that Perl needs to load from modules, though this feed finder program still needs to bring in WWW::Mechanize and XML::RSS with annotations to indicate they’re coming from the `Perl5` side of the fence.

I decided to wrap the majority of the program in a [`MAIN`](https://docs.raku.org/language/create-cli#index-entry-MAIN) function, which handily [gives me command line arguments as variables](https://docs.raku.org/language/create-cli#Calling_a_provided_MAIN_subroutine_using_that_capture) as well as a [usage message](https://docs.raku.org/language/create-cli#Creating_/_showing_usage_information_if_calling_MAIN_failed) if someone calls it with a `--help` option. This is a neat quality-of-life feature for script authors that cleverly reuses function signatures, and I’d love to see this available in Perl as an extension to its [signatures](https://perldoc.perl.org/perlsub#Signatures) feature.

Raku and Perl also differ in that the former [has a different concept](https://docs.raku.org/language/contexts) of [context](https://perldoc.perl.org/perldata#Context), where an expression may be evaluated differently depending upon whether its result is expected to be a single value (scalar) or a list of values. Inline::Perl5 calls Perl functions in list context by default, but you can add the `Scalar` type object as a first argument to force scalar context as I’ve done with calls to [`find_all_links`](https://metacpan.org/pod/WWW::Mechanize#$mech-%3Efind_all_links(-...-)) (to return an array reference) and [content_type](https://metacpan.org/pod/WWW::Mechanize#$mech-%3Ect()-/-$mech-%3Econtent_type()) (to [return the first parameter](https://metacpan.org/pod/HTTP::Headers#$h-%3Econtent_type) of the HTTP Content-Type header).

Another interesting difference is the use of the [`(elem)`](https://docs.raku.org/routine/(elem),%20infix%20%E2%88%88) operator to determine membership in a set. This is Raku’s ASCII way of spelling the ∈ symbol, which it can also use; `!(elem)` can also be spelled [∉](https://docs.raku.org/routine/%E2%88%89). Both are hard to type on my keyboard so I chose the more verbose alternative, but if you want your code to more closely resemble mathematical notation it’s nice to know the option is there.

I also didn’t use Raku’s [`die`](https://docs.raku.org/routine/die) routine to exit the program with an error, mainly because of its method of suppressing the line on which the error occurred. It requires [using a `CATCH` block](https://docs.raku.org/language/exceptions#index-entry-CATCH) and then keying off of the type of exception thrown in order to customize its behavior, which seemed like overkill for such a small script. It would have looked something like this:

```raku
{
    die $mech.uri ~ ' does not have an RSS feed'
        if $response.content_type(Scalar) !(elem) @rss_types;
    CATCH {
        default {
            note .message;
            exit 1;
        }
    }
}
```

Doubtless, this could be [golfed](https://en.wikipedia.org/wiki/Code_golf) down to reduce its verbosity at the expense of readability, but I didn’t want to resort to clever tricks when trying to do a one-to-one comparison with Perl. More experienced Raku developers are welcome to set me straight in the comments below.

The last difference I’ll point out is Raku’s welcome lack of [dereferencing](https://perldoc.perl.org/perlref#Using-References) operators compared to Perl. This is due to the former’s concept of [containers](https://docs.raku.org/language/containers), which I’m [still learning about](https://docs.raku.org/language/5to6-nutshell#Creating_references_and_using_them). It seems to be fairly [DWIM](https://en.wikipedia.org/wiki/DWIM)my so I’m not that worried, but it’s nice to know there’s an understandable mechanism behind it.

Overall I’m pleased with this first venture into Raku and I enjoyed what I’ve learned of the language so far. It’s not as different with Perl as I anticipated, and I can foresee coding more projects as I learn more. The community on the [`#raku` IRC channel](https://web.libera.chat/#raku)was also very friendly and helpful, so I’ll be hanging out there as time permits.

What do you think? Can Perl and Raku better learn to coexist, or are they destined to be rivals? Leave a comment below.

* * *

_Cover image: [“Frenemies 2”](https://www.flickr.com/photos/38631185@N06/5551846737) by [Mauricio Delgado](https://www.flickr.com/photos/38631185@N06) is licensed under [CC BY-SA 2.0](https://creativecommons.org/licenses/by-sa/2.0/?ref=ccsearch&atype=rich)_.