On Tue, 2002-03-26 at 16:26, Michel J Lambert wrote:

> An example of where variable capture is needed is:
> macro println ($a) {
>   return <<"EOF";
>   print $a;
>   print "\n";
> EOF
> }
> for my $b (1..100) {
>   println $b;
> }

Ok, I don't get it. I'm willing to concede that I'm dense, but I need to
understand how.

This looks to me like:

    sub println ($a) {
        print $a, "\n";
    }
    for my $b (1..100) {
      println $b;
    }

And, if we inline the sub, the only difference will be...?

Your example seems to involve no variable capture at all, in fact, just
passing parameters to a macro. See below....
 
> Personally, I'm at a loss for how macros will fit seamlessly in Perl 6.
> The examples above return a string, instead of real code (to make it
> easier to see how the interpolation works.) The code passes in a block of
> code, which magically gets interpolated back into a string as its original
> code form.

I *can* see some advantage in:

    macro mygrep ($code is macroblock, *@list) {
      my @newlist = ();
      for @list {
        push @newlist, $_ if $code.();
      }
      return @newlist;
    }
    @x = mygrep {/\S/} $fh.getlines();
    
where no code reference is ever created. It could be abused mercilessly,
but I can see the massive savings in performance that we would reap,
especially when translating/compiling this code for native or JIT
execution. This is because we don't have to fire a function call each
time we execute the block.

But, perhaps this is too syntax-heavy. Maybe something simpler:

    sub mygrep ($code is inline, *@list) {
      my @newlist = ();
      for @list {
        push @newlist, $_ if $code.();
      }
      return @newlist;
    }
    @x = mygrep {/\S/} $fh.getlines();

Now you put it in the compiler's hands to determine if a code reference
should be generated or not. Access to $_ is the only thing that is in
question here, and I don't have a good answer off the top of my head.

It would be very interesting to see how

    sub mymap ($code is inline, *@list) {
      my @newlist = ();
      for @list {
        push @newlist, $code.();
      }
      return @newlist;
    }
    @x = mymap {mygrep {$_} split //, $_} $fh.getlines();

would behave. Possibly quite efficient.

> Other things which the above 'forintlist' example used was the ability to
> send an arbitrary structure to the macro, and have it be matched against
> the parameter list for the macro. This allows one more flexibility in
> passing parameters to a macro, as they don't need to be a straight out
> list/array, but can be more complicatged structures, which are
> automagically matched. If this were in perl 6, regular array/list argument
> passing could be a simple case of a more complex argument/parameter
> passing structure.

I think your ideas here are good. If a general mechanism could be found
for the syntax and deemed valuable enough to add, I'd be all for it.

However, is it really macro-specific or should it be part of the
function call syntax in general?


Reply via email to