Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type capture for positional arguments

Type captures are a cool thing to use for even some simple stuff:

sub assert-same(::T $a, T $b) { ; }

assert-same 1, 2;   # silent 
assert-same 1, "a"; # type check error

However, the result is non-intuitive for positionals. If I have the following signature

sub foo(Str @bar, Str @xyz) { ; }

Then @bar is a positional whose elements must be Str, as is @xyz. But if I use a type capture, things go weird:

sub assert-same(::T @a, T @b) { ; }

my Str @x = <i j>;
my Str @y = <x y>;

assert-same @x, @y; 
# Type check failed in binding to parameter '@b';
# expected Positional[Array[Str]] but got Array[Str] (Array[Str].new("x", "y"))

It seems that the first type capture is capturing via .WHAT (which makes sense for scalars) rather than .of which to me is the intuitive sense for positionals, given that the immediate reuse of the capture would only work if .of had been originally used.

This smells of a bug, but if it's by design, is there a way to enforce via type capture that two typed positionals have elements that are of the same type? In the meantime, I can use

sub assert-same(::T @a, @b where .all ~~ @a.of ) { ; }

my Str @x = <a b c>;
my Str @y = <x y z>;
my Int @i = 1,2,3;
assert-same @x, @y; # silent 
assert-same @x, @i; # type check

But that seems a bit silly.

like image 201
user0721090601 Avatar asked Aug 20 '19 14:08

user0721090601


1 Answers

I think there are many bugs lurking in this area. I posted these a couple weeks ago:

  • (::T $, T @) yields "Internal error: inconsistent bind result"

  • sub foo (::T $, Array[T] $) { }; foo Int, Array[Int] yields "expected Array[T] but got Array[Int]";

I searched RT and the GH rakudo issues queue before posting them. In the latter I mention "cf #2595 and other type capture bugs". Maybe it's already in there; if not, please add an issue. TIA.

like image 81
raiph Avatar answered Oct 29 '22 15:10

raiph