Re: callbacks with placeholder vars

2021-08-09 Thread Patrick R. Michaud
On Mon, Aug 09, 2021 at 01:00:52PM -0700, Joseph Brenner wrote:
> There's this much:
> 
> https://docs.raku.org/language/variables#index-entry-$$CIRCUMFLEX_ACCENT
> 
> > If you have self-declared a parameter using $^a once, you may refer to it 
> > using only $a thereafter.
> 
> But it doesn't go anywhere near far enough.   You *had better* to
> refer to it as $a or you'll get some very weird behavior, though only
> under some circumstances.

Just to clarify (because I'm not sure this is clear yet):

You get "weird" behavior if you try to use it in the $^a form in a nested 
block, because the language treats any caret variables in the nested block as 
being part of the signature definition for the nested block.

So, going to the original "if" example, writing

   { 
 if ($^a eq $^b) {
   "$^a";
 } else {
   "$^a & $^b";
 }
   }

is akin to writing

   -> $a, $b {
 if ($a eq $b) -> $a {
   "$a";
 } else -> $a, $b {
   "$a & $b";
 }
   }

Each of the nested blocks is effectively defining a local $a (and $b), and the 
error is because the else clause sends only one argument to the block where two 
are expected.

The if statement and its clauses receive the result of the comparison as 
arguments to the nested blocks, if I remember correctly.  This is why "else" 
sends only one argument to its nested block.

Hope this helps a bit,

Pm
  


Re: callbacks with placeholder vars

2021-08-09 Thread Joseph Brenner
There's this much:

https://docs.raku.org/language/variables#index-entry-$$CIRCUMFLEX_ACCENT

> If you have self-declared a parameter using $^a once, you may refer to it 
> using only $a thereafter.

But it doesn't go anywhere near far enough.   You *had better* to
refer to it as $a or you'll get some very weird behavior, though only
under some circumstances.


Re: callbacks with placeholder vars

2021-08-09 Thread Joseph Brenner
Okay, so my central confusion here has to do with not
understanding that the caret gets used *only once* in
a construct like this:

   my $cb =  {
do if ($^a eq $^b)  {
 "$a";
} else {
 "$a & $b";
}
};
say $cb( 'a', 'b' );


After $^a is used, then $a is declared, and you use that form.

So, if you think of $^a as just a funny variable name, you'll get
tripped up in the ways I was, because if you use it again in
the sub-blocks of the if/else, it thinks you're trying to tell
it something about the calling signature for the sub-blocks.

You can however use the "$^a" form repeatedly if you're *not*
using any sub-blocks though, as in the ternary form I was playing
with.

I don't think this usage is very well described anywhere, though
you can argue you should just Get It if you understand that the
caret is a twigil.

And I still think the messaging here is more than a little LTA.


callbacks with placeholder vars

2021-08-09 Thread Joseph Brenner
Here's a simple use of a callback that just works:

my $cb =  {
 "$^a & $^b";
};
say $cb('a', 'b');  # a & b

Just as an aside, it's interesting that this would be an error:

say $cb('a', 'b', 'c');
# Too many positionals passed; expected 2 arguments but got 3

The number of placeholder vars inside the block gives it an
implicit arity, despite the absence of any explicit signature.

You can of course do more complex things, e.g. using this ternary conditional:

my $cb = {
 ($^a eq $^b) ?? "$^a" !! "$^a & $^b";
};
say $cb( 'a', 'b' );   # a & b
say $cb( 'c', 'c' );   # c

However, doing the same thing with an if/else construct doesn't work.
It generates a pretty baffling error message:

my $cb =  {
do if ($^a eq $^b)  {
 "$^a";
} else {   # line 48
 "$^a & $^b";
}
};
say $cb( 'a', 'b' );

# Too few positionals passed; expected 2 arguments but got 1
#  in code  at
/home/doom/End/Cave/Perl6/bin/callback_placeholder_vars_and_if_else-out.raku
line 48
#  in block  at
/home/doom/End/Cave/Perl6/bin/callback_placeholder_vars_and_if_else-out.raku
line 46
#  in block  at
/home/doom/End/Cave/Perl6/bin/callback_placeholder_vars_and_if_else-out.raku
line 5

I theorize that Raku is treating the blocks of the if/else much like
the surrounding block,
and using a count of the placeholder vars to get an implicit arity for
the "else" block--
(why it's just getting one thing passed and not two, that I don't get).


So, what if we move the use of the placeholder vars outside of the
if/else?  A: yet another baffling error

 my $cb =  {
 my $a = $^a;
 my $b = $^b;
 do if ($a eq $b)  {
  "$a";
 } else {
  "$a & $b";
 }
 };
 say $cb( 'a', 'b' );

# ===SORRY!=== Error while compiling
/home/doom/End/Cave/Perl6/bin/callback_placeholder_vars_and_if_else-out.raku
# Redeclaration of symbol '$^a' as a placeholder parameter.
# at 
/home/doom/End/Cave/Perl6/bin/callback_placeholder_vars_and_if_else-out.raku:85
# --> my $a = $^a⏏;


Flailing around a bit, I concluded there was something strange
going on with the variable name $a, e.g. *this* works:

my $cb =  sub {
my $alpha = $^a;
my $beta  = $^b;
return do if ($alpha eq $beta) {
"$a";
} else {
"$a & $b";
}
};
say $cb( 'a', 'b' );  # a & b

It is of course, also possible to use an explicit sub-signature
instead (this at least, just works):

my $cb = sub ($a, $b) {
my $result =
do if ($a eq $b)  {
  "$a";
} else {
  "$a & $b";
};
return $result;
};
say $cb( 'a', 'b' );   # a & b
say $cb( 'e', 'e' );   # e


I'm using:

  raku --version
  Welcome to 퐑퐚퐤퐮퐝퐨™ v2020.10.
  Implementing the 퐑퐚퐤퐮™ programming language v6.d.
  Built on MoarVM version 2020.10.