develooper Front page | perl.perl6.users | Postings from August 2021

callbacks with placeholder vars

Thread Next
From:
Joseph Brenner
Date:
August 9, 2021 18:56
Subject:
callbacks with placeholder vars
Message ID:
CAFfgvXWjTgMn-wszj2v7_yM=_-3svOJhxufbz2KtGJ3H+w-QNw@mail.gmail.com
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 <unit> 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.

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About