Is there a Perl 6 equivalent of a byte array?

Not sure about the question, but is this what you're looking for?

my int8 @a = ^10;         # a native array of 8-bit signed bytes
sub frobnicate(int8 @b) { # a sub taking a native 8-bit array
    dd @b;
}
frobnicate @a;
# array[int8].new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

Perhaps this is helpful:

my \buffer = Buf.new: 'mystring'.encode: 'utf-8';
my \offset = 3;
my \mask   = 0x03;

sub mask-buffer-from-to (\mask,
                         \buffer,
                         \from = 0,
                         \to = buffer.end) {
  buffer[from..to]».&{ $_ +&= mask }
}
mask-buffer-from-to mask, buffer, offset;
say buffer; # Buf:0x<6d 79 73 00 02 01 02 03>

I've slashed sigils (used \ in variable declarations instead of $ etc.) to reduce clutter (slashing sigils means they're dropped after the declaration). My hope is that this makes it easier to read. Please let me know if that worked for you or if it actually made it harder.

The = 0 and = buffer.end bits in the sub's signature are defaults.

If you were reasonably familiar with P6 it would be obvious what the ».&{ $_ +&= mask } expression meant. But you're not, so I'll explain it.

Reading it in English, it means that, given the range of buffer elements on the left, iterate (in parallel if the compiler wishes to do so) over each element, bit-wise AND-ing each element with mask.

Reading it in computerese, in detail:

»

is a hyperoperator, the P6 distillation of SPMD.

» iterates the operand on its left (the left operand corresponds to the MD bit of SPMD) and applies the operation on its right (corresponding to the SP bit of SPMD) on each iteration.

Only use » if the SP and MD operands are SPMD safe, i.e. the individual operations don't interfere with each other. (If you're not sure, use something like a for loop or map instead.) In this case it's hopefully obvious to you that the operation (bitwise AND-ing each element with a mask) is SPMD safe.

To remember what this use of » does, just remember that it's a SPMD op and/or note how it shows two parallel > (to remind you it assumes parallel semantics, i.e. the compiler is free to parallelize it) with the leftside greater than the right side (to remind you that the left operand is a plural thing, i.e. it can and typically does have multiple elements, whereas the right is always just a single operation).

.

This is the method call operator. It calls the method on its right given the invocant on its left.

&

& immediately after a . forces the expression on the right of the & to be interpreted as a routine.

{ ... }

Braced code immediately after .& is interpreted as a closure (a routine). Inside the closure, $_ (which may be read as "this one") is aliased to each of the elements resulting from iterating the operand to the left of the ».&.

$_ +&= mask

This line is of the form LHS op= RHS. This form is shorthand for LHS = LHS op RHS. So the code in the closure is shorthand for:

$_ = $_ +& mask

i.e. "this one becomes this one bit-wise AND masked with mask".

I apologize to readers who find this answer confusing; please leave comments below and I will react accordingly, perhaps writing a completely different, simpler, new answer. My hope is that @madcrazydrumma finds it interesting and helpful.

Tags:

Arrays

Raku