raku types
01.11.2023 2 min readWell, I ended up playing with Raku a little bit more, even though I said I probably wouldn’t. And… I quite like it. I’ve built a few (smol) CLI apps with it (it’s really quick and easy!). I still find it hard to read… but, idk. I like the idea of TIMTOWTDI, especially in a personal setting. I don’t want to be writing Go code at home - it does not spark joy.
Anyway. I digress. Back to Raku.
I’ve been playing around with the type system a bit, and it works a little differently than other type systems I’ve worked with (Nim, Typescript). In Nim or Typescript, you would have to denote the type of a variable, and the types that the variable contains.
const myArr: number[] = [1, 2, 3, 4, 5];
const mySeq: seq[int] = @[1, 2, 3]
However, in Raku, you just specify the types that the container holds - i.e. an @
sigil already denotes that something will be an array, so you just specify the types that the array will contain. Here’s an example:
my Int @arr = [1, 2, 3, 4, 5];
@arr.WHAT; # (Array[Int])
Declaring the types for a subroutine’s arguments are no different:
sub my-sub(Int @arr) {...}
However, there’s a little gotcha to be aware of. I was struggling with this for the longest time. Why doesn’t the following example work?
sub my-sub(Int @arr) {...}
my-sub([1, 2, 3, 4, 5]);
This is because we are passing in an array literal to my-sub
. And because it’s an array literal, it doesn’t contain any type information that says it’s an Array[Int]
. In Raku, arrays can hold different types of variables, which means that the fact that our array only holds integers is purely coincidental. It is not an Array[Int]
unless we say so beforehand. So, to get this to work, what we really need is this:
sub my-sub(Int @arr) {...}
my Int @arr = [1, 2, 3, 4, 5];
my-sub(@arr);
And everything works as it should.