Skip to content

Instantly share code, notes, and snippets.

@uzluisf
Last active May 29, 2023 23:54
Show Gist options
  • Save uzluisf/b3539dbf95ad6b1e158313f4646e6c05 to your computer and use it in GitHub Desktop.
Save uzluisf/b3539dbf95ad6b1e158313f4646e6c05 to your computer and use it in GitHub Desktop.
Sigilless and Sigilled Variables in Raku

Sigilless and Sigilled Variables in Raku

There are several differences between sigilless and sigilled variables, which are already documented in the Raku docs. This is simply my attempt at consolidating them in a single place.

Sigil

At the surface, a sigil or lack thereof is the most apparent difference between sigilless and sigilled variables. As their names imply, sigilless variable don't have sigils while sigilled variables do.

my \degrees = pi / 180;
my $angle = 90;

Sigilless variables are declared using the \ prefix, which is dropped when using the variables. For sigilled variables, the sigil is part of the variable's name and thus must be used when both declaring a variable and using it.

say degrees;
say $angle;

Binding

Sigilless variables are bound by default. You can bind sigilless variables with both the binding operator := and the assignment operator =; both operators have the same effect.

my \a  = 42;
my \b := 42;

In order to bind to a sigilled variable, you must use the binding operator :=.

my $c := 42;

Unlike sigilless variables, you can always re-bind sigilled variables.

my $c := 42;
$c := 45; # Ok!

To prevent re-binding to a sigilled variable, you can declare it as a constant.

my constant $d := 42;
$d := 45; # Cannot bind to '$d' because it was bound in a signature and variables
          # bound in signatures cannot be rebound unless they were declared with the
          # 'is rw' or 'is copy' traits

Container

A more striking difference between sigilless and sigilled variables is the fact sigilless variables do not have associated containers.

my \a = 42;
my $b = 42;

say  a.VAR.^name; # 42
say $b.VAR.^name; # Scalar

If the value bound to the sigilless variable is containerized, then its container will be the variable's container.

my \c = [1, 2];
my @d = [1, 2];

say  c.VAR.^name; # Array
say @d.VAR.^name; # Array

Assignment

Whether or not you can assign to a sigilless variable ultimately depends on what's bound to it. If it's an immutable structure (i.e., no container), as shown here with an Int, then you cannot assign to it once it's been declared.

my \a = 42;
a = 84;  # Error: Cannot modify an immutable Int (42) 

If you bind a mutable structure to the sigilless variable, you can assign to the variable once it's been bound.

my \f = [1, 2];
say f; # [1, 2]
f = [4, 5];
say f; # [4, 5]

Here, the circumfix operator [] creates an Array, which is mutable by design and thus allows for assignments.

With assignment sigilled variables create containers by default, thus you can update a variable's value through subsequent assignment.

my $b = 42;
$b = 21;

Context

Unlike sigilled variables, sigilless variables don't enforce context.

my \list = (1, 2, 3);
for list { .say }
# OUTPUT:
# 1
# 2
# 3

my $item = (1, 2, 3);
for $item { .say }
# OUTPUT:
# (1 2 3)

Assigning to a scalar variable $ means the content is itemized (i.e., a single thing), shown by $item which when looped produces a single item, i.e., the list (1, 2, 3) itself. In contrast, the list in list isn't itemized and the for loops over its elements.

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment