Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CODE {...} mentioning variables without interpolation

2 views
Skip to first unread message

Brad Bowman

unread,
Feb 17, 2006, 6:57:18 PM2/17/06
to perl6language,
Hi again,

L<S06/"Macros">

Is it possible to refer to a variable in a CODE quotation without
splicing it in as an AST or string? I can't see how this is
be possible under S06, unless using OUTER:: is intended to be
a non-splicing variable mention.

The sample snippet in S06 seems simple but got me confused.
I'll explain my interpretation so the confusion can be removed
from the rules or my understanding, where ever it's found to be.
The snippet:

return CODE { say $a };

The snippet will probably be found inside a macro and will be run
during the macro's expansion elsewhere. When it is run,
an AST for "say $a" is produced that searches for $a in
the lexical scope containing the CODE block, otherwise
the macro call scope is searched, or emit a compile time error.

$a is spliced into the say as either a string or AST, not
as a runtime use of $a. If the snippet was:

$a = '$a';
return CODE { say $a };

Then we'd (eventually) get a non-splicing mention of $a, one that
would refer to the $a in scope at the macro call, I think.
Is this correct?


Perhaps signatures on CODE forms can be used to specify the variables
which are to be spliced, and their scope of origin. I'm posting
some hypothetical syntax because the post made even less sense without it.
It's obviously in need of refinement:

# non-splicing $a from this scope
return CODE () { say $a };

# non-splicing $a in the scope of the macro call
return CODE () { say COMPILING::<$a> };

# ast-splicing with dwiminess
return CODE ($a) { say $a };

# ast-splicing requiring a lexical $a here
return CODE (OUTER::<$a>) { say $a };

Traits could be used in the signatures instead of the pseudo packages.
Sugar to taste.

This would probably be overloading the meaning of signatures since
there's no explicit application of the code object to a set of runtime
arguments. idea--

It seems like I'm currently obsessed with signatures as silver bullets.
Is there any hope for my peculiar quest?


A minor related query, can the CODE { ... } form appear outside
of macro returns? Can we put the AST in a variable, pass it between
subroutines and do the usual runtime things with it?


This sig seems particularly apt here,

Brad

--
When one is not capable of true intelligence, it is good to consult with
someone of good sense. -- Hagakure http://bereft.net/hagakure/

Larry Wall

unread,
Feb 17, 2006, 8:10:53 PM2/17/06
to perl6language,
On Sat, Feb 18, 2006 at 01:57:18AM +0200, Brad Bowman wrote:
: Hi again,

:
: L<S06/"Macros">
:
: Is it possible to refer to a variable in a CODE quotation without
: splicing it in as an AST or string? I can't see how this is
: be possible under S06, unless using OUTER:: is intended to be
: a non-splicing variable mention.
:
: The sample snippet in S06 seems simple but got me confused.
: I'll explain my interpretation so the confusion can be removed
: from the rules or my understanding, where ever it's found to be.
: The snippet:
:
: return CODE { say $a };
:
: The snippet will probably be found inside a macro and will be run
: during the macro's expansion elsewhere. When it is run,
: an AST for "say $a" is produced that searches for $a in
: the lexical scope containing the CODE block, otherwise
: the macro call scope is searched, or emit a compile time error.
:
: $a is spliced into the say as either a string or AST, not
: as a runtime use of $a. If the snippet was:
:
: $a = '$a';
: return CODE { say $a };
:
: Then we'd (eventually) get a non-splicing mention of $a, one that
: would refer to the $a in scope at the macro call, I think.
: Is this correct?

No. If bare $a is not found in the CODE's scope, it must *bind* to
an existing $a in the macro caller's scope as a runtime use of $a,
or the macro fails. If the calling code wants to supply arguments
to the macro body, they must come in as ordinary arguments, or use
some modifier that chases up the dynamic stack, such as one of

CALLER::<$a>
ENV::<$a>
COMPILING::<$a>

: Perhaps signatures on CODE forms can be used to specify the variables


: which are to be spliced, and their scope of origin. I'm posting
: some hypothetical syntax because the post made even less sense without it.
: It's obviously in need of refinement:
:
: # non-splicing $a from this scope
: return CODE () { say $a };
:
: # non-splicing $a in the scope of the macro call
: return CODE () { say COMPILING::<$a> };
:
: # ast-splicing with dwiminess
: return CODE ($a) { say $a };
:
: # ast-splicing requiring a lexical $a here
: return CODE (OUTER::<$a>) { say $a };
:
: Traits could be used in the signatures instead of the pseudo packages.
: Sugar to taste.
:
: This would probably be overloading the meaning of signatures since
: there's no explicit application of the code object to a set of runtime
: arguments. idea--

Seems to be trying to duplicate the function of the macro's signature,
which is already presumably declaring parameters with various type
signatures.

It's possible that the interpretation of a macro's $a could depend on
its declared type of the variable it is eventually bound to, but we
can't readily extend that idea to dynamicly scoped value or run-time types.

: It seems like I'm currently obsessed with signatures as silver bullets.


: Is there any hope for my peculiar quest?

Dunno. But then I don't know if there's any hope for my particular
quest either. :-)

: A minor related query, can the CODE { ... } form appear outside


: of macro returns? Can we put the AST in a variable, pass it between
: subroutines and do the usual runtime things with it?

I don't see why not. The behavior is defined in terms of the current
lexical scope, so it's not required that that particular lexical
scope be supplied by a macro.

: This sig seems particularly apt here,

Signatures are overrated. :-)

: Brad


:
: --
: When one is not capable of true intelligence, it is good to consult with
: someone of good sense. -- Hagakure http://bereft.net/hagakure/

It's not entirely clear to me that we should trust the advice of someone
who was prevented from committing seppuku only by edict of Tokugawa. :-)

But the scary part about that quote is that it seems to be saying that
if you have true intelligence you don't need good sense.

Larry

qqpphu...@gmail.com

unread,
Feb 18, 2006, 2:07:32 AM2/18/06
to
MY NAME I’S HUANG JUN
我的名字叫黄俊

Brad Bowman

unread,
Feb 18, 2006, 1:25:25 PM2/18/06
to Larry Wall, perl6language,
On 18/02/06 03:10, Larry Wall wrote:
> On Sat, Feb 18, 2006 at 01:57:18AM +0200, Brad Bowman wrote:
> : $a is spliced into the say as either a string or AST, not
> : as a runtime use of $a. If the snippet was:
> :
> : $a = '$a';
> : return CODE { say $a };
> :
> : Then we'd (eventually) get a non-splicing mention of $a, one that
> : would refer to the $a in scope at the macro call, I think.
> : Is this correct?
>
> No. If bare $a is not found in the CODE's scope, it must *bind* to
> an existing $a in the macro caller's scope as a runtime use of $a,

I was intending the above example to satisfy the "$a in the CODE's scope"
clause, I was missing a "my". I think my example doesn't achieve
it's goal anyway. I'll try again:

macro M ($a) {
my $b = '$c';
return CODE { $a + $b };
}

package Elsewhere;
my ($b, $c, $d) = (1,2,3);

say M($d + 2);

The macro parameter $a is bound to the ast for COMPILING::<$d> + 2
The $a mentioned in the CODE is replace with the same, roughly:
CODE { COMPILING::<$d> + 2 + $b }

$b exists in the lexical scope of the CODE block, so it is preferred.
Since $b is a string, '$c' replaces $b in the above and parsing
is restarted there. Once $c is parsed, the macro's scope is searched
and fails. (This is where I derailed the first time round)

CODE { COMPILING::<$d> + 2 + $c }

The $c is free and so must bind to an existing $c in the scope of the
macro call, which is fine in this example. The result is a complicated 7.

I guess I was unclear about the effect of the $b='$c' indirection,
it seems like the answer is that there is no effect, the $c is
bound and spliced just as the original $b is.

> or the macro fails. If the calling code wants to supply arguments
> to the macro body, they must come in as ordinary arguments, or use
> some modifier that chases up the dynamic stack, such as one of
>
> CALLER::<$a>
> ENV::<$a>
> COMPILING::<$a>

These are non-splicing mentions of variables from the call site (right?).
Is there a way to do a non-splicing mention of variables at the macro
definition site, similar to normal code closures?

The CODE can mention sub names, they're not spliced and thus give the
indirection I was looking for. (I think)

my $counter;
sub inc_counter { return $counter++; }
macro c {
return CODE { inc_counter() };
}

A state variable declared within the CODE would also suffice in this case.

> : --
> : When one is not capable of true intelligence, it is good to consult with
> : someone of good sense. -- Hagakure http://bereft.net/hagakure/
>
> It's not entirely clear to me that we should trust the advice of someone
> who was prevented from committing seppuku only by edict of Tokugawa. :-)

Yeah! Where's his mettle?

> But the scary part about that quote is that it seems to be saying that
> if you have true intelligence you don't need good sense.

Maybe it was lost in translation. Or maybe those of true intelligence
can work it out themselves, without needing the advice of a cranky samurai. :)

--
... One should think well then speak. ... -- Hagakure

0 new messages