cat
cat

Reputation: 4030

How is this Perl sensical, considering Perl 6's type system?

I was gonna edit this into my other related question, but it feels different enough and I don't want to ask too many questions per question.


My mind... has exploded.

Consider:

use strict;

my Int $n = 6;
my Str $x = "a";
my @l = $n, $x;
say @l ~~ List;

Prints True, as expected.

Consider, then:

use strict;

my Int $n = 6;
my Str $x = "a";
my List @l = $n, $x; # <-- only change is the type notation
say @l ~~ List;

Which dies with:

Type check failed in assignment to @l; expected List but got Int

So... the type of List is List but I can't say it's List because that's a sin!

What's going on here? Is this a bug? Or am I bringing my irrelevant Python and Go idioms to Perl and breaking things?

Upvotes: 11

Views: 288

Answers (2)

Christoph
Christoph

Reputation: 169713

my List @l;

is shorthand notation for

my @l is Array of List;

which places a List type constraint on the elements of the array.

The type constraint on the container is already expressed via the @ sigil, corresponding to the role Positional, whereas a % sigil corresponds to the role Associative.

The case of $ variables is similar insofar as there's also a container involved (a Scalar) with a constraint on its single element. However, the constraint also allows direct rebinding to a decontainerized value1.


1 If the above does not make sense to you, you should look into the difference between assignment = and binding :=. It might also be instructive to inspect the variable via .VAR.WHAT.

Note that we can also rebind to another scalar container as long as its element meets the type constraint at time of binding.

This can be used to subvert the type system:

my Int $a;
my $b = 42;
$a := $b;
$b = "not cool";
say $a;

Not cool :(

Upvotes: 10

darch
darch

Reputation: 4311

my List @l = $n, $x;

doesn't do what you think it does. It doesn't declare that @l is a List. It declares that the elements of @l will be Lists. You don't need to declare that @l will be an array; you already did that when you used the sigil.

You can move the explosion around by replacing List with Int to make Perl 6 expect a list of Ints.

Upvotes: 12

Related Questions