Here is an experiment with Raku:
> my $x
(Any)
> my $y=1
1
> my @a=[1, 2]
[1 2]
> my %h=a=>\'b\'
{a => b}
> say \"nil\" unless $x
nil
>
In addition to lizmat's excellent answer, it's probably relevant to explain what's going on here.
When you say my $foo, you're effectively saying my Any $foo.1 And when you say my @foo, you're implicitly saying something closer to my Any @foo which is the same as my Array[Any] $foo (but in a positional container). That lets you put anything into the array, because it's typed, well, as Any.
When you access an object that's undefined, it returns an undefined value — but that value is still typed. It just happens that by default, the type is Any. We could, however, change some things and it would probably become clearer:
my Str $foo;
say $foo; # a Str that's undefined, so '(Str)';
my $bar; # implicitly typed Any
say $bar; # an Any that's undefined, so '(Any)';
my Int @foo = 0, 1, 2;
say @foo[0]; # an Int defined as 0, so '0'
say @foo[1]; # an Int defined as 1, so '1'
say @foo[3]; # an Int that's undefined, so '(Int)'
As lizmat pointed out in her answer, (Type) is the default representation of the .gist method, which is used by .say, for undefined values.2
The reason that they don't return Nil is because by definition, Nil returns Nil for every method that's called upon it (with a few exceptions like Bool where it returns False) — it's sort of like Objective-C's nil. But an undefined type object still has uses: for instance, you can still call methods on it, as long as they don't access attributes. There are some times where that can be a very useful property, and it's what actually enables you to do something like:
my Foo $foo .= new;
Which is syntactical sugar for
my Foo $foo;
$foo = $foo.new;
$foo is a an undefined type object, so we actually still call Foo.new.