Subsetting Blocks (or Callables in general)
Asked Answered
F

2

6

This question was originally posted by lookatme in the Perl6 IRC channel. The original intention is to constrain a Callable by using subsets or any other possible way. It works in signatures, however this:

subset WalkCb of Callable where *.signature ~~ :(Int $a); 
my WalkCb $x = sub (Int $a) { return $a; };

returns

«Type check failed in assignment to $x; expected WalkCb but got Sub (sub (Int $a) { #`(Sub...)␤  in block <unit> at <tmp> line 1␤␤»

Other variants of the declaration return similar messages. What would be the correct syntax?

Fustic answered 17/5, 2018 at 6:39 Comment(1)
FWIW, I have opened a Rakudo issue about this: github.com/rakudo/rakudo/issues/1836Verona
V
6

It appears the WhateverCode parsing messes up in this case. So if you specify a block in the where:

subset WalkCb of Callable where { .signature ~~ :(Int $) }
my WalkCb $x = sub (Int $a) { return $a; }

it appears to work as expected. Also note that I removed the ; at the end of the lines, as a } at the end of a line is also the end of a statement. And that I removed the "a" from the signature: the name of of positional parameters in signature smartmatching is ignored.

Verona answered 17/5, 2018 at 8:13 Comment(0)
B
7

A where constraint can take a block (lambda) or a statement.

… where { $_ == 42 }; # block
… where    * == 42;   # lambda
… where   $_ == 42;   # statement

The thing is that ~~ doesn't participate in the creation of WhateverCode lambdas (*)
So what you are really doing is creating a lambda of *.signature inside of a larger where statement (not lambda).

constant $lambda = *.signature;
subset WalkCb of Callable where $lambda ~~ :(Int $);

Which will of course never return True as the lambda has a signature of :(;; $ is raw)


So instead just write the statement form. (using implicit $_)

subset WalkCb of Callable where .signature ~~ :(Int $);
my WalkCb $x = sub (Int $a) { return $a }
say $x(42); # 42␤
Babs answered 17/5, 2018 at 15:20 Comment(0)
V
6

It appears the WhateverCode parsing messes up in this case. So if you specify a block in the where:

subset WalkCb of Callable where { .signature ~~ :(Int $) }
my WalkCb $x = sub (Int $a) { return $a; }

it appears to work as expected. Also note that I removed the ; at the end of the lines, as a } at the end of a line is also the end of a statement. And that I removed the "a" from the signature: the name of of positional parameters in signature smartmatching is ignored.

Verona answered 17/5, 2018 at 8:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.