<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Andrew Shitov</title>
    <description>The latest articles on DEV Community by Andrew Shitov (@andrewshitov).</description>
    <link>https://dev.to/andrewshitov</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1156302%2Fcbc65b3f-7688-49e1-864b-8e3ed1748660.jpeg</url>
      <title>DEV Community: Andrew Shitov</title>
      <link>https://dev.to/andrewshitov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/andrewshitov"/>
    <language>en</language>
    <item>
      <title>Raku: a language that counts to infinity (Part 2)</title>
      <dc:creator>Andrew Shitov</dc:creator>
      <pubDate>Sun, 30 Aug 2026 18:14:28 +0000</pubDate>
      <link>https://dev.to/andrewshitov/raku-a-language-that-counts-to-infinity-part-2-3ph7</link>
      <guid>https://dev.to/andrewshitov/raku-a-language-that-counts-to-infinity-part-2-3ph7</guid>
      <description>&lt;p&gt;In this part, let's look at infinite sequences from another angle: let's start collecting the values.&lt;/p&gt;

&lt;p&gt;First of all, Raku has a pair of built-in routines &lt;code&gt;gather&lt;/code&gt; and &lt;code&gt;take&lt;/code&gt;. They are useful when you need to collect data that's computed along the way. For example:&lt;/p&gt;

&lt;pre&gt;my &lt;a class="mentioned-user" href="https://dev.to/data"&gt;@data&lt;/a&gt; = &lt;strong&gt;gather&lt;/strong&gt; {
    for ^50 {
        my $value = 100.rand.Int;
        &lt;strong&gt;take&lt;/strong&gt; $value if 45 &amp;lt; $value &amp;lt; 55;
    }
}

say &lt;a class="mentioned-user" href="https://dev.to/data"&gt;@data&lt;/a&gt;;&lt;/pre&gt;

&lt;p&gt;The program prints a few random numbers between 45 and 55 (or none when unlucky). You don't know upfront how many numbers it will pick, but at least there's some limit: the loop body runs only 50 times, and the random numbers are less than 100.&lt;/p&gt;

&lt;p&gt;So, it's time to introduce some infinity into the code. The next program scans the number, but does not explicitly say how many of them the user will use later. The second line, for example, demands the first five items, and that's when the real computation happens:&lt;/p&gt;

&lt;pre&gt;my $data = gather for 1 .. ∞ { take $_ if 45 &amp;lt; $_ &amp;lt; 55 }
say $data[^5]; # (46 47 48 49 50)&lt;/pre&gt;

&lt;p&gt;Surprisingly, working with infinities makes the code clearer for the reader. You just describe what to do with data, but omit the length. The next snippet literally says “Convert the numbers to their squares”. You apply this rule to the infinite (but lazy) range &lt;code&gt;1 .. ∞&lt;/code&gt;, and only then you take the first five elements.&lt;/p&gt;

&lt;pre&gt;say (gather for 1 .. ∞ { take $_ × $_ }).head(5);&lt;/pre&gt;

&lt;p&gt;Once again, note that you first apply the action to an infinite sequence, and only then cut it to the size you need. Not vice versa (of course you can if you know when to stop; but sometimes you need the condition on the results rather than on the source). The program prints:&lt;/p&gt;

&lt;pre&gt;(1 4 9 16 25)&lt;/pre&gt;

&lt;p&gt;A similar approach is demonstrated in the next two lines:&lt;/p&gt;

&lt;pre&gt;say ([\+] 1 .. ∞)[^10];
say ([\*] 1 .. ∞)[^7];&lt;/pre&gt;

&lt;p&gt;Wait, how? Add up or multiply all the integer numbers, and then take the first few elements of one of the triangle metaoperator's results?!&lt;/p&gt;

&lt;p&gt;Yes, no problem. A couple of triangle metaoperators are only used to compute the values for the first few items, not for the whole infinity:&lt;/p&gt;

&lt;pre&gt;(1 3 6 10 15 21 28 36 45 55)
(1 2 6 24 120 720 5040)&lt;/pre&gt;

&lt;p&gt;Here is a slightly more complex program, but the principle is the same, you define a rule and allow it work for any number of items:&lt;/p&gt;

&lt;pre&gt;my &lt;a class="mentioned-user" href="https://dev.to/pascal"&gt;@pascal&lt;/a&gt; = [1], -&amp;gt; @p { [0, |@p Z+ |@p, 0] } ... ∞;
.say for &lt;a class="mentioned-user" href="https://dev.to/pascal"&gt;@pascal&lt;/a&gt;[^5];&lt;/pre&gt;

&lt;p&gt;The function in this case is an anonymous pointy block &lt;code&gt;-&amp;gt; @p { [0, |@p Z+ |@p, 0] }&lt;/code&gt;. The program prints five rows of Pascal's triangle:&lt;/p&gt;

&lt;pre&gt;[1]
[1 1]
[1 2 1]
[1 3 3 1]
[1 4 6 4 1]&lt;/pre&gt;

&lt;p&gt;By the way, you can also ask Raku to add up everything in &lt;code&gt;1 .. ∞&lt;/code&gt; and you'll get the correct answer: &lt;code&gt;Inf&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;say [+] 1 .. ∞;&lt;/pre&gt;

&lt;p&gt;Again and again we can see that things like &lt;code&gt;Inf&lt;/code&gt; and &lt;code&gt;∞&lt;/code&gt; are not black holes in Raku. They behave according to the task you are working on.&lt;/p&gt;

&lt;pre&gt;say &amp;lt;a b c&amp;gt; Z (1 .. ∞);&lt;/pre&gt;

&lt;p&gt;Even though one of the operands of &lt;code&gt;Z&lt;/code&gt; is an infinite range, the result is limited to the first three items, as the left operand is quite measurable:&lt;/p&gt;

&lt;pre&gt;((a 1) (b 2) (c 3))&lt;/pre&gt;

&lt;p&gt;But nobody can stop us from having infinite ranges on both sides of &lt;code&gt;Z&lt;/code&gt; and even making some computations on those as we did earlier. Just make sure you do not take too many:&lt;/p&gt;

&lt;pre&gt;say ((1 .. ∞) Z (1 .. ∞).map(* ** 2)).head(4);&lt;/pre&gt;

&lt;p&gt;This program prints the numbers with their squares:&lt;/p&gt;

&lt;pre&gt;((1 1) (2 4) (3 9) (4 16))&lt;/pre&gt;

&lt;p&gt;If you are curious why, remove the &lt;code&gt;map&lt;/code&gt; and confirm that this weird construct just gives you the same number twice:&lt;/p&gt;

&lt;pre&gt;((1 1) (2 2) (3 3) (4 4))&lt;/pre&gt;

&lt;p&gt;As homework, rewrite the last example without using the &lt;code&gt;Z&lt;/code&gt; metaoperator.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>tutorial</category>
      <category>raku</category>
      <category>infinity</category>
    </item>
    <item>
      <title>Raku: a language that counts to infinity (Part 1)</title>
      <dc:creator>Andrew Shitov</dc:creator>
      <pubDate>Sun, 16 Aug 2026 19:21:49 +0000</pubDate>
      <link>https://dev.to/andrewshitov/raku-a-language-that-counts-to-infinity-part-1-4h4l</link>
      <guid>https://dev.to/andrewshitov/raku-a-language-that-counts-to-infinity-part-1-4h4l</guid>
      <description>&lt;p&gt;We've already seen that Raku understands characters like &lt;code&gt;∞&lt;/code&gt;, and it would be logically that you can use them with ease, similar to any other constructs of the language.&lt;/p&gt;

&lt;p&gt;Take, for example, a sequence with no definite end. You define a pattern and take as many items as you need.&lt;/p&gt;

&lt;pre&gt;say (1, 1, * + * ... ∞)[^10];&lt;/pre&gt;

&lt;p&gt;Here, the pattern defines a Fibonacci sequence and we only take the first 10 elements of it:&lt;/p&gt;

&lt;pre&gt;(1 1 2 3 5 8 13 21 34 55)&lt;/pre&gt;

&lt;p&gt;You don't know upfront what the 10&lt;sup&gt;th&lt;/sup&gt; element will be, so just say that the sequence is defined by the rule &lt;code&gt;* + *&lt;/code&gt; and goes towards &lt;code&gt;∞&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Need a stop at a given point? You can make the stop rule explicit:&lt;/p&gt;

&lt;pre&gt;say 1, 1, * + * ...^ * &amp;gt; 100;&lt;/pre&gt;

&lt;p&gt;Here we see the same sequence, but it stops as soon as the next number overcomes 100:&lt;/p&gt;

&lt;pre&gt;(1 1 2 3 5 8 13 21 34 55 89)&lt;/pre&gt;

&lt;p&gt;If you want to manipulate data a bit more elaborate than just taking the first few items, save the whole infinite list in a variable, why not? Use it as any other array in a Raku program:&lt;/p&gt;

&lt;pre&gt;my &lt;a class="mentioned-user" href="https://dev.to/fib"&gt;@fib&lt;/a&gt; = 1, 1, * + * ... ∞;
say &lt;a class="mentioned-user" href="https://dev.to/fib"&gt;@fib&lt;/a&gt;[5];
say &lt;a class="mentioned-user" href="https://dev.to/fib"&gt;@fib&lt;/a&gt;[55];&lt;/pre&gt;

&lt;p&gt;The program prints the requested 5&lt;sup&gt;th&lt;/sup&gt; and 55&lt;sup&gt;th&lt;/sup&gt; items of the sequence:&lt;/p&gt;

&lt;pre&gt;8
225851433717&lt;/pre&gt;

&lt;p&gt;The main difference with other elements is that the sequence that &lt;code&gt;@fib&lt;/code&gt; hosts is &lt;em&gt;lazy&lt;/em&gt;. It only computes the values when you demand it. Raku offers an easy way to check if it's lazy indeed:&lt;/p&gt;

&lt;pre&gt;my &lt;a class="mentioned-user" href="https://dev.to/fib"&gt;@fib&lt;/a&gt; = 1, 1, * + * ... ∞;
say &lt;a class="mentioned-user" href="https://dev.to/fib"&gt;@fib&lt;/a&gt;.is-lazy; # True&lt;/pre&gt;

&lt;p&gt;Working with lazy computations is very similar to any other "non-infinite" data. It's possible to map the values of an infinite sequence, say, square the numbers:&lt;/p&gt;

&lt;pre&gt;my &lt;a class="mentioned-user" href="https://dev.to/squares"&gt;@squares&lt;/a&gt; = (1 .. ∞).map(* ** 2);
say &lt;a class="mentioned-user" href="https://dev.to/squares"&gt;@squares&lt;/a&gt;[^5];
say &lt;a class="mentioned-user" href="https://dev.to/squares"&gt;@squares&lt;/a&gt;[999];&lt;/pre&gt;

&lt;p&gt;The program first prints the first five squares and then the item number 999, which is 1000²:&lt;/p&gt;

&lt;pre&gt;(1 4 9 16 25)
1000000&lt;/pre&gt;

&lt;p&gt;Let's try filtering a lazy sequence:&lt;/p&gt;

&lt;pre&gt;say (1 .. ∞).grep(*.is-prime)[^10];
say (1 .. ∞).grep(*.is-prime).first(* &amp;gt; 1000);&lt;/pre&gt;

&lt;p&gt;In this case, not only the original sequence &lt;code&gt;1 .. ∞&lt;/code&gt; is lazy, but also it's filtered version &lt;code&gt;(1 .. ∞).grep(*.is-prime)&lt;/code&gt;. Use it in a similar manner as before:&lt;/p&gt;

&lt;pre&gt;(2 3 5 7 11 13 17 19 23 29)
1009&lt;/pre&gt;

&lt;p&gt;That's all for now. In Part 2, we'll see some more interesting things that you can do with lazy sequences.&lt;/p&gt;

</description>
      <category>code</category>
      <category>coding</category>
      <category>programming</category>
    </item>
    <item>
      <title>Raku: a language that speaks Unicode</title>
      <dc:creator>Andrew Shitov</dc:creator>
      <pubDate>Sun, 09 Aug 2026 17:58:02 +0000</pubDate>
      <link>https://dev.to/andrewshitov/raku-a-language-that-speaks-unicode-48ap</link>
      <guid>https://dev.to/andrewshitov/raku-a-language-that-speaks-unicode-48ap</guid>
      <description>&lt;p&gt;Raku is by design a language that supports Unicode.&lt;/p&gt;

&lt;p&gt;So, yes, Unicode is special for both Raku and Raku++. This all starts from the visible surface, like when you can type Greek letters and use math symbols — even easier than you do it in LaTeX (in case you know how to type in non-ASCII characters).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;say τ;                       
say ∞ &amp;gt; 10⁹⁹;

my \φ = (1 + sqrt 5) ÷ 2;
say φ;

say 2⁵;
say 5 ∈ (2, 3, 5, 7);

sub prefix:&amp;lt;∑&amp;gt;(@a) { [+] @a }
say ∑(1, 2, 3);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can run this program in your browser to see how it works &lt;a href="https://raku.online/play" rel="noopener noreferrer"&gt;using the Raku.js playground&lt;/a&gt;. You can also change it a bit to try other things.&lt;/p&gt;

&lt;p&gt;The above program was mostly about the characters that are available in the source code. But behind it, Raku knows the internal rules of the Unicode datasets, and the current Raku++ version comes with the embedded UCD 17 tables (Unicode Character Database). They are simply built in the source code, so all happens naturally.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my $family = "👨‍👩‍👧‍👦";
say $family.chars;    # 1   — one grapheme
say $family.codes;    # 7   — seven code points
say "noël".flip;      # lëon — the ë survives reversal
say "🇺🇦🇵🇱".chars;    # 2   — flags don't split
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The distinction between the number of codes and characters is mostly visible as soon as you leave the ASCII space. What's beyond it, it's the whole Universe of different rules, collations, normalisations, names, properties, etc.&lt;/p&gt;

&lt;p&gt;The good thing is that you do not need to think about all those Unicode internals when just using Raku and when just working with text. For example, converting to upper case has no difference in the code for "street" and "straße".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;say "straße".uc;  # STRASSE — one char becomes two
say "ﬃ".uc;      # FFI     — ligature expands
say "🐋".uniname; # WHALE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Diacritics are difficult because a single character (glyph) can be represented differently: say, as two distinct items for the letter and the accent, as well as as a single Unicode entry point. For Raku, it's not difficult at all.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;say "e\x[0301]" eq "é"; # True — NFG normalizes on creation
say "é".NFD.list;       # (101 769)
say "é".NFC.list;       # (233)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you know that Unicode has &lt;a href="https://andrewshitov.com/2019/09/09/all-unicode-digits-in-perl-6/" rel="noopener noreferrer"&gt;literally hundreds of characters&lt;/a&gt; marked as digits, you may also want to use similar nice characters in the programs. Unicode fractions, Roman numbers, all that has it's meaning and can even be used in place of Arabic digits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;say "½".unival + "⅓".unival;  # 0.833333
say "Ⅻ".unival;              # 12
say "五".unival;              # 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you ever learned Greek, you may remember that letter S looks differently depending on the position of the word. Raku knows it out of the box; the final lowercased sigma looks differently indeed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"ΣΊΣΥΦΟΣ".lc.say # prints σίσυφος
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Characters names and properties, &lt;a href="https://emojipedia.org/emoji-17.0" rel="noopener noreferrer"&gt;even weird&lt;/a&gt;, are reachable with ease.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;say "\c[ORCA]".uniprop("Age"); # 17.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Regexes (and thus grammars) are no exception.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;say "abc🐋def" ~~ /&amp;lt;:Emoji&amp;gt;/; # ｢🐋｣
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A couple of words about &lt;a href="https://github.com/ash/rakupp" rel="noopener noreferrer"&gt;Raku++&lt;/a&gt;. The first phase of its development was to target the compiler against Roast, which is a huge official test suite of the Raku programming language. In total, Roast includes about 90k tests in the Unicode sections. All of them pass under Raku++. Actually, &lt;a href="https://raku.online/spec/conformance/" rel="noopener noreferrer"&gt;having proper support&lt;/a&gt; of UCD 17 helped &lt;a href="https://raku.online/spec/dashboard/" rel="noopener noreferrer"&gt;to jump from 57% to 82%&lt;/a&gt; of Raku coverage, just so huge it is.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd68y1lnyvp1w6onvll5y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd68y1lnyvp1w6onvll5y.png" alt=" " width="799" height="299"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And before wrapping up, some homework for you. Below are two variants of the program that solves quadratic equations and — what is important for us today — uses a lot of non-ASCII characters. Well, and some other useful Raku features such as custom operators and junctions.&lt;/p&gt;

&lt;p&gt;Variant 1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sub prefix:&amp;lt;√&amp;gt;($x) {
    $x.sqrt
}
sub infix:&amp;lt;±&amp;gt;($p, $q) is equiv(&amp;amp;infix:&amp;lt;+&amp;gt;) {
    ($p + $q), ($p - $q)
}

my (\a, \b, \c) = 1, -4, 3;
if (my $D = b² − 4 × a × c) ≥ 0 {
    my @roots = (−b ± √$D) »÷» (2 × a);
    say @roots;
}
else {
    say "There are no real solutions";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Variant 2:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sub prefix:&amp;lt;√&amp;gt;($x) {
    $x.sqrt
}
sub infix:&amp;lt;±&amp;gt;($p, $q) is equiv(&amp;amp;infix:&amp;lt;+&amp;gt;) {
    ($p + $q) | ($p - $q)
}

my (\a, \b, \c) = 1, -4, 3;
if (my $D = b² − 4 × a × c) ≥ 0 {
    my $roots = (−b ± √$D) ÷ (2 × a);
    say $roots;
}
else {
    say "There are no real solutions";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First try to understand what the programs will print, and then run them in the playground. The first variant uses regular arrays to save results, but the in the second program &lt;code&gt;$root&lt;/code&gt; is a scalar and it's a junction that keep both roots at the same time.&lt;/p&gt;

</description>
      <category>raku</category>
      <category>rakulang</category>
      <category>programming</category>
      <category>unicode</category>
    </item>
    <item>
      <title>Raku: a Language Where 0.1 + 0.2 is 0.3</title>
      <dc:creator>Andrew Shitov</dc:creator>
      <pubDate>Sat, 18 Jul 2026 11:48:53 +0000</pubDate>
      <link>https://dev.to/andrewshitov/raku-a-language-where-01-02-is-03-2862</link>
      <guid>https://dev.to/andrewshitov/raku-a-language-where-01-02-is-03-2862</guid>
      <description>&lt;p&gt;Programming languages are fascinating. Even if you think that these are the last days when you need to write code yourself, that only gives you more time to enjoy the beauty.&lt;/p&gt;

&lt;p&gt;In this article I would like to showcase some of the small but astonishing features of Raku. Even if you never had a chance to install a compiler on your machine, you can run all the examples below in the online &lt;a href="https://raku.online/" rel="noopener noreferrer"&gt;Raku playground&lt;/a&gt; straight away.&lt;/p&gt;

&lt;h2&gt;
  
  
  0.1 + 0.2 == 0.3
&lt;/h2&gt;

&lt;p&gt;It is an obvious equation when written on paper, but when you employ floating-point arithmetic, you get a &lt;a href="https://0.30000000000000004.com/" rel="noopener noreferrer"&gt;collection of various answers&lt;/a&gt; – the price of the trade-off between speed, compactness, and exactness.&lt;/p&gt;

&lt;p&gt;In Raku, 0.1 + 0.2 equals 0.3 exactly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;say 0.1 + 0.2 == 0.3;   # True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://raku.online/#code=ARYA6f9zYXkgMC4xICsgMC4yID09IDAuMzsK" rel="noopener noreferrer"&gt;Run it in the online playground to confirm&lt;/a&gt;. In the rest of the article, I will use links like this: &lt;a href="https://raku.online/#code=ARYA6f9zYXkgMC4xICsgMC4yID09IDAuMzsK" rel="noopener noreferrer"&gt;🦋▶&lt;/a&gt; to point you to the playground with the code filled in. All you need is to press the Run button and see the magic.&lt;/p&gt;

&lt;p&gt;Similarly, &lt;code&gt;0.1 + 0.2 - 0.3&lt;/code&gt; is an exact zero. &lt;a href="https://raku.online/#code=ARUA6v9zYXkgMC4xICsgMC4yIC0gMC4zOwo" rel="noopener noreferrer"&gt;🦋▶&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All this is possible as Raku treats these numbers as belonging to the &lt;code&gt;Rat&lt;/code&gt; (rational) type of numbers. &lt;code&gt;0.1&lt;/code&gt; is a fraction &lt;code&gt;1/10&lt;/code&gt;. &lt;code&gt;0.2&lt;/code&gt; is the same as &lt;code&gt;1/5&lt;/code&gt;. And while &lt;code&gt;say 1/3&lt;/code&gt; does print a rounded &lt;code&gt;0.333333&lt;/code&gt;, that is only the display: underneath lives the exact &lt;code&gt;⅓&lt;/code&gt;, with the numerator and the denominator in easy reach &lt;a href="https://raku.online/#code=ASgA1_9zYXkg4oWTLm51bWVyYXRvcjsKc2F5IOKFky5kZW5vbWluYXRvcjsK" rel="noopener noreferrer"&gt;🦋▶&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;say ⅓.numerator;    # 1
say ⅓.denominator;  # 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And yes, Unicode fractions are understood, together with any kind of digits &lt;a href="https://raku.online/#code=AQ4A8f9zYXkg4oW3ICsg2aM7Cg" rel="noopener noreferrer"&gt;🦋▶&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;say ⅷ + ٣;   # 11
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ⅷ&lt;/code&gt; here is a single Unicode character – the small Roman numeral eight – and &lt;code&gt;٣&lt;/code&gt; is the Arabic-Indic digit three, the everyday three for hundreds of millions of people. Raku reads both as the numbers they are.&lt;/p&gt;

&lt;h2&gt;
  
  
  Superscripts are powers
&lt;/h2&gt;

&lt;p&gt;Raise a number to a power the way your maths teacher wrote it &lt;a href="https://raku.online/#code=ASIA3f9zYXkgMuKBtTsKc2F5IDXCsiArIDEywrIgPT0gMTPCsjsK" rel="noopener noreferrer"&gt;🦋▶&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;say 2⁵;               # 32
say 5² + 12² == 13²;  # True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second line is the 5–12–13 Pythagorean triple, checked in one readable line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integers have no ceiling
&lt;/h2&gt;

&lt;p&gt;An integer in Raku is as long as it needs to be. There is no 64-bit cliff to fall off, no special "big integer" import – the numbers simply grow &lt;a href="https://raku.online/#code=ATkAxv9zYXkgMsK54oGw4oGwOwpzYXkgMTDCueKBuCDDlyAxMMK54oG4OwpzYXkgWypdIDEgLi4gMTAwOwo" rel="noopener noreferrer"&gt;🦋▶&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;say 2¹⁰⁰;         # 1267650600228229401496703205376
say 10¹⁸ × 10¹⁸;  # 1 followed by 36 zeroes
say [*] 1 .. 100;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The square brackets in the last line are the reduction meta-operator: &lt;code&gt;[*]&lt;/code&gt; places &lt;code&gt;*&lt;/code&gt; between all the numbers of the range, so you get the factorial of 100 – all 158 digits of it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Primality included
&lt;/h2&gt;

&lt;p&gt;Number theory is on board too &lt;a href="https://raku.online/#code=ATAAz_9zYXkgOTcuaXMtcHJpbWU7CnNheSAoMsK5wrLigbcg4oiSIDEpLmlzLXByaW1lOwo" rel="noopener noreferrer"&gt;🦋▶&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;say 97.is-prime;          # True
say (2¹²⁷ − 1).is-prime;  # True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second number is a Mersenne prime of 39 digits, tested as casually as the small one. Notice the minus sign in &lt;code&gt;2¹²⁷ − 1&lt;/code&gt;: it is not the ASCII hyphen but the true Unicode minus, and Raku is perfectly happy with either.&lt;/p&gt;

&lt;h2&gt;
  
  
  Operators from the maths textbook
&lt;/h2&gt;

&lt;p&gt;Superscripts are not the only notation rescued from the maths textbook. The multiplication and division signs, and the comparison signs with the slash already crossed through, are all ordinary Raku operators &lt;a href="https://raku.online/#code=ATkAxv9zYXkgNyDDlyA2OwpzYXkgMTAgw7cgNDsKc2F5IDEg4omkIDIg4omkIDM7CnNheSAyIOKJoCAzOwo" rel="noopener noreferrer"&gt;🦋▶&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;say 7 × 6;      # 42
say 10 ÷ 4;     # 2.5
say 1 ≤ 2 ≤ 3;  # True
say 2 ≠ 3;      # True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;×&lt;/code&gt; and &lt;code&gt;÷&lt;/code&gt; are the real multiplication and division operators (the ASCII &lt;code&gt;*&lt;/code&gt; and &lt;code&gt;/&lt;/code&gt; work too, of course). Comparisons chain the way they do in mathematics: &lt;code&gt;1 ≤ 2 ≤ 3&lt;/code&gt; is a single condition, not a syntax error. And &lt;code&gt;10 ÷ 4&lt;/code&gt; is the familiar &lt;code&gt;Rat&lt;/code&gt; story again – the exact fraction &lt;code&gt;5/2&lt;/code&gt;, whose decimal display &lt;code&gt;2.5&lt;/code&gt; this time needs no rounding at all.&lt;/p&gt;

&lt;p&gt;Chaining also combines with the reduction meta-operator you met at the factorial: put &lt;code&gt;≤&lt;/code&gt; between the square brackets, and &lt;code&gt;[≤]&lt;/code&gt; chains it across every neighbouring pair of a list – a ready-made test that the list is sorted &lt;a href="https://raku.online/#code=K06sVIh-1LkkVsFQR8FIR8FUR8HSmqsYLmqsA5aw5gIA" rel="noopener noreferrer"&gt;🦋▶&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;say [≤] 1, 2, 5, 9;  # True
say [≤] 3, 1, 2;     # False
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  π, τ, and ∞
&lt;/h2&gt;

&lt;p&gt;The constants you know from school are predefined &lt;a href="https://raku.online/#code=ARsA5P9zYXkgz4A7CnNheSDPhCA9PSAyIMOXIM-AOwo" rel="noopener noreferrer"&gt;🦋▶&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;say π;           # 3.141592653589793
say τ == 2 × π;  # True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Type &lt;code&gt;pi&lt;/code&gt; and &lt;code&gt;tau&lt;/code&gt; if the Greek letters are far from your keyboard.) Infinity is a value in its own right: you can compare things with it, and you can build a range of &lt;em&gt;all&lt;/em&gt; positive integers and politely take the first five &lt;a href="https://raku.online/#code=ASoA1f9zYXkg4oieID4gMTDCueKBsOKBsDsKc2F5ICgxIC4uIOKInilbXjVdOwo" rel="noopener noreferrer"&gt;🦋▶&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;say ∞ &amp;gt; 10¹⁰⁰;     # True
say (1 .. ∞)[^5];  # (1 2 3 4 5)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The range is lazy, so nobody attempts to materialise the rest of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  And when you do want floating point
&lt;/h2&gt;

&lt;p&gt;Floats did not go anywhere – you ask for them with scientific notation &lt;a href="https://raku.online/#code=ARMA7P9zYXkgMC4xZTAgKyAwLjJlMDsK" rel="noopener noreferrer"&gt;🦋▶&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;say 0.1e0 + 0.2e0;  # 0.30000000000000004
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;0.1e0&lt;/code&gt; is a &lt;code&gt;Num&lt;/code&gt;, an honest IEEE double, and with it comes the famous constant from the beginning of this article. Floats remain the right tool for physics and simulations; Raku simply refuses to make them the default meaning of a decimal literal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this runs
&lt;/h2&gt;

&lt;p&gt;Every example above runs in the &lt;a href="https://raku.online/" rel="noopener noreferrer"&gt;raku.online&lt;/a&gt; playground, which is powered by &lt;a href="https://github.com/ash/rakupp" rel="noopener noreferrer"&gt;Raku++&lt;/a&gt;, an independent implementation of Raku compiled to WebAssembly – the interpreter works entirely in your browser page. The reference implementation of the language is &lt;a href="https://rakudo.org" rel="noopener noreferrer"&gt;Rakudo&lt;/a&gt;, and everything shown here prints exactly the same on both.&lt;/p&gt;

&lt;p&gt;The next article in this series opens the second cabinet of curiosities: Unicode – strings that count a seven-codepoint emoji as one character, a variable named &lt;code&gt;$Δ&lt;/code&gt;, and a file called &lt;code&gt;café-☕.txt&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>raku</category>
      <category>rakupp</category>
      <category>math</category>
      <category>unicode</category>
    </item>
    <item>
      <title>Sorting numbers in Raku with the help of ChatGPT</title>
      <dc:creator>Andrew Shitov</dc:creator>
      <pubDate>Fri, 08 Sep 2023 07:57:21 +0000</pubDate>
      <link>https://dev.to/andrewshitov/sorting-numbers-in-raku-with-the-help-of-chatgpt-4279</link>
      <guid>https://dev.to/andrewshitov/sorting-numbers-in-raku-with-the-help-of-chatgpt-4279</guid>
      <description>&lt;p&gt;In this post I will show you the solution to the &lt;a href="https://theweeklychallenge.org/blog/perl-weekly-challenge-233/#TASK2"&gt;Task 2 of this week’s Weekly Challenge 233&lt;/a&gt;. This time I was using the help of ChatGPT, which offered a very nice solution.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You are given an array of integers.&lt;br&gt;
Write a script to sort the given array in increasing order based on the frequency of the values. If multiple values have the same frequency then sort them in decreasing order.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I asked ChatGPT the following: ‘Create a program. Here is the description of the task.’ To make sure the result is in the Raku programming language, I also added the following instruction in my local settings so that it knows which programming language I prefer by default.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WpQcrjqz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qwmso4rxp5iti24b26gg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WpQcrjqz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qwmso4rxp5iti24b26gg.png" alt="Image description" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The solution generated by ChatGPT was quite good with a small mistake.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ChatGPT: Sure, here’s a Raku program that implements the described sorting algorithm for the given task:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sub frequency-sort(@arr) {
    my %freq;

    %freq{$_}++ for @arr;
    my @sorted = @arr.sort: {
        %freq{$^b} &amp;lt;=&amp;gt; %freq{$^a} ||
        $^b &amp;lt;=&amp;gt; $^a
    };

    return @sorted;
}

my @ints = (1, 1, 2, 2, 2, 3);
my @sorted = frequency-sort(@ints);

say "Input:  @ints";
say "Output: @sorted";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, Raku would not interpolate arrays, so &lt;code&gt;say "Input: @ints"&lt;/code&gt; prints the string literary: &lt;code&gt;Input: @ints&lt;/code&gt;. Second, in the sorting rule, sorting by frequency must be ascending rather than descending, so we need to switch the placeholder variables &lt;code&gt;$^b&lt;/code&gt; and &lt;code&gt;$^a&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the rest, ChatGPT did a good work. It computed the frequency using a loop, and I especially liked how it addressed the requirement to sort by two dimensions.&lt;/p&gt;

&lt;p&gt;Here is the full program with the above-mentioned corrections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sub frequency-sort(@arr) {
    my %freq;
    %freq{$_}++ for @arr;

    my @sorted = @arr.sort: {
        %freq{$^a} &amp;lt;=&amp;gt; %freq{$^b} ||
        $^b &amp;lt;=&amp;gt; $^a
    };

    return @sorted;
}

my @tests =
    (1, 1, 2, 2, 2, 3),
    (2, 3, 1, 3, 2),
    (-1, 1, -6, 4, 5, -6, 1, 4, 1);

say frequency-sort($_) for @tests;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This program prints the following output for the given test cases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ raku ch-2.raku
[3 1 1 2 2 2]
[1 3 3 2 2]
[5 -1 4 4 -6 -6 1 1 1]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>raku</category>
      <category>algorithms</category>
      <category>challenge</category>
      <category>rakulang</category>
    </item>
  </channel>
</rss>
