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

Unifying invocant and topic naming syntax

37 views
Skip to first unread message

Me

unread,
Nov 4, 2002, 12:17:32 AM11/4/02
to perl6-l...@perl.org, Allison Randal
I read Allison's topicalization piece:

http://www.perl.com/pub/a/2002/10/30/topic.html

I started with a simple thought:

is given($foo)

seems to jar with

given $foo { ... }

One pulls in the topic from outside and
calls it $foo, the other does the reverse --
it pulls in $foo from the outside and makes
it the topic.

On its own this was no big deal, but it got
me thinking.

The key thing I realized was that (naming)
the invocant of a method involves something
very like (naming) the topic of a method,
and ultimately a sub and other constructs.

Thus it seems that whatever syntax you pick
for the former is likely to work well for
the latter.

Afaik, the syntax for invocant naming is:

method f ($self : $a, $b) { ... }

But whatever it is, I think one can build
on it for topic transfer / naming too in a
wide range of contexts.

With apologies for talking about Larry's
colon, something that really does sound
like it is taboo for good reason, I'll
assume the above invocant naming syntax
for the rest of this email.

So, perhaps:

sub f ($a, $b) is given($c) { ... }
sub f ($a, $b) is given($c is topic) { ... }
sub f ($a, $b) is given($_) { ... }

could be something like:

sub f ($c : $a is topic, $b) { ... }
sub f ($c : $a, $b) { ... }
sub f ($_ : $a, $b) { ... }

where the first arg to be mentioned is the
topic unless otherwise specified.

(The first line of the alternates is not
semantically the same as the line it is a
suggested replacement for, in that the
current scheme would not set the topic --
its value would be the value of $_ in
the lexical block surrounding the sub
definition. It's not obvious to me why
the current scheme has it that way and
what would best be done about it in the
new scheme I suggest, so I'll just move on.)

Anyhow, the above is my suggestion for an
alternate to 'is given' in a sub definition.

The obvious (to me) thing to do for methods
is to have /two/ colon separated prefixes of
the arg list. So one ends up with either one,
two, or three sections of the arg list:

# $_ is invocant:
method f ($a, $b) { ... }

# $_ and $self are both invocant:
method f ($self : $a, $b) { ... }

# $_/$self are invocant, $c caller's topic
method f ($self : $c : $a, $b) { ... }

One could have incantations such as:

method f ($self : $c : $a is topic, $b) { ... }
method f ($self : $c is topic : $a, $b) { ... }
method f ($self : $_ : $a, $b) { ... }

which all clobber the invocant being 'it',
but if that's what a method author wants,
then so be it.

One question is what happens if one writes:

method f (: $c : $a, $b) { ... }

Is the invocant the topic, or $c, ie what
does a missing invocant field signify?

Jumping to a different topic for one moment,
I think it would be nice to provide some
punctuation instead of (or as an alternate
to) a property for setting 'is topic'. Maybe:

method f ($self : $c : $a*, $b) { ... }

or maybe something like:

method f ($self : $c : $aT, $b) { ... }

(Unicode TM for Topic Marker? Apologies if I
screwed up and the TM character comes through
as something else.)

Anyhow, a further plausible tweak that builds
on the above colon stuff is that one could
plausibly do:

sub f ($bar : $a, $b) {
...
}

and then call f() like so:

f (20 : 30, 40)

as a shortcut for setting $_ before calling f(),
ie to set $_ in the body of f to 20, $a to 30.

Unfortunately that conflicts with use of colon
as an operator adverb. Conclusion: if y'all
end up using a different syntax for specifying
the variable name of the invocant for a method,
and go with the extension I suggested earlier
for replacing 'is given', then maybe the above
can still work, and maybe it would be a good
idea to allow it.

And if you do, I can see a further trick being:

given $foo {
# $_ = $foo here, hiding outer topic
}

given $c : $foo {
# $_ = $foo here, hiding outer topic
# $c = outer $_
}

And likewise for other topicalizers.

--
ralph

Allison Randal

unread,
Nov 4, 2002, 4:52:20 PM11/4/02
to Me, perl6-l...@perl.org
On Sun, Nov 03, 2002 at 11:17:32PM -0600, Me wrote:
>
> I started with a simple thought:
>
> is given($foo)
>
> seems to jar with
>
> given $foo { ... }
>
> One pulls in the topic from outside and
> calls it $foo, the other does the reverse --
> it pulls in $foo from the outside and makes
> it the topic.

It comes from is using 'given' as a noun (meaning the same thing as
'topic') instead of a verb. So, this:

given $foo { ... }

means "make $foo become the given" or "Given-ify $foo". While:

is given($foo)

means "$foo takes the value of the given".

There may be room for a better parameter name. We considered quite a few
before picking this one, though, and I'm pretty happy with it for now.

> On its own this was no big deal, but it got
> me thinking.
>
> The key thing I realized was that (naming)
> the invocant of a method involves something
> very like (naming) the topic of a method,
> and ultimately a sub and other constructs.

The similarity is that both are implicit parameters, i.e. they're
accessible to the sub/method but aren't explicitly passed when it's
called. They're not quite the same though, as the C<is given> parameter
is entirely out-of-band (in P5 terms, it wouldn't appear in @_).

Also, both may be the topic under certain circumstances. But then, any
variable can be the topic.

Generally, there's no conceptual link between the invocant of a method
and the topic in the caller's scope.

Even though both features have something to do with topic, they're
really independent. There are times when it's useful to access the
caller's topic without setting the current topic and times when it's
useful to just set the current topic.

sub f ($a, $b) { ... } # use neither feature
sub f ($a is topic, $b) { ... } # topic setting
sub f ($a, $b) is given($c) { ... } # access caller's topic
sub f ($a, $b) is given($c is topic) { ... } # combine

When you have a system with two independent but interacting features,
it's far more efficient to define two independent flags than to define 4
flags to represent the 4 combinations. It's also easier to learn.

> The obvious (to me) thing to do for methods
> is to have /two/ colon separated prefixes of
> the arg list. So one ends up with either one,
> two, or three sections of the arg list:
>
> # $_ is invocant:
> method f ($a, $b) { ... }
>
> # $_ and $self are both invocant:
> method f ($self : $a, $b) { ... }
>
> # $_/$self are invocant, $c caller's topic
> method f ($self : $c : $a, $b) { ... }

Any two constructs with the same syntax but an entirely different
meaning exponentially increase the chance of confusion. Confusion
increases the likelyhood of bugs. Not to mention frustrating the
programmer.

> One question is what happens if one writes:
>
> method f (: $c : $a, $b) { ... }
>
> Is the invocant the topic, or $c, ie what
> does a missing invocant field signify?

The invocant would be the topic still. It is now with:

method f (: $a, $b) { ... }

> Jumping to a different topic for one moment,
> I think it would be nice to provide some
> punctuation instead of (or as an alternate
> to) a property for setting 'is topic'. Maybe:
>
> method f ($self : $c : $a*, $b) { ... }
>
> or maybe something like:
>
> method f ($self : $c : $aT, $b) { ... }
>
> (Unicode TM for Topic Marker? Apologies if I
> screwed up and the TM character comes through
> as something else.)

Huffman encoding comes to mind. Is this really common enough to merit a
single punctuation character?

> Anyhow, a further plausible tweak that builds
> on the above colon stuff is that one could
> plausibly do:
>
> sub f ($bar : $a, $b) {
> ...
> }
>
> and then call f() like so:
>
> f (20 : 30, 40)
>
> as a shortcut for setting $_ before calling f(),
> ie to set $_ in the body of f to 20, $a to 30.

So, in this system, the colon is used for both explicit parameters and
implicit parameters. Sometimes its only purpose is to set the topic in
the body of the sub/method and sometimes it doesn't set the topic. I'd
prefer more consistency.

> Unfortunately that conflicts with use of colon
> as an operator adverb. Conclusion: if y'all
> end up using a different syntax for specifying
> the variable name of the invocant for a method,
> and go with the extension I suggested earlier
> for replacing 'is given', then maybe the above
> can still work, and maybe it would be a good
> idea to allow it.
>
> And if you do, I can see a further trick being:
>
> given $foo {
> # $_ = $foo here, hiding outer topic
> }
>
> given $c : $foo {
> # $_ = $foo here, hiding outer topic
> # $c = outer $_
> }
>
> And likewise for other topicalizers.

It would be much more transparent to simply name the outer topic. It
would be more convenient too, if there are other nested topicalizers.
It's better to attack the problem at the root than to apply a series of
cosmetic fixes.

given $whatever -> $c {


given $foo {
# $_ = $foo here, hiding outer topic

# $c = outer $_
}

for @bar {


# $c = outer $_
}
}

Allison

Me

unread,
Nov 4, 2002, 6:34:07 PM11/4/02
to Allison Randal, perl6-l...@perl.org
> > (naming) the invocant of a method involves
> > something very like (naming) the topic
>
> Generally, there's no conceptual link...

....other than

> The similarity is that both are implicit
> parameters

which was my point.

Almost the entirety of what I see as relevant
in the context of deciding syntax for naming
the invocant is that it's an especially
important implicit argument to methods that
may also be the topic.

Almost the exact same thing is true of the
"topic", with the exception being that it
applies to subs as well as methods.

It's clear you could have come up with
something like one of these:

method f ($a, $b) is invoked_by($self)
method f ($a, $b) is invoked_by($self is topic)
method f ($a, $b) is invoked_by($_)

but you didn't. Any idea why not?


> There are times when it's useful to access
> the caller's topic without setting the current
> topic and times when it's useful to just set
> the current topic.

> ...


> When you have a system with two independent
> but interacting features, it's far more
> efficient to define two independent flags
> than to define 4 flags

Of course. The general scheme I suggested
doesn't impinge on this one way or the other.

But the specifics I suggested made a different
choice for the default situation.

As you said of the current scheme:

The following example will either print
nothing, or else print a stray $_ that is
in lexical scope wherever the sub is defined.

sub eddy ($space, $time) {
print;
}

In the scheme I suggest the first arg is the
topic by default (just as is the case for the
other topicalizers such as pointy sub, for,
etc in the current scheme). I think this
choice makes sense, but then, as I implied,
maybe I'm missing something.


> > method f ($self : $c : $a*, $b) { ... }

(where * is short for 'is topic'.)

> Is this really common enough to merit a single
> punctuation character?

If I didn't think so I wouldn't have suggested
the shortcut. ;>


> > Anyhow, a further plausible tweak that builds
> > on the above colon stuff is that one could
> > plausibly do:
>

> So, in this system, the colon is used for both
> explicit parameters and implicit parameters.

> ...


> I'd prefer more consistency.

If by "system" you mean the scheme I suggested
prior to this "plausible tweak", then no. The
colon would only be used in this way if one
introduced the tweak. Rejecting this tweak has
no impact on the value of the general scheme
I suggested.

The colon in my scheme (not the tweak) can
optionally be used to be explicit in sub
*defs* about otherwise implict args. The
tweak I am suggesting is that one could,
optionally, use the exact same syntax to
be explicit in sub *calls* about otherwise
implicit args. I think this has a clean
consistency.


> > given $c : $foo {


> > # $c = outer $_
> > }
>

> It would be much more transparent to simply
> name the outer topic.

How is this so different to

method f ($c : $foo) {
# $c = invocant
}

?


>
> Allison

--
ralph

Damian Conway

unread,
Nov 4, 2002, 9:09:16 PM11/4/02
to perl6-l...@perl.org
ralph wrote:

> It's clear you could have come up with
> something like one of these:
>
> method f ($a, $b) is invoked_by($self)
> method f ($a, $b) is invoked_by($self is topic)
> method f ($a, $b) is invoked_by($_)
>
> but you didn't. Any idea why not?

Because most methods need some kind of access to their own invocant,
but relatively few subroutines need access to the upscope topic.
So the syntax for invocant specification should be compact,
and the syntax for external topic access should be less so.

Moreover, because the latter mechanism compromises the lexical
scoping of the upscope topic, it ought to be marked very clearly
(i.e. with a keyword, rather than a single colon).


>>> method f ($self : $c : $a*, $b) { ... }
>>
>
> (where * is short for 'is topic'.)

Too short, IMHO.

For such a non-standard method definition, I'd *very* much rather
maintain a syntax like:

method f ($self : $a is topic, $b) is given($c) { ... }

which clearly marks all the irregularities.

Not to mention that this more explicit syntax doesn't inject a spurious
pseudoparameter into the parameter list.

Damian

Me

unread,
Nov 5, 2002, 6:13:45 AM11/5/02
to Damian Conway, perl6-l...@perl.org
> relatively few subroutines need access
> to the upscope topic.

Well, this is a central issue. What are
the real percentages going to be here?
Just how often will one type the likes
of

-> is given($foo is topic) { ... }

rather than

-> $foo: { ... }

?

My imagination suggests to me that in a
typical short perl 6 script, between 20%
and 50% of all sub defs would use the
upscope topic... ;>

Seriously, the functions chapter of Camel
III contains 202 functions; 36 of these
use the upscope topic.

So that gives an idea of what to expect --
although there is likely to be /more/ use
of tricks like this that support brevity
when advanced coders specifically wish to
write brief scripts.

Unless of course the very syntax that
creates /call/ brevity is itself so
verbose that it neutralizes some of its
utility in such cases, something that
would be rather ironic, don't you think?


> Moreover, because ['is given'] compromises


> the lexical scoping of the upscope topic,
> it ought to be marked very clearly

Yes.

> [keywords are clearer than punctuation for
> marking something]

I think that's overly general.

In something that is as likely to be naturally
keyword dense as a sub or method definition, I
imagined the situation would be near reverse,
i.e. well chosen punctuation would often be a
better pick than YAK for marking something.

(Maybe colon isn't it, but I didn't pick that.)

Of course, in code written to be brief, sub
defs would tend to be less keyword, but then
again, in code written to be brief, brevity
would again suggest punctuation.

So perhaps punctuation wins in both cases;
in large projects sub defs will be keyword
dense and punctuation would better highlight
"it" and in small scripts, punctuation in
sub defs would be desirable for brevity.


--
ralph

Ken Fox

unread,
Nov 5, 2002, 9:32:12 AM11/5/02
to perl6-l...@perl.org
Me wrote:

> YAK for marking something.

I've been assuming that a keyword will only have
meaning in contexts where the keyword is valid.
Given the shiny new top-down grammar system, there's
no requirement for keywords to be global. (Context
sensitive keywords fall out of Perl 6 grammars
naturally -- just the opposite of yacc.)

Is this a valid assumption?

What's the parse of the following code?

sub topic ($x is topic) {
$x.topic
}

- Ken

Damian Conway

unread,
Nov 5, 2002, 3:24:02 PM11/5/02
to perl6-l...@perl.org
ralph hypothesized:

> My imagination suggests to me that in a
> typical short perl 6 script, between 20%
> and 50% of all sub defs would use the
> upscope topic... ;>

That's some imagination you've got there! ;-)

My estimate (based on the -- not inconsiderable -- code base of
my own modules) is closer to 5%.

But that's beside the point. The two factors that nix this idea
IMHO are that:

* Putting a non-parameter in the parameter list
is Just Plain Wrong

* Using a single character to denote the use of
an upscope topic is insufficiently obvious
(regardless of which character is used for
the purpose)

Damian

Allison Randal

unread,
Nov 5, 2002, 3:36:08 PM11/5/02
to Me, perl6-l...@perl.org
On Tue, Nov 05, 2002 at 05:13:45AM -0600, Me wrote:
> > relatively few subroutines need access
> > to the upscope topic.
>
> Well, this is a central issue. What are
> the real percentages going to be here?
> Just how often will one type the likes
> of
>
> -> is given($foo is topic) { ... }
>
> rather than
>
> -> $foo: { ... }
>
> ?
>
> My imagination suggests to me that in a
> typical short perl 6 script, between 20%
> and 50% of all sub defs would use the
> upscope topic... ;>
>
> Seriously, the functions chapter of Camel
> III contains 202 functions; 36 of these
> use the upscope topic.

The fact that accessing the upscope topic is common enough to be useful
is why we decided to provide an easy way to do it.

But compare that frequency to the frequency of addition.

> > Moreover, because ['is given'] compromises
> > the lexical scoping of the upscope topic,
> > it ought to be marked very clearly
>
> Yes.

Which is another reason why it shouldn't be too easy.

> So that gives an idea of what to expect --
> although there is likely to be /more/ use
> of tricks like this that support brevity
> when advanced coders specifically wish to
> write brief scripts.
>
> Unless of course the very syntax that
> creates /call/ brevity is itself so
> verbose that it neutralizes some of its
> utility in such cases, something that
> would be rather ironic, don't you think?

I don't consider the ability to write brief code to be the chief goal of
language design. One of the goals, sure. No one wants to type:

is the_property_that_provides_access_to_the_topic_in_the_callers_scope($foo is
the_current_topic_in_the_block)

But brevity is a lower goal than clarity and ease of maintenance. It's
a balance, like everything in language design (and life in general).

> > [keywords are clearer than punctuation for
> > marking something]
>
> I think that's overly general.
>
> In something that is as likely to be naturally
> keyword dense as a sub or method definition, I
> imagined the situation would be near reverse,
> i.e. well chosen punctuation would often be a
> better pick than YAK for marking something.
>
> (Maybe colon isn't it, but I didn't pick that.)
>
> Of course, in code written to be brief, sub
> defs would tend to be less keyword, but then
> again, in code written to be brief, brevity
> would again suggest punctuation.
>
> So perhaps punctuation wins in both cases;
> in large projects sub defs will be keyword
> dense and punctuation would better highlight
> "it" and in small scripts, punctuation in
> sub defs would be desirable for brevity.

It's a balance again. You can't just look at the one feature in
isolation and decide if it's better off as a keyword or punctuation. You
have to look at the whole language as a system and decide which features
most deserve punctuation. Even if we have the option of unicode
punctuation, moderation is still desirable. The logical extreme of a
language that prefers punctuation is something like:

$%(_^?.)*@!+-#&

I'm sure that's not what you meant, or what you want, but it illustrates
the point that more punctuation leads toward less clarity. Somewhere
between the insanity of all punctuation and the verbosity of no
punctuation lies the happy medium.

Allison

--
Punctuation is the spice of life.

Damian Conway

unread,
Nov 5, 2002, 3:28:40 PM11/5/02
to perl6-l...@perl.org
Ken Fox wrote:

> I've been assuming that a keyword will only have
> meaning in contexts where the keyword is valid.
> Given the shiny new top-down grammar system, there's
> no requirement for keywords to be global. (Context
> sensitive keywords fall out of Perl 6 grammars
> naturally -- just the opposite of yacc.)
>
> Is this a valid assumption?

Sure. It's a valid assumption for Perl 5:

sub print {
my ($print, @print) = @_;
${print}->{print}->print(@{print});
}


so I'm sure it will be for Perl 6 too.

Damian

Me

unread,
Nov 5, 2002, 8:31:22 PM11/5/02
to Damian Conway, perl6-l...@perl.org
> > My imagination suggests to me that in a
> > typical short perl 6 script
>
> That's some imagination you've got there! ;-)

:>


> My estimate (based on the -- not inconsiderable --
> code base of my own modules) is closer to 5%.

Your estimate of what others will do when
knocking out 10 line scripts in a hurry,
or what's in your current p5 modules?


> But that's beside the point. The two factors
> that nix this idea IMHO are that:
>
> * Putting a non-parameter in the parameter list
> is Just Plain Wrong

Right. I've always thought that too.


> * Using a single character to denote the use of
> an upscope topic is insufficiently
> obvious (regardless of which character
> is used for the purpose)

Right again. And again, I've always thought
that too.

As I said in my original email on this topic:

Afaik, the syntax for invocant naming is:

method f ($self : $a, $b) { ... }

But whatever it is, I think one can build
on it for topic transfer / naming too in a
wide range of contexts.

I didn't like the invocant syntax but didn't
want to tackle the problems with it that you
so rightly list above. My point was always
just that what's good for one very common
implicit arg (invocant) seems to me likely
to be good for what could so easily become
the other-not-quite-so-but-still-somewhat
common implicit arg (it).

But I'll assume the horse is dead, and move
on to the horses sibling, which hopefully
might live on:

Can currying include the given topic? Can
I do something like:

$foo = &bar.assuming( _ => 0)

or whatever the latest syntax is?

And what about a topic placeholder:

{ print $^_ }

such that $^_ is effectively converted to
an 'is given($^_)'.

?

--
ralph

Me

unread,
Nov 5, 2002, 10:09:21 PM11/5/02
to Me, Damian Conway, perl6-l...@perl.org
> Can currying include the given topic? Can
> I do something like:
>
> $foo = &bar.assuming( _ => 0)
>
> or whatever the latest syntax is?

Oops. More clearly:

sub bar is given($foo) {
...
}

$foo = &bar.assuming( foo => 0 )

--
ralph

Damian Conway

unread,
Nov 7, 2002, 4:19:24 AM11/7/02
to perl6-l...@perl.org
ralph wrote:

>>My estimate (based on the -- not inconsiderable --
>>code base of my own modules) is closer to 5%.
>
> Your estimate of what others will do when
> knocking out 10 line scripts in a hurry,
> or what's in your current p5 modules?

Both.


> Can currying include the given topic?
>

> sub bar is given($foo) {
> ...
> }
>
> $foo = &bar.assuming( foo => 0 )

Maybe. Depends whether we treat the topic specifier as an out-of-band
parameter mechanism. Personally, I'm leery of doing that, but Larry might
well feel it's okay.

> And what about a topic placeholder:
>

> $foo = { print $^_ };


>
> such that $^_ is effectively converted to
> an 'is given($^_)'.

No, that doesn't work. The placeholder $^_ is
entirely unrelated to $_. Besides, what's wrong with:

$foo = sub { print $_ } is given($_);

???

Damian

Me

unread,
Nov 7, 2002, 4:27:51 PM11/7/02
to Damian Conway, perl6-l...@perl.org
Damian:
> ["it" will be passed to about 5% of subs,
> regardless of whether the context is your
> 10 line scripts or my large modules]

If the syntax for passing "it" to a sub
remains as verbose as it currently is,
you are probably right that "it" won't
be used to achieve brevity! I think it's
a pity given that the core point of "it"
is to achieve brevity.

Why do you think your estimate of Perl 6
usage of "it" is so much lower than is
true for the standard Perl 5 functions?

Btw, can I just confirm that one can't do:

sub f ($a = <mumble>) { ... }
or
sub f (;$_ = <mumble>) { ... }

where <mumble> is the upscope it and $_
is the sub's topic.


> > Can currying include the given topic?
>

> Maybe.

Naturally, I see this as another symptom
of the way upscope "it" is being treated
as a second class citizen, and that this
is leading things in the wrong direction.


> > And what about a topic placeholder:
> >
> > $foo = { print $^_ };
> >
> > such that $^_ is effectively converted
> > to an 'is given($^_)'.
>
> No, that doesn't work. The placeholder
> $^_ is entirely unrelated to $_.

Well, it is at the moment, but there is
clearly mnemonic value between $^_ and $_.


> Besides, what's wrong with:
>
> $foo = sub { print $_ } is given($_);

Compared with

$foo = sub { print $^_ };

The answer is brevity, or lack thereof.

Why bother with currying? Why bother with
the "it" concept? None of these are necessary.
They simplify code generation, but their more
general feature is enabling brevity.


--
ralph

Damian Conway

unread,
Nov 11, 2002, 4:46:08 AM11/11/02
to perl6-l...@perl.org
ralph wrote:

> If the syntax for passing "it" to a sub
> remains as verbose as it currently is,
> you are probably right that "it" won't
> be used to achieve brevity!

You're confusing brevity of declaration with brevity of use.
Declarations should always be relatively verbose.


> Why do you think your estimate of Perl 6
> usage of "it" is so much lower than is
> true for the standard Perl 5 functions?

Because I don't believe many people write subroutines that
default to $_ or that rely on some particular value of $_.
In Perl 5, relying on $_ is fraught with peril, since its
global nature means you have to be wary of what happens to
it in any nested calls as well.

We ought not make that peril any easier to fall into in
Perl 6. Making $_ lexical goes a long way towards that.
Making (limited) circumvention of that lexicality depend on
a verbose and explicit syntax will help too.


> Btw, can I just confirm that one can't do:
>
> sub f ($a = <mumble>) { ... }
> or
> sub f (;$_ = <mumble>) { ... }
>
> where <mumble> is the upscope it and $_
> is the sub's topic.

I seriously doubt it but, as always, that's up to Larry.
If it were allowed, the syntaxes might be something like:

sub f ($a = $CALLER::_) { ... }

sub f (;$_ = $CALLER::_) { ... }


> Naturally, I see this as another symptom
> of the way upscope "it" is being treated
> as a second class citizen,

No. It's just not being treated as a parameter.
Because it isn't one.


> and that this is leading things in the wrong direction.

Actually, I'm very happy with the direction it's being led.

>>Besides, what's wrong with:
>>
>> $foo = sub { print $_ } is given($_);
>
>
> Compared with
>
> $foo = sub { print $^_ };
>
> The answer is brevity, or lack thereof.

But, even if $^_ *were* synonymous with $_, it
still wouldn't do what you want. The placeholder
in:

$foo = sub { print $^_ };

makes the closure equivalent to:

$foo = sub ($_) { print $_ };

which expects the topic to be passed as the argument of the
subroutine, *not* "inherited" out-of-band from the caller's
scope.

If you're proposing that there be some special exemption for
$^_ so that it (a) doesn't placehold a parameter and (b)
aliases the caller's topic instead, then I'm vehemently opposed,
since it makes $^_ a kind of *anti*-placeholder.

Introducing that kind of inconsistency would be playing straight
into Simon's hands! ;-)


> Why bother with currying?

You mean placeholders. Currying is something else entirely.


> Why bother with the "it" concept? None of these are necessary.
> They simplify code generation, but their more
> general feature is enabling brevity.

Of usage, yes, but not necessarily of declaration.

Damian

Me

unread,
Nov 11, 2002, 3:11:12 PM11/11/02
to Damian Conway, perl6-l...@perl.org
> You're confusing brevity of declaration
> with brevity of use.

One needs sufficient brevity of both call
and declaration syntax if the mechanism's
brevity is to be of use in short scripts.


> Making (limited) circumvention of [$_'s


> lexicality] depend on a verbose and
> explicit syntax will help too.

Sometimes verbosity doesn't matter, but
I don't see how it can ever help. I'd buy
"clarity".

More to the point, the declaration syntax
will not help with avoiding accidents at
the time of call. So what is driving you
guys to deliberately avoid a brief def
syntax?


> > $foo = sub { print $^_ }; # shorthand for


> > $foo = sub { print $_ } is given($_);

....

> If you're proposing that there be some special
> exemption for $^_ so that it (a) doesn't
> placehold a parameter and (b) aliases the
> caller's topic instead

Well it clearly does placehold something.

In

method f ($self : $a) { ... }
sub f ($a) is given ($line) { ... }

what do you call $self and $line? I am
talking about being able to placehold
these things, whatever you choose to call
them.


> > Why bother with currying?
>
> You mean placeholders.

I meant currying. (I was listing mechanisms
that I believed existed to enable coding
brevity.)


--
ralph

Damian Conway

unread,
Nov 11, 2002, 6:27:40 PM11/11/02
to perl6-l...@perl.org
ralph wrote:

> So what is driving you
> guys to deliberately avoid a brief def
> syntax?

Can't speak for Larry. But what's driving me is the desire
to balance conciseness with comprehensibility, and to keep the
overall cognitive load manageable.


>>If you're proposing that there be some special
>>exemption for $^_ so that it (a) doesn't
>>placehold a parameter and (b) aliases the
>>caller's topic instead
>
> Well it clearly does placehold something.

Sure. It's placeholds a parameter named $^_, which
may or may not be equivalent to a parameter named $_
(Larry will need to rule on that bit).


> In
>
> method f ($self : $a) { ... }
> sub f ($a) is given ($line) { ... }
>
> what do you call $self

The "invocant".

> and $line?

A lexical variable that happens to be bound to the caller's topic.


> I am talking about being able to placehold
> these things, whatever you choose to call
> them.

You can't placehold the invocant, since placeholders create subroutines,
not methods.

We probably *could* find a notation to placehold the C<is given> variable,
but I just can't see the need, when all you have to do now is write
C<is given($var)> after the closure.


>>>Why bother with currying?
>>
>>You mean placeholders.
>
> I meant currying. (I was listing mechanisms
> that I believed existed to enable coding
> brevity.)

Currying is more about efficiency and algorithmic integrity than
brevity. In fact, I would argue that it explciitly *not* about brevity.
Compare:

$incr = &add.assuming(x=>1);

with:

$incr = { add(1,$^y) };

The currying syntax was (deliberately) chosen to be verbose because
powerful or unusual things should be clearly marked.


Ultimately we're discussing philosophy, which is a waste of time since
we are unlikely to convince each other. I think we should just agree
to disagree here, and let Larry decide.

Damian

Me

unread,
Nov 12, 2002, 12:48:06 AM11/12/02
to Damian Conway, perl6-l...@perl.org
> > method f ($self : $a) { ... }
> > sub f ($a) is given ($line) { ... }
> >
> > what do you call $self
>
> The "invocant".
>
> > and $line?
>
> A lexical variable that happens to be
> bound to the caller's topic.

The "invokit" perhaps?


> placeholders create subroutines, not methods.

Oh.

Are placeholders only usable with anonymous
subs, or named subs too?

Switching briefly to currying, can one curry
a method?


--
ralph

Larry Wall

unread,
Nov 13, 2002, 2:05:29 PM11/13/02
to Me, Damian Conway, perl6-l...@perl.org
On Mon, Nov 11, 2002 at 11:48:06PM -0600, Me wrote:
: Are placeholders only usable with anonymous

: subs, or named subs too?

Placeholders are not intended for use with named subs, since named
subs have a way of naming their parameters in a more readable fashion.
However, it may well fall out that if you say

sub foo { $^b <=> $^a }

it would effectively mean the same thing as

sub foo ($a, $b) { $b <=> $a }

But note that there's no placeholder equivalent for a forward declaration:

sub foo ($a, $b) { ... }

: Switching briefly to currying, can one curry
: a method?

Hmm. We can allow what makes sense. I suppose a class should be
allowed to curry one of its own methods on any non-invocant parameter,
since that's just equivalent to defining a new method in the same class.
(Generally, outside of a class, if you want to make the signatures of
the methods look different, the standard way is to derive a new class.)

Currying on the invocant is different, since it essentially turns
a method into a subroutine, and treats a class as a mere module.
This could be construed as antisocial. However, as a special case,
one might often want to curry a set of methods to assume a particular
invocant. But the syntax for that should probably involve the class
rather than the individual methods. Saying

use DB_Connection.assuming(self => new DB_Connection)

could import all of DB_Connection's public methods into the current
class or module as subroutines, and then you don't have to do the
sort of I'm-a-class-no-I'm-a-module shenanigans that modules like
CGI currently do.

Larry

Nicholas Clark

unread,
Nov 13, 2002, 3:34:49 PM11/13/02
to Me, Damian Conway, perl6-l...@perl.org
Apologies for raising the dead (horse)

On Thu, Nov 07, 2002 at 03:27:51PM -0600, Me wrote:
> Damian:
> > ["it" will be passed to about 5% of subs,
> > regardless of whether the context is your
> > 10 line scripts or my large modules]
>
> If the syntax for passing "it" to a sub
> remains as verbose as it currently is,
> you are probably right that "it" won't
> be used to achieve brevity! I think it's
> a pity given that the core point of "it"
> is to achieve brevity.
>
> Why do you think your estimate of Perl 6
> usage of "it" is so much lower than is
> true for the standard Perl 5 functions?

If a subroutine explicitly needs access to its invocant's topic, what is so
wrong with having an explicit read-write parameter in the argument list that
the caller of the subroutine is expected to put $_ in?

It makes it clear.

If I understand all this correctly, as is, this "access caller's topic"
is an unrestricted licence to commit action at a distance.

Accessing the caller's topic is the default in perl5. And there is still a
steady stream of bugs to p5p where core perl modules are doing something
(typically a while loop) which tramples on $_, and so makes something go
wrong in their caller. (possibly several levels down)

(And for that matter the "obvious" solution of local ($_) in perl5 is also
action at a distance if $_ is tied, as local is an immediate fetch and a
store at end of scope. Special case local on $_ ?)

Nicholas Clark
--
perl6 better than perl (this week)? http://www.perl.org/advocacy/spoofathon/
[Alledgedly some judging activity soon. Yeah, right. Pull the other one]

Luke Palmer

unread,
Nov 13, 2002, 3:53:13 PM11/13/02
to ni...@unfortu.net, m...@self-reference.com, dam...@conway.org, perl6-l...@perl.org
> Date: Wed, 13 Nov 2002 20:34:49 +0000
> From: Nicholas Clark <ni...@unfortu.net>

>
>
> If a subroutine explicitly needs access to its invocant's topic, what is so
> wrong with having an explicit read-write parameter in the argument list that
> the caller of the subroutine is expected to put $_ in?
>
> It makes it clear.
>
> If I understand all this correctly, as is, this "access caller's topic"
> is an unrestricted licence to commit action at a distance.
>
> Accessing the caller's topic is the default in perl5. And there is still a
> steady stream of bugs to p5p where core perl modules are doing something
> (typically a while loop) which tramples on $_, and so makes something go
> wrong in their caller. (possibly several levels down)
>
> (And for that matter the "obvious" solution of local ($_) in perl5 is also
> action at a distance if $_ is tied, as local is an immediate fetch and a
> store at end of scope. Special case local on $_ ?)

Indeed. And also mind that many (IIRC all, but I could be wrong)
Perl5 builtins used $_ as the I<default>, and if a parameter was
supplied it would use that.

My favorite was from ages ago:

sub bar(;$foo //= $_) {...}

'Course that could be mistaken for defaulting to the current $_ in
C<bar>'s lexical scope. Regardless, IMO it is better style to always
use $_ as just a default, rather than a requirement. Is there a good
reason to have subs like this:?

sub bar($foo) is given($baz) {...}

Or, if you stick with Perl5 convention, and I imagine this is what
people will expect from the builtins at least:

sub bar($foo; $baz) is given($baz) {...}

That duplicated parameter looks strange, and people will be wary of
using it that way (as I was). I don't know what it looks like, but it
doesn't look like $baz gets $_ if not, well, C<given>.

Luke

Me

unread,
Nov 13, 2002, 7:12:32 PM11/13/02
to Nicholas Clark, Damian Conway, perl6-l...@perl.org
> "access caller's topic" is an unrestricted
> licence to commit action at a distance.

Right.

Perhaps:

o There's a property that controls what subs
can do with a lexical variable. I'll call
it Yours.

o By default, in the main package, topics are
set to Yours(rw); other lexicals are set to
not Yours.

o A mechanism exists for a sub to bypass this
access control for use with library routines.

--
ralph

Andrew Wilson

unread,
Nov 13, 2002, 8:42:24 PM11/13/02
to perl6-l...@perl.org, Nicholas Clark
On Wed, Nov 13, 2002 at 08:34:49PM +0000, Nicholas Clark wrote:
> If a subroutine explicitly needs access to its invocant's topic, what is so
> wrong with having an explicit read-write parameter in the argument list that
> the caller of the subroutine is expected to put $_ in?

It's the difference between this:

print;

and this:

print $_;

It is as far as I'm concerned exactly what topic is all about. It let's
you write subroutines that behave like builtins with respect to $_. I
think it's generally intended to be used like so:

sub my_print is given($default) {
my @args = @_ // $default;
...
}

i.e. only doing stuff with $_ if no explicit parameters are passed.

> It makes it clear.
>
> If I understand all this correctly, as is, this "access caller's topic"
> is an unrestricted licence to commit action at a distance.
>
> Accessing the caller's topic is the default in perl5. And there is still a
> steady stream of bugs to p5p where core perl modules are doing something
> (typically a while loop) which tramples on $_, and so makes something go
> wrong in their caller. (possibly several levels down)

I don't think that'll be a massive problem with this. It's not the same
thing at all because $_ is now lexical it's not passed to stuff you call
unless it specifically asks for it. This will eliminate the trampling
over $_ several levels down. Needlessly messing with caller's $_ will
become like not using strict or warnings. Occasionally useful but
generally frowned on in a "don't do that" kind of way.

andrew
--
Gemini: (May 21 - June 21)
Disappointment is yours when you overestimate the power of the
human spirit.

Damian Conway

unread,
Nov 14, 2002, 7:57:00 PM11/14/02
to perl6-l...@perl.org
Micholas Clarke asked:

> If a subroutine explicitly needs access to its invocant's topic, what is so
> wrong with having an explicit read-write parameter in the argument list that
> the caller of the subroutine is expected to put $_ in?

Absolutely nothing. And perfectly legal. You can even call that rw parameter $_
if you like:

sub get($id_obj, $_ is rw) {
when "who" { return $id_obj.name }
when "choose" { return any($id_obj.features).pick }
when "all" { return $id_obj.features }
}

for «name choose all» {
print get($obj, $_);
}


> If I understand all this correctly, as is, this "access caller's topic"
> is an unrestricted licence to commit action at a distance.

Yes. As in Perl 5.


> Accessing the caller's topic is the default in perl5. And there is still a
> steady stream of bugs to p5p where core perl modules are doing something
> (typically a while loop) which tramples on $_, and so makes something go
> wrong in their caller. (possibly several levels down)

Yes. That's why it's not the default in Perl 6, and you have to specify
a verbose and slightly ungainly property in order to get the behaviour.

Damian

fear...@figaro.weizmann.ac.il

unread,
Nov 15, 2002, 4:31:58 AM11/15/02
to Damian Conway, perl6-l...@perl.org
Damian Conway writes:
> Micholas Clarke asked:
>
> > If a subroutine explicitly needs access to its invocant's topic, what is so
> > wrong with having an explicit read-write parameter in the argument list that
> > the caller of the subroutine is expected to put $_ in?
>
> Absolutely nothing. And perfectly legal. You can even call that rw parameter $_
> if you like:
>
> sub get($id_obj, $_ is rw) {
> when "who" { return $id_obj.name }
> when "choose" { return any($id_obj.features).pick }
> when "all" { return $id_obj.features }
> }
>
> for «name choose all» {
> print get($obj, $_);
> }
>

Just ( my ) terminology clean-up : in this example sub{ } is implicit
topicalizer ( it does not set $_ explicitly ) , and you are setting $_
for perl . that's why you can use "when" .


???

is this valid ?
(morning() is function that analyse stringifyed time )

#!/usr/bin/perl -w

when ~time ~~ &morning { print "good morning" }

__END__

and also

#!/usr/bin/perl -w
$_ = ~time
when &morning() { print "good morning" }

__END__


arcadi .

Damian Conway

unread,
Nov 16, 2002, 4:42:09 PM11/16/02
to perl6-l...@perl.org
Luke Palmer wrote:

> My favorite was from ages ago:
>
> sub bar(;$foo //= $_) {...}

I think that today that would be written more like this:

sub bar(;$foo) is given($def_foo) {
$foo = $def_foo unless exists $foo;
...
}

Though we might get away with:

sub bar(;$foo = $def_foo) is given($def_foo) {
...
}


> Or, if you stick with Perl5 convention, and I imagine this is what
> people will expect from the builtins at least:
>
> sub bar($foo; $baz) is given($baz) {...}

I think this should definitely be a compile-time error.

Damian

Damian Conway

unread,
Nov 16, 2002, 6:53:55 PM11/16/02
to perl6-l...@perl.org
Andrew Wilson wrote:

> It's the difference between this:
>
> print;
>
> and this:
>
> print $_;
>
> It is as far as I'm concerned exactly what topic is all about.

Exactly.


> It let's you write subroutines that behave like builtins with respect
> to $_. I think it's generally intended to be used like so:
>
> sub my_print is given($default) {
> my @args = @_ // $default;
> ...
> }
>
> i.e. only doing stuff with $_ if no explicit parameters are passed.

I would expect that to be by far the most common use of C<is given>.


> I don't think that'll be a massive problem with this. It's not the same
> thing at all because $_ is now lexical it's not passed to stuff you call
> unless it specifically asks for it. This will eliminate the trampling
> over $_ several levels down. Needlessly messing with caller's $_ will
> become like not using strict or warnings. Occasionally useful but
> generally frowned on in a "don't do that" kind of way.

My sentiments precisely. Though it may only be frowned upon in a
"don't do that without documenting it" kind of way. ;-)

Damian

Damian Conway

unread,
Nov 16, 2002, 8:52:21 PM11/16/02
to perl6-l...@perl.org
Acadi asked:

> Just ( my ) terminology clean-up : in this example sub{ } is implicit
> topicalizer

No. It isn't a topicalizer at all.

> ( it does not set $_ explicitly )

Or implicitly.


> and you are setting $_ for perl .

Yes.

> that's why you can use "when" .

Yes.

> is this valid ?
> (morning() is function that analyse stringifyed time )
>
> #!/usr/bin/perl -w
>
> when ~time ~~ &morning { print "good morning" }

Yep. If C<when> is given a boolean, it acts like an C<if>
(except for the automatic C<break> at the end of its block.


> and also
>
>
> #!/usr/bin/perl -w
> $_ = ~time
> when &morning() { print "good morning" }

Almost. You want:

when &morning { print "good morning" }

(i.e. no explicit call parens)

Damian

Damian Conway

unread,
Nov 17, 2002, 4:05:47 PM11/17/02
to perl6-l...@perl.org
Adam D. Lopresto wrote:

> It seems like that would be useful and common enough to write as
>
> sub bar(;$foo is given) {
> ...
> }
>
> Where $foo would then take on the caller's topic unless it was explicitly
> passed an argument.

While I can certainly see the utility of that, I believe it is too confusing
to have all three of:

* C<is topic> on parameters
* C<is given> on parameters
* C<is given> on subroutines

withthe two C<is given>s meaning quiet different things.

In addition, I think saying C<$param is given> doesn't convey what is actually
happening there (i.e. that $param only *defaults* to the caller's topic).

Finally, I would rather we did not have more than one syntax for specifying
default values for parameters.

I still think my original:

sub bar(; $foo = $topic) is given($topic) {...}

is the appropriate compromise.

Damian

Adam D. Lopresto

unread,
Nov 17, 2002, 11:03:34 AM11/17/02
to Damian Conway, perl6-l...@perl.org, ad...@express.cec.wustl.edu
> > My favorite was from ages ago:
> >
> > sub bar(;$foo //= $_) {...}
>
> I think that today that would be written more like this:
>
> sub bar(;$foo) is given($def_foo) {
> $foo = $def_foo unless exists $foo;
> ...
> }
>
> Though we might get away with:
>
> sub bar(;$foo = $def_foo) is given($def_foo) {
> ...
> }

It seems like that would be useful and common enough to write as

sub bar(;$foo is given) {
...
}

Where $foo would then take on the caller's topic unless it was explicitly
passed an argument.

--
Adam Lopresto (ad...@cec.wustl.edu)
http://cec.wustl.edu/~adam/

Never be afraid to tell the world who you are.

--Anonymous

Larry Wall

unread,
Nov 18, 2002, 3:01:22 PM11/18/02
to Damian Conway, perl6-l...@perl.org
On Mon, Nov 18, 2002 at 08:05:47AM +1100, Damian Conway wrote:
: I still think my original:

:
: sub bar(; $foo = $topic) is given($topic) {...}
:
: is the appropriate compromise.

Won't fly. Referring to something lexical before it's declared is
a no-no. I think we need some other way of indicating the outer topic
if we're gonna use it as a default, and I think we do want that.

Perhaps it's a good time for a real keyword for use in defaults:

sub bar(; $foo = topic) {...}

That would let us work it nicely for arrays too:

sub bar(*@args = [topic]) {...}

Without the [], people might get confused about what to do with a $_
containing an array reference. But maybe that means it should really
be a magical variable so we can distinguish

sub bar(*@args = $<mumble>) {...} # default to [$_]
sub bar(*@args = @$<mumble>) {...} # default to @$_

What <mumble> might be is an interesting, er, topic.

Larry

Damian Conway

unread,
Nov 18, 2002, 3:45:25 PM11/18/02
to Larry Wall, perl6-l...@perl.org
Larry Wall wrote:

> On Mon, Nov 18, 2002 at 08:05:47AM +1100, Damian Conway wrote:
> : I still think my original:
> :
> : sub bar(; $foo = $topic) is given($topic) {...}
> :
> : is the appropriate compromise.
>
> Won't fly. Referring to something lexical before it's declared is
> a no-no.

I would maintain that that depends on the associativity of C<is given>. ;-)
But you mean in a strict left-to-right parsing sense.


> I think we need some other way of indicating the outer topic
> if we're gonna use it as a default, and I think we do want that.

I think so too.


> Perhaps it's a good time for a real keyword for use in defaults:
>
> sub bar(; $foo = topic) {...}

That would have to be:

sub bar(; $foo = topic) is given($whatever) {...}

wouldn't it? Otherwise the topic is C<undef>.


Anyway, I think a C<topic> keyword is NQR.
For a start, it introduces a (rather too) subtle difference between:

sub bar($foo = topic) is given($whatever) {...}

and:

sub bar($foo is topic) is given($whatever) {...}

not to mention the pain in continually needing to explain why this is okay:

sub bar($foo is topic = topic) is given($whatever) {...}

but this is not:

sub bar($foo = topic is topic) is given($whatever) {...}


Hmmmmm. Given that the topic is in some sense a property of the lexical
scope of the subroutine body, this might be a possibility:

sub bar($foo is MY.topic) is given($whatever) {...}

But I think there's a better solution. See below.


> That would let us work it nicely for arrays too:
>
> sub bar(*@args = [topic]) {...}
>
> Without the [], people might get confused about what to do with a $_
> containing an array reference. But maybe that means it should really
> be a magical variable

Yep.


> so we can distinguish
>
> sub bar(*@args = $<mumble>) {...} # default to [$_]
> sub bar(*@args = @$<mumble>) {...} # default to @$_
>
> What <mumble> might be is an interesting, er, topic.

I would argue it ought to be just $_, which is, after all,
the One True Topic. And conveniently lexically predeclared in all scopes.

I would also argue that it ought not be called anything else.
Surely don't want two specially named variables for the topic?

Damian

Brent Dax

unread,
Nov 18, 2002, 7:04:51 PM11/18/02
to Damian Conway, Larry Wall, perl6-l...@perl.org
Damian Conway:
# Larry Wall wrote:
# > On Mon, Nov 18, 2002 at 08:05:47AM +1100, Damian Conway wrote:
# > : I still think my original:
# > :
# > : sub bar(; $foo = $topic) is given($topic) {...}
# > :
# > : is the appropriate compromise.
# >
# > Won't fly. Referring to something lexical before it's
# declared is a
# > no-no.
# > sub bar(*@args = $<mumble>) {...} # default to [$_]
# > sub bar(*@args = @$<mumble>) {...} # default to @$_
# >
# > What <mumble> might be is an interesting, er, topic.
#
# I would argue it ought to be just $_, which is, after all,
# the One True Topic. And conveniently lexically predeclared in
# all scopes.

I prefer $CALLER::_ ("CALLER:: - access caller's lexical variables, then
globals"). I'd expect that you could use the same thing for other
variables, e.g. $CALLER::some_lexical. Of course, the can of worms that
opens is horrifying to consider (and no longer has the benefit of the
ugly caller.MY). :^)

--Brent Dax <bren...@cpan.org>
@roles=map {"Parrot $_"} qw(embedding regexen Configure)

Wire telegraph is a kind of a very, very long cat. You pull his tail in
New York and his head is meowing in Los Angeles. And radio operates
exactly the same way. The only difference is that there is no cat.
--Albert Einstein (explaining radio)

Me

unread,
Nov 18, 2002, 7:27:39 PM11/18/02
to Damian Conway, Larry Wall, perl6-l...@perl.org
Larry:
> > sub bar(; $foo = <topicmumble>) {...}
Damian:
> topic [would be] C<undef>.

I assumed <topicmumble> implied an 'is given'.
I don't see why it couldn't.


Damian:


> Hmmmmm. Given that the topic is in some sense
> a property of the lexical scope of the subroutine
> body, this might be a possibility:
>
> sub bar($foo is MY.topic) is given($whatever) {...}

Isn't this confusing dynamic and lexical scopes?
Perhaps:

sub bar (;$foo = YOUR.topic) { ... }
sub bar (;$foo = CALLERS.topic) { ... }


> > sub bar(*@args = $<mumble>) {...} # default to [$_]
> >

> > What <mumble> might be is an interesting, er, topic.
>

Damian:


> I would argue it ought to be just $_

You seem to be saying one could write:

sub bar (;$foo = $_) { ... }

Btw, can one write any/all of these and
have DWIMery:

sub bar (;$_) { ... }
bar ( _ => 1 );
sub bar (;$_ = $_) { ... }

As other's have suggested, a mumble of
$CALLERS::_ makes sense:

sub bar (;$foo = $CALLERS::_) { ... }

but I can see the point of a different
syntax dedicated to just the upscope topic
to avoid encouraging wider use of $CALLERS.

Hmmm.

--
ralph

Larry Wall

unread,
Nov 18, 2002, 9:59:55 PM11/18/02
to Damian Conway, perl6-l...@perl.org
On Tue, Nov 19, 2002 at 07:45:25AM +1100, Damian Conway wrote:
: >What <mumble> might be is an interesting, er, topic.

:
: I would argue it ought to be just $_, which is, after all,
: the One True Topic. And conveniently lexically predeclared in all scopes.
:
: I would also argue that it ought not be called anything else.
: Surely don't want two specially named variables for the topic?

I actually had an entire ramble on that subject that I deleted from
my previous message before I wrote what I wrote. But the gist of
it was similar, in that $_ is of indeterminate meaning in a signature
anyway, so why not force it to mean what we want it to mean? The
long and the short of it was that

my sub foo ($_ := $arg = $_)

is how you might set $arg to be both the "topic" and the "given".
In the common case, that comes down to

my sub foo ($_ = $_)

to just propagate the outer $_ inward. But it still has the problem that
it looks like a declaration of $_ followed by a use of $_ that *isn't* that
declaration. So I was thinking it'd be better to use something different to
represent the outer topic, like:

my sub foo ($_ = $^)
my sub foo ($_ = $+)
my sub foo ($_ = $|)
my sub foo ($_ = $=)
my sub foo ($_ = $:)
my sub foo ($_ = $?)
my sub foo ($_ = $$)
my sub foo ($_ = $@)

or some such. That's what I meant by <mumble>. I kinda like $= at the
moment, presuming it's coming available from formats. Or maybe $?.

Possibly we have something more evil than that, such as the notion that
$? is a double sigil that pulls a name out of the dynamic context's
lexical scope. Then we could write $?_ for the outer $_, $?foo for the
outer $foo, @+_ for the outer @_, $?! for the outer $!, etc. That would
make it

my sub foo ($arg is topic = $?_)

I suppose it could be argued that defaulting the outer topic should also
set the inner topic by default, so you could write

my sub foo ($arg = $?_) {
when 1 { ... }
...
}

I'm trying to remember why it was that we didn't always make the first
argument of any sub the topic by default. I think it had to do with
the assumption that a bare block should not work with a copy of $_ from
the outside. But if the signature for a bare block is ($_ = $?_), and
if the = there is really a binding operator, then the inner $_ is just
an alias for the outer one, and it doesn't really matter in that case.

I'm not sure whether we should allow $?_ in a sub body, however.

for @sortparms {
&closure := { $?_
j ?? $^a <=> $^b
:: $^b <=> $^a
};
sort &closure, @list;
}

In this case, $?_ would be synonymous with $OUTER::_, since the block is
called in the same lexical context. But that wouldn't necessarily always
be the case. We can assume the outer dynamic scope also has a $_ in its
lexical scope, but assuming there's a $?foo out there is more problematic.

But maybe that's one way to explicitly export symbols:

module Foo;
&?foo := &my_foo;

That assumes we can tell the the outer scope is being compiled
currently. It would have the same restrictions as mucking around
with caller.MY, basically.

But don't worry, I still think normal export should be via properties
on the declaration of sub my_foo.

Larry

Damian Conway

unread,
Nov 18, 2002, 11:39:23 PM11/18/02
to Larry Wall, perl6-l...@perl.org
Larry wrote:

> The long and the short of it was that
>
> my sub foo ($_ := $arg = $_)
>
> is how you might set $arg to be both the "topic" and the "given".

Wow. I'm surprised by how much I don't like that syntax! ;-)

I mean, two entirely different meanings for $_ in the space of one parameter
definition? And both := and = in one parameter definition?

I'd *so* much prefer to have to write:

my sub foo ($arg is topic = $CALLER::_)

(see below).


> In the common case, that comes down to
>
> my sub foo ($_ = $_)
>
> to just propagate the outer $_ inward.

That only works when $_ can somehow be shoe-horned into the parameter list.
Whereas:

my sub foo is given($_)

works for *any* parameter list.


> So I was thinking it'd be better to use something different to
> represent the outer topic, like:
>
> my sub foo ($_ = $^)
> my sub foo ($_ = $+)
> my sub foo ($_ = $|)
> my sub foo ($_ = $=)
> my sub foo ($_ = $:)
> my sub foo ($_ = $?)
> my sub foo ($_ = $$)
> my sub foo ($_ = $@)
>
> or some such. That's what I meant by <mumble>. I kinda like $= at the
> moment, presuming it's coming available from formats. Or maybe $?.

$= as an alias for the caller's $_, I could certainly live with.
It's mnemonically *much* better than $?. And it gets rid of the need
for a separate C<is given> property on the subroutine, since the sub
can just refer to $= if it needs to.

And no, formats aren't going to need $=.


> Possibly we have something more evil than that, such as the notion that
> $? is a double sigil that pulls a name out of the dynamic context's
> lexical scope. Then we could write $?_ for the outer $_, $?foo for the
> outer $foo, @+_ for the outer @_,

Typo on that last one (I hope!)


> $?! for the outer $!, etc. That would
> make it
>
> my sub foo ($arg is topic = $?_)

The only problems I have with this are:

1. Do we really want to allow every lexical to be accessible anywhere
in its dynamic scope? This has many of the same drawbacks as C<local>.
$_ is probably a special case (which argues for $= rather than
a general mechanism).

2. If we *do* want to provide that mechanism, do we really want to make
it that easy/subtle/short/missable? If we're going to do this,
I think $CALLER::_, $CALLER::foo, @CALLER::_, $CALLER::! might be
better. At least they're ugly, and scream for special attention. ;-)


> I suppose it could be argued that defaulting the outer topic should also
> set the inner topic by default, so you could write
>
> my sub foo ($arg = $?_) {
> when 1 { ... }
> ...
> }

Yeah, I wouldn't have a problem with that
(except for $?_ not being $CALLER::_ ;-)

Though I think:

my sub foo($arg = $=) {...}

would be even better.

Damian


Me

unread,
Nov 19, 2002, 1:27:25 AM11/19/02
to Damian Conway, Larry Wall, perl6-l...@perl.org
> > my sub foo ($_ = $_)
> >
> > to just propagate the outer $_ inward.
>
> That only works when $_ can somehow be
> shoe-horned into the parameter list.
> Whereas:
>
> my sub foo is given($_)
>
> works for *any* parameter list.

Other than the placeholder situation, I
don't understand when one could do the
'is given($_)' and not do the ($_ = $_).


> > Possibly we have something more evil than
> > that, such as the notion that $? is a double
> > sigil that pulls a name out of the dynamic
> > context's lexical scope.
>

> 1. Do we really want to allow every lexical to
> be accessible anywhere in its dynamic scope?

It is intriguing.

One only needs to know the def of a sub one is
calling. One does not have to worry about subs
that get called by the sub one is calling. Imo
one should know the def of a sub one calls. In
this case one needs to know the pertinent arg
/names/, not just their position, but that is
already somewhat the case for optional args.

When writing in the, er, medium (as against
small or large), one could develop a variable
name vocabulary, rather as one does with
globals, but without its dangers:

A (horrible, but hopefully illustrative)
example:

my $filename = 'foobar';
my $buf;
open;
read;
write;
delete;

I'm imagining a potential sweetspot between
globals and lexicals. An extension of the
power of "it", which is just a way to talk
more succinctly when you can get away with
assumptions about nearby nouns. No?


> 2. If we *do* want to provide that mechanism,
> do we really want to make it that easy/subtle

If the sweetspot I theorize above exists,
then I think my answer is 'yes' to easy.

But, no matter what, NO to subtle. It would
be important that people know that any given
arg is, er, given, or one just ends up with
something that is halfway to the usual global
problem.

I'm thinking the syntax should be, in order
of priority, LOUD, short, pleasing.

I'm also thinking it would be nice to be able
to say that the called sub's lexical shares its
name as well as value (copy or bound) with the
calling sub's lexical, without having to say
the name twice. Further, that this would be a
good pick as the norm, with the syntax optimized
for that, so that it may be more cumbersome when
you want the formal and actual arg names to be
different.

Perhaps we need some Unicode? ;>


--
ralph

Damian Conway

unread,
Nov 19, 2002, 2:28:31 AM11/19/02
to perl6-l...@perl.org
ralph wrote:

> Other than the placeholder situation, I
> don't understand when one could do the
> 'is given($_)' and not do the ($_ = $_).

Any time that the caller's topic isn't supposed to be
explicitly passed as an argument, but is still used within
the subroutine.

For example, the Class::Contract module provides a subroutine
like this:

# Perl 5 code

sub check(\%;$) {
my $state = !$#_ ? 0 : $_[1] ? 0 : 1;
my $forclass = $_;
defined $forclass or croak;

$_[0]->{$forclass} =
bless { prev=>$no_opt{$forclass}, forclass=>$forclass},
'Class::Contract::FormerState';
$no_opt{$forclass} = $state;
}

It is passed a hash (that is used to store objects it generates) and a scalar
that indicates whether checking is to be enabled or disabled. It uses the
callers $_ (which is specifically *not* passed as an argument) to determine
what class to turn checking on or off for. That (slightly odd) interface
allows users of the module to write very tidy code:

check %cache, $on_or_off
for qw/Class1 Class2 Class3/;

C<check> needs the callers $_, but doesn't (want to) have it passed as an
argument. So a ($_ = $_) argument won't work.

And, yes, I could make it an optional argument, but them I have no way of
preserving my chosen interface. Or porting that code cleanly.

Besides all that, ($_ = $_) where $_ means something different from $_
is Just Plain Wrong. ;-)


Damian

Me

unread,
Nov 19, 2002, 3:31:16 AM11/19/02
to Damian Conway, perl6-l...@perl.org
> > don't understand when one could do the
> > 'is given($_)' and not do the ($_ = $_).
>
> Any time that the caller's topic isn't
> supposed to be explicitly passed as an
> argument, but is still used within the
> subroutine.
>
> [example]

>
> And, yes, I could make it an optional
> argument, but them I have no way of
> preserving my chosen interface. Or
> porting that code cleanly.

Well, it would mean the interface gets
the additional facet that the caller can
/optionally/ explicitly pass $_. I'd call
that a benefit, not a problem.

What's the issue with porting cleanly?


> Besides all that, ($_ = $_) where $_
> means something different from $_
> is Just Plain Wrong. ;-)

Well, I don't see it in quite that strong
a tone. One could argue that the context
of the rhs of assignments in the arg list
is /naturally/ the caller's. But I agree
it might cause a good ppl to double-take,
because of the way it looks.

More importantly, it doesn't seem LOUD
enough for what it's doing.

Unless it doesn't need to be loud because
one sorts out the issue of protecting
against potential problems by requiring
some explicit marking at the caller's end,
as I suggested in my recent "Access to
caller's topic" post.


--
ralph

Andy Wardley

unread,
Nov 19, 2002, 6:38:11 AM11/19/02
to Larry Wall, Damian Conway, perl6-l...@perl.org
Larry Wall wrote:
> So I was thinking it'd be better to use something different to
> represent the outer topic...

How about this:

$_ # current topic
$__ # outer topic
$___ # outer outer topic

...etc...

I also wondered if $= might be a suitable alias to the current iterator.
It has a nice mnemonic, looking as it does like a '_' stacked on top
of another.

while <$something> {
if ($=.first) {
# first iteration
}
elsif ($=.last) {
# last iteration
}
}

You could then use $==, $===, etc., to access outer iterators:

while <$foo> {
while <$bar> {
if ($==.first) {
# first foo
}
if ($=.first) {
# first bar
}
}
}


A

Tanton Gibbs

unread,
Nov 19, 2002, 6:56:18 AM11/19/02
to Andy Wardley, Larry Wall, Damian Conway, perl6-l...@perl.org
> How about this:
>
> $_ # current topic
> $__ # outer topic
> $___ # outer outer topic
>

Unfortunately, or maybe fortunately, that is impossible to read correctly
without having to move the cursor and count how many underscores exist.

It seems to me, that in English, it is hard to correctly jump to a previous
topic without being fairly explicit. If you start talking about trapeze
artists and I change the subject to monkees, then if I say I like the way
they swing, you should assume I am talking about monkees unless I have
explicitly changed the topic back to trapeeze artists. I don't think there
should be a shortcut to do this, an explict way, yes, but not a shortcut as
it seems to break the English analogy.

Tanton

Dan Sugalski

unread,
Nov 19, 2002, 12:03:38 PM11/19/02
to Tanton Gibbs, Andy Wardley, Larry Wall, Damian Conway, perl6-l...@perl.org
At 6:56 AM -0500 11/19/02, Tanton Gibbs wrote:
> > How about this:
>>
>> $_ # current topic
>> $__ # outer topic
>> $___ # outer outer topic
>>
>
>Unfortunately, or maybe fortunately, that is impossible to read correctly
>without having to move the cursor and count how many underscores exist.

More to the point, I think it's too much to have to juggle in your
(or at least my) head at once. Sure the computer can do it, but
that's not much use if I can't figure out what's being referred to.

>It seems to me, that in English, it is hard to correctly jump to a previous
>topic without being fairly explicit.

I expect this is due to inherent limitations in people. We can't keep
too much stuff in flight at any one time in our heads, and stacking
referents like this is not something we're well suited for.
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Me

unread,
Nov 19, 2002, 1:11:04 PM11/19/02
to Tanton Gibbs, Andy Wardley, Larry Wall, Dan Sugalski, Damian Conway, perl6-l...@perl.org
> >> $_ # current topic
> >> $__ # outer topic
> >> $___ # outer outer topic
>
> [not sufficiently visibly distinct]
> [too much anyway]

Agreed.

Returning to the topic of binding/copying
from a caller to a callee, what about using
square brackets to mark implicit args thus:

sub bar ($a, $b)
[$_, $foo]
{ ... }

In the above, implicit args go inside the
square brackets and the topic and $foo of
the sub being def'd are the same as (aliased
to) the topic and $foo of the calling sub.

As I said before, if you call a sub you
really ought to know that sub's signature,
and the above would make it clear that $_
and $foo are shared between caller and callee.

Of course, you might then come back and
change your calling code, accidentally
clobbering a shared lexical. So, back at
the caller end of things, I suggest the
following (simplified from an earlier post):

o There's a property that controls whether
called subs can share a given lexical of
a callee. I'll call this property Yours.

o By default, topics are set to Yours(rw);


other lexicals are set to not Yours.

--
ralph

Allison Randal

unread,
Nov 19, 2002, 3:35:10 PM11/19/02
to Me, perl6-l...@perl.org
To summarize, we're discussing 3 features:

a) the ability to set the topic with a block (sub, method, etc)
b) the ability to set a default value for a parameter
c) the ability to break lexical scope
1) for $_ only
2) for any variable

Each of these features already have syntax that allows them to be used
independently:

# a) set topic
sub foo ($param is topic) { ... }
# or it's set implicitly to the first parameter

# b) default
sub foo ($param = 5) { ... }

# c) break lexical scope
$CALLER::varname

The propsals all basically boil down to bits of syntactic sugar that
combine these three features in various ways.

The fundamental question for each of the proposals is "What's the
overall gain for the language in providing syntatic sugar for this
particular combination of features?"

Allison

Allison Randal

unread,
Nov 19, 2002, 4:09:40 PM11/19/02
to Larry Wall, perl6-l...@perl.org
Larry wrote:
> I'm trying to remember why it was that we didn't always make the first
> argument of any sub the topic by default. I think it had to do with
> the assumption that a bare block should not work with a copy of $_ from
> the outside.

I dug through the archives. We were considering allowing dynamic scoping
of $_ across subroutine calls (for backward compatibility with p5), so
we delayed any final call on whether subs topicalize their first
argument. We've pretty much resolved the first: such an abuse of lexical
scope should be explicitly marked.

For consistency, I think the first argument of subs should be the topic by
default.

Allison

Austin Hastings

unread,
Nov 19, 2002, 4:24:30 PM11/19/02
to Allison Randal, Me, perl6-l...@perl.org
So what's wrong with:

sub foo($param is topic //= $= // 5) # Shorter form with $=
sub foo($param is topic //= $CALLER::_ // 5)

It doesn't really seem like we can make it much shorter. Yes, we could
convert //= into a single character, but why? People will understand
//=.

The idea of $= as CALLER::_ is good, though.

Also, since we're jamming things into the signature, how do we declare
call-by-value/call-by-reference info?

=Austin

Austin Hastings

unread,
Nov 19, 2002, 4:28:41 PM11/19/02
to Allison Randal, Larry Wall, perl6-l...@perl.org

--- Allison Randal <a...@shadowed.net> wrote:

For methods, will that be the invocant or the first other parameter?

$string.toLanguage("french")

Topic is $string, or "french" ?

=Austin

Allison Randal

unread,
Nov 19, 2002, 4:33:26 PM11/19/02
to Austin Hastings, perl6-l...@perl.org
Austin wrote:
>
> For methods, will that be the invocant or the first other parameter?
>
> $string.toLanguage("french")
>
> Topic is $string, or "french" ?

It is the invocant.

Allison

Allison Randal

unread,
Nov 19, 2002, 4:44:16 PM11/19/02
to Austin Hastings, perl6-l...@perl.org
On Tue, Nov 19, 2002 at 01:24:30PM -0800, Austin Hastings wrote:
> So what's wrong with:
>
> sub foo($param is topic //= $= // 5) # Shorter form with $=
> sub foo($param is topic //= $CALLER::_ // 5)
>
> It doesn't really seem like we can make it much shorter. Yes, we could
> convert //= into a single character, but why? People will understand
> //=.

There's not really anything wrong with it. But one of the tricks to an
elegant language is that it provides syntatic sugar for commonly used
features, instead of requiring you to type out long arcane sequences.
The problem is deciding which features deserve the sugar.

> The idea of $= as CALLER::_ is good, though.

Though C<//= $= //> is a nasty sequence.

Allison

Deborah Ariel Pickett

unread,
Nov 19, 2002, 5:02:05 PM11/19/02
to Allison Randal, Austin Hastings, perl6-l...@perl.org
Ah . . . one message with two things I wanted to talk about. Good.

Allison wrote:
> On Tue, Nov 19, 2002 at 01:24:30PM -0800, Austin Hastings wrote:
> > So what's wrong with:
> >
> > sub foo($param is topic //= $= // 5) # Shorter form with $=
> > sub foo($param is topic //= $CALLER::_ // 5)

^^^
Don't I recall Larry saying that C< //= > for setting a parameter's
default value was a Bad Idea, because it means that you can't explicitly
pass C<undef> to foo()? I thought it'd been changed to C< = > for that
reason.

Or is this piece of code doing something different?

> > It doesn't really seem like we can make it much shorter. Yes, we could
> > convert //= into a single character, but why? People will understand
> > //=.
>
> There's not really anything wrong with it. But one of the tricks to an
> elegant language is that it provides syntatic sugar for commonly used
> features, instead of requiring you to type out long arcane sequences.
> The problem is deciding which features deserve the sugar.

(See my remark about three paragraphs down.)

> > The idea of $= as CALLER::_ is good, though.

I'd like to raise my hand in the "please, God, no!" camp, for C< $= >.
One of the things about Perl 5 that I dislike the most is all the $( $>
$- $= $[ $$ special variables. Yes, we're losing almost all of them - I
think the only one that is really left is $! (*), which I can live with
- but if we're going to introduce more of these, then perhaps we're not
learning from our past mistakes as well as we think we are.

Yes, we've already been through the whole C<use English;> thing and how
no one uses it. We don't need to talk about it again. I'm just
expressing an opinion. Move along, and tell me how these continuation
thingies work again.

Besides: inheriting a caller's topic isn't going to be that common a
thing that it needs such a short name, is it?

> Though C<//= $= //> is a nasty sequence.

(*) $_ I don't consider special, because my C training leads me to think
of _ as an alphabetic character. Probably not true in a Perl lexer, but
it's how my brain functions.

--
Debbie Pickett http://www.csse.monash.edu.au/~debbiep deb...@csse.monash.edu.au
"I am the eye in the sky, looking at you, I can read your mind. I am the maker
of rules, dealing with fools, I can cheat you blind. And I don't need to see any
more to know that I can read your mind." - _Eye in the Sky_, APP

Austin Hastings

unread,
Nov 19, 2002, 5:18:21 PM11/19/02
to Allison Randal, perl6-l...@perl.org

--- Allison Randal <a...@shadowed.net> wrote:

Final // only required for "another default":
//= $= // 5 # Default to $CALLER::_, or 5

Allison Randal

unread,
Nov 19, 2002, 5:41:16 PM11/19/02
to Austin Hastings, perl6-l...@perl.org
Austin wrote:
> > > The idea of $= as CALLER::_ is good, though.
> >
> > Though C<//= $= //> is a nasty sequence.
>
> Final // only required for "another default":
> //= $= // 5 # Default to $CALLER::_, or 5

Aye, it's just a worst case scenario. C<//= $=> and C<= $=> are still
line-noisy. It's a trade-off between clarity and brevity.

Allison

--
"Mene, mene, tekel"

Austin Hastings

unread,
Nov 19, 2002, 5:43:55 PM11/19/02
to Deborah Ariel Pickett, Allison Randal, Austin Hastings, perl6-l...@perl.org

--- Deborah Ariel Pickett <deb...@mail.csse.monash.edu.au> wrote:
> Ah . . . one message with two things I wanted to talk about. Good.
>
> Allison wrote:
> > On Tue, Nov 19, 2002 at 01:24:30PM -0800, Austin Hastings wrote:
> > > So what's wrong with:
> > >
> > > sub foo($param is topic //= $= // 5) # Shorter form with $=
> > > sub foo($param is topic //= $CALLER::_ // 5)
> ^^^
> Don't I recall Larry saying that C< //= > for setting a parameter's
> default value was a Bad Idea, because it means that you can't
> explicitly
> pass C<undef> to foo()? I thought it'd been changed to C< = > for
> that
> reason.
>
> Or is this piece of code doing something different?

Maybe. This code says "if $param is undef, pull the value from
$CALLER::_. If THAT is undef, it's 5."

So obviously this example doesn't WANT there to be an undef.

But if you wanted an undef and passed it, it wouldn't take it.

So obviously we need ///=, the "only if it REALLY wasn't there"
operator. :-)

Or we could give special meaning to =.

Drat.

Good catch, though.

>
> (See my remark about three paragraphs down.)
>

> I'd like to raise my hand in the "please, God, no!" camp, for C< $=
> >.
> One of the things about Perl 5 that I dislike the most is all the $(
> $>
> $- $= $[ $$ special variables. Yes, we're losing almost all of them
> - I
> think the only one that is really left is $! (*), which I can live
> with
> - but if we're going to introduce more of these, then perhaps we're
> not
> learning from our past mistakes as well as we think we are.

Or maybe we're making a valid, justified decision that facilitating
this kind of thing is desirable.

Remember, signatures are getting an AWFUL lot of information crammed
into them. In fact, I wonder if your question wouldn't be better asked
about all the information we're putting into them: Do we actually know
enough about what we're doing to justify all this?

So far there are (modulo my having confused the line noise):

sub versive(
$invocant is topic:
$arg is rw,
@array is ro,
*@flattened_rest;
@optional_named_ones)
is cached
{
print "Don't let my rhyme \n"
~ " raise your hackles -- \n"
~ "Learn perl6 instead, \n"
~ " Cast off your shackles!\n\n";

print " - OR - \n\n";

print "When your data base \n"
~ " is in a fix -- \n"
~ "Don't sweat the details, \n"
~ " Learn Perl 6! \n";
~ "Burma Shave!\n";
}

And now we're trying to find out how to add one more item --
inherit-from-caller.

It's really a neat idea, since it represents putting an entire idiom
into a single glyph -- essentially, surrounding every sub with

if ($#_ == 0) { $_ := $CALLER::_; <REST OF SUB> }

Except that it's more than that, since you can do it for ANY part:

sub join($re, @*list = $=) # Shouldn't that be @=?

=Austin

Me

unread,
Nov 19, 2002, 5:44:49 PM11/19/02
to Allison Randal, perl6-l...@perl.org
> c) the ability to break lexical scope

Well, I could argue that c) already exists
in the form of passing parameters in parens.

Of course, that doesn't feel like "breaking"
anything.

So instead I'll argue that the word "break"
is perhaps prejudicially perjorative.

I'd say, to steer away from being ppp:

c) introducing 'locals' or 'yours'

Where this terminology and perspective comes
from:

My view is that c) is about sharing vocabulary
between a caller and a callee to retain much
of the referential simplicity and brevity of
globals (and hence I think it's a pretty large
issue), and c) is also about the fact that this
can be done while omitting /all/ the dangers of
globals (short of dangers that also apply to
ordinary lexicals).

Elements of this shared vocabulary might be
called 'locals' or 'yours'.

--
ralph

Mark J. Reed

unread,
Nov 19, 2002, 5:57:13 PM11/19/02
to perl6-l...@perl.org
On 2002-11-19 at 16:44:49, Me wrote:
> Elements of this shared vocabulary might be
> called 'locals' or 'yours'.
I like the 'yours' idea from the point of view of the callee:

my $inherited = your $_;

However, I also like the idea of having to mark shareable lexicals
explicitly in the caller, and the "your" keyword doesn't work as well
from the caller's point of view:

your $_;
somesub(); # this sub can see $_

It almost calls for "our"; too bad that's taken. Although the current
"our" has the "exclusive we" meaning (me and others but not you), and this
would be more of an "inclusive we" (me and you and maybe others); too bad
English only has the one set of pronouns for both.

--
Mark REED | CNN Internet Technology
1 CNN Center Rm SW0831G | mark...@cnn.com
Atlanta, GA 30348 USA | +1 404 827 4754

Me

unread,
Nov 19, 2002, 5:54:46 PM11/19/02
to Deborah Ariel Pickett, Allison Randal, Austin Hastings, perl6-l...@perl.org
> inheriting a caller's topic isn't going to be
> that common a thing that it needs such a short
> name, is it?

15% of the perl 5 builtins do so.

I have suggested that, in some extreme
scenarios such as short scripts, perhaps
as many as 50% of subs might do so. But
then again I probably ate a lot of cheese
just prior to suggesting that.

Damian has estimated that 5% of perl 6
code will do so. I've heard he can wolf
a lot of pizza.

--
ralph

Me

unread,
Nov 19, 2002, 6:22:58 PM11/19/02
to Mark J. Reed, perl6-l...@perl.org
> > Elements of this shared vocabulary might be
> > called 'locals' or 'yours'.
>
> I like the 'yours' idea from the point of
> view of the callee:
>
> my $inherited = your $_;

I like that syntax, but I'm uncomfortable
with an underlying principle, which is that
one can reach in to the caller's lexical
context from any place in a callee's body.
It exacerbates the (mostly over-stated, imo)
action-at-a-distance concerns about this.

I know you can do what you wrote anyway with
the $CALLER::foo syntax, but I don't like that
either.

Allison et al have already intimated that they
too find a generic 'yours' (or $CALLER::foo)
capability that can be fired off anywhere in
a sub's body to be dangerously obscure, to say
the least. So while they expect to provide the
raw $CALLER::foo capability, they have suggested
some sugar that's a lot prettier AND a lot less
dangerous for common cases (probably just for
dealing with $_, though I am currently thinking
it could work rather nicely to have it work for
any lexical).

Hence my focus on putting any callee side 'yours'
sugar in the sub preamble.


> However, I also like the idea of having to
> mark shareable lexicals explicitly in the
> caller, and the "your" keyword doesn't work
> as well from the caller's point of view:
>
> your $_;
> somesub(); # this sub can see $_
>
> It almost calls for "our"; too bad that's
> taken.

I was thinking of yours as in "yours too",
and as in a property:

my $foo is yours;

$_ would be yours(rw) by default, all other
lexicals are not yours by default. The ability
to have yours(ro) and yours(rw) is part of why
I was thinking in terms of a property rather
than a, er, whatever C<my> is.

--
ralph

Allison Randal

unread,
Nov 19, 2002, 6:47:35 PM11/19/02
to Me, perl6-l...@perl.org
Me wrote:
> > c) the ability to break lexical scope
>
> Well, I could argue that c) already exists
> in the form of passing parameters in parens.
>
> Of course, that doesn't feel like "breaking"
> anything.

Formal parameters are lexically scoped.

Lexical scope: references to the established entity can occur only
within certain program portions that are lexically contained within the
establishing construct.

> So instead I'll argue that the word "break"
> is perhaps prejudicially perjorative.
>
> I'd say, to steer away from being ppp:
>
> c) introducing 'locals' or 'yours'
>
> Where this terminology and perspective comes
> from:
>
> My view is that c) is about sharing vocabulary
> between a caller and a callee to retain much
> of the referential simplicity and brevity of
> globals (and hence I think it's a pretty large
> issue), and c) is also about the fact that this
> can be done while omitting /all/ the dangers of
> globals (short of dangers that also apply to
> ordinary lexicals).
>
> Elements of this shared vocabulary might be
> called 'locals' or 'yours'.

It's a valid proposal. It's just not lexical scope.

I'm categorizing, not judging. This fits as a (c) feature.

Allison

Brent Dax

unread,
Nov 19, 2002, 9:01:22 PM11/19/02
to Me, Mark J. Reed, perl6-l...@perl.org
Me:
# > > Elements of this shared vocabulary might be
# > > called 'locals' or 'yours'.
# >
# > I like the 'yours' idea from the point of
# > view of the callee:
# >
# > my $inherited = your $_;
#
# I like that syntax, but I'm uncomfortable
# with an underlying principle, which is that
# one can reach in to the caller's lexical
# context from any place in a callee's body.
# It exacerbates the (mostly over-stated, imo)
# action-at-a-distance concerns about this.
#
# I know you can do what you wrote anyway with
# the $CALLER::foo syntax, but I don't like that
# either.

We need that capability if we're going to have lexically-scoped exports:

{
use FooBar 'baz';
baz(); #OK
}
baz(); #Unknown subroutine

Now, we can either include it in the Perl language or write it specially
for Exporter. If we write it specially for Exporter, someone will
generalize the code and put it in a module (witness PadWalker.pm), so we
might as well have it in the base language and save someone some
hassles.

--Brent Dax <bren...@cpan.org>
@roles=map {"Parrot $_"} qw(embedding regexen Configure)

Wire telegraph is a kind of a very, very long cat. You pull his tail in
New York and his head is meowing in Los Angeles. And radio operates
exactly the same way. The only difference is that there is no cat.
--Albert Einstein (explaining radio)

Brent Dax

unread,
Nov 19, 2002, 10:22:47 PM11/19/02
to Me, Mark J. Reed, perl6-l...@perl.org
Me:
# I am thinking one should have to predeclare
# in a sub's preamble that such a trick will
# be going on.
#
# Thus something like:
#
# sub foo [&bar] { ... }
#
# is (part of what is) required to be allowed
# to create a bar sub in the context of the
# caller of foo.

So how does Exporter declare its import() function?

Me

unread,
Nov 19, 2002, 9:53:01 PM11/19/02
to Brent Dax, Mark J. Reed, perl6-l...@perl.org
> # I'm uncomfortable [that]

> # one can reach in to the caller's lexical
> # context from any place in a callee's body.
>
> We need that capability if we're going to
> have lexically-scoped exports:

I think I was a bit careless in how I worded
that.

My problem is not that one reaches in to the
caller's lexical context, but where one gets
to declare that that is going to happen.

I am thinking one should have to predeclare

in a sub's preamble that such a trick will

be going on.

Thus something like:

sub foo [&bar] { ... }

is (part of what is) required to be allowed

to create a bar sub in the context of the

caller of foo.

--
ralph

Me

unread,
Nov 20, 2002, 12:30:57 AM11/20/02
to Me, Brent Dax, Mark J. Reed, perl6-l...@perl.org
> # I am thinking one should have to predeclare
> # in a sub's preamble that such a trick will
> # be going on.
> #
> # Thus something like:
> #
> # sub foo [&bar] { ... }
> #
> # is (part of what is) required to be allowed
> # to create a bar sub in the context of the
> # caller of foo.
>
> So how does Exporter declare its import() function?

Keeping things simple, something like:

method import [*] { ... }

is required if one is to use $CALLERS::
in the body.

Skip the rest unless you enjoy flights
of pure fancy.

=========

Being really radical, perhaps [*] means
that all the lexicals in the caller are
mapped to an identical set of lexicals
in the called. Dangerous stuff, huh?

Entering the realms of the truly insane,
one could have something like:

method import (@symbols)
[ { @symbols } ]
{ ... }

to indicate run time eval of the locals
list, but the above ignores all sorts
of practical problems and is plainly
huge overkill for the situation.

(All of this would of course still be
subject to the Yours property that by
default restricts localization to the
topic, and to non-existent lexicals,
ones the called sub intends to /add/
to the caller's lexical context.)

--
ralph

Andy Wardley

unread,
Nov 20, 2002, 4:20:58 AM11/20/02
to Me, perl6-l...@perl.org
Me wrote:
> Well, I could argue that c) already exists
> in the form of passing parameters in parens.

This reminds me of the Law of Demeter. It specifies what your methods
should and shouldn't be able to do if you want to build a bright, shiny
system that never has bugs, maintains itself, turns water into wine, etc.

The essence is about limiting what you can access (and therefore screw up)
from a particular scope. It's like a mild form of the "no side effects"
policy of certain functional programming languages. I'm not sure how
applicable it's going to be to Perl 6, but here's the view from 30,000 feet.


Object Form of Law of Demeter
-----------------------------

"Do not talk to strangers".

Within a method, messages can only be sent to the following objects:

1. A parameter of the method, including the enclosing object (this or self);

1.1. For pragmatic reasons: a global object;

2. An immediate part object (computed or stored):

2.1 An object that a method called on the enclosing object returns,
including attributes of the enclosing object;
2.2 An element of a collection which is an attribute of the enclosing
object;

3. An object created within the method.


Usenet Form of Law of Demeter
-----------------------------

* You can play with yourself.
* You can play with your own toys (but you can't take them apart),
* You can play with toys that were given to you.
* You can play with toys you've made yourself.


Interested parties should Google[ law of demeter ] for the full story.

A

Larry Wall

unread,
Nov 20, 2002, 2:59:23 PM11/20/02
to Allison Randal, perl6-l...@perl.org

This might work now, presuming

sub foo (;$_ = $=)

(or whatever) is really a binding, and not an assignment. (That's another
reason why //= is *wrong*--it implies assignment.)

I guess it's almost an epistemological issue. Suppose you see the
following general code:

$_ = 1;
mumble {
$_ = 2;
}
print $_;

How can you know whether it will print 1 or 2? It will depend on
both the signature of C<mumble>, and the signature of the bare closure
passed to it. Things that are trying to look like C<grep> or C<map>
obviously want to have a private $_. Things that are trying to look
like C<if> or C<while> will want to share $_ with the outside scope.

I suspect the bare block has to have a signature like (;$_ = $=) in the
absence of $^a etc. That means that a bare block always treats $_ as
pseudo-dynamic (by aliasing two lexicals). That means

$sub = {
$_ = 2;
};

$_ = 1;
$sub();
print $_;

would print 2.

But if the bare block always binds $_ inward, it's the wrapper that
actually decides the issue. For something if-like:

sub mumble (&block; $_ = $=) {
block();
}

For something grep-like:

sub mumble (&block) {
block()
}

Oddly, if we make the first argument the topic by default, the second
block actually gets &block as its topic. That's...strange. People will
expect it (rightly or wrongly) to be initialized with the outer value,
even if it's just a copy. Hmm...need to think about this s'more...

Larry

Austin Hastings

unread,
Nov 20, 2002, 3:11:52 PM11/20/02
to Larry Wall, Allison Randal, perl6-l...@perl.org

--- Larry Wall <la...@wall.org> wrote:
> ...

> This might work now, presuming
>
> sub foo (;$_ = $=)
>
> (or whatever) is really a binding, and not an assignment. (That's
> another reason why //= is *wrong*--it implies assignment.)

Umm, that's what it was supposed to do.

IOW: sub($param //= $=)

means "if you don't get one, grab the value of $=."

As opposed to sub($param ://= $=)

which would be a horrible-looking way of getting something by
reference.

Which is also why I asked about value/reference semantics.

Or is ";" supposed to be the "here be reference-args" delimiter? (I
thought it meant "here be named parameters"...)


=Austin


Martin D Kealey

unread,
Nov 19, 2002, 9:15:35 PM11/19/02
to Brent Dax, perl6-l...@perl.org
On Wed, 2002-11-20 at 15:01, Brent Dax wrote:
> We need that capability if we're going to have lexically-scoped exports:

Whilst it would be useful for pragmatic modules to access anything and
everything in the current compilation scope, I submit that access to
dynamic scope should (in general) be more closely controlled... and of
course the former can be used to implement the latter:

use visible '$topic';

no visible '$_';

-Martin

Luke Palmer

unread,
Nov 20, 2002, 3:49:48 PM11/20/02
to Austin_...@yahoo.com, la...@wall.org, a...@shadowed.net, perl6-l...@perl.org
> Date: Wed, 20 Nov 2002 12:11:52 -0800 (PST)
> From: Austin Hastings <austin_...@yahoo.com>

>
>
> --- Larry Wall <la...@wall.org> wrote:
> > ...
>
> > This might work now, presuming
> >
> > sub foo (;$_ = $=)
> >
> > (or whatever) is really a binding, and not an assignment. (That's
> > another reason why //= is *wrong*--it implies assignment.)
>
> Umm, that's what it was supposed to do.
>
> IOW: sub($param //= $=)
>
> means "if you don't get one, grab the value of $=."

More like "if you don't get one, bind to $="

Copying stuff should always be explicit, as it can take awhile. I'm
wondering how //= implies assignment while = doesn't. But I tend to
like = better anyway. And using := :

sub foo ($param := $=) {...}

Just feels wrong. I guess there was no point to what I just wrote...

> As opposed to sub($param ://= $=)
>
> which would be a horrible-looking way of getting something by
> reference.

Using an operator that doesn't exist.

> Which is also why I asked about value/reference semantics.
>
> Or is ";" supposed to be the "here be reference-args" delimiter? (I
> thought it meant "here be named parameters"...)

Neither. It means "here be optional parameters." Just like Perl 5.

Luke

Me

unread,
Nov 20, 2002, 5:20:07 PM11/20/02
to Larry Wall, Allison Randal, perl6-l...@perl.org
> $_ = 1; mumble { $_ = 2 }; print;

>
> will print 1 or 2?

Least surprise, visually, is obviously 2.

This would be true if bare blocks (even
those passed as args) just pick up from
the surrounding lexical context. And if
that were true, mumble presumably could
not do anything about this (without some
as yet undefined language support).

What does this mean:

$_ = 1; mumble -> { $_ = 2 }; print;

perhaps the '->' could imply that $_ /is/
going to be private to the block somehow?
Could mumble somehow be a continuation that
alternated between generating values to be
plugged in to the block and executing it?


> sub mumble (&block) {
> block()
> }
>
> Oddly, if we make the first argument the
> topic by default, the second block actually
> gets &block as its topic. That's...strange.

This would go away with the above scenario.

--
ralph

Larry Wall

unread,
Nov 20, 2002, 9:26:17 PM11/20/02
to Me, Allison Randal, perl6-l...@perl.org
On Wed, Nov 20, 2002 at 04:20:07PM -0600, Me wrote:
: > $_ = 1; mumble { $_ = 2 }; print;

: >
: > will print 1 or 2?
:
: Least surprise, visually, is obviously 2.
:
: This would be true if bare blocks (even
: those passed as args) just pick up from
: the surrounding lexical context. And if
: that were true, mumble presumably could
: not do anything about this (without some
: as yet undefined language support).

Yes, that's the problem. A bare block would have to notice at run
time that it was called with unexpected arguments and unbind its
binding to the outer $_. That's probably not gonna fly.

: What does this mean:


:
: $_ = 1; mumble -> { $_ = 2 }; print;
:
: perhaps the '->' could imply that $_ /is/
: going to be private to the block somehow?

As it stands now, explicitly telling it there are no arguments would
have exactly the opposite effect, and bind $_ to the outer $_.

: Could mumble somehow be a continuation that


: alternated between generating values to be
: plugged in to the block and executing it?

Well, sure, doesn't need to be a continuation for that. Doesn't
even need to be a coroutine unless you plan to get the values one
by one.

: > sub mumble (&block) {


: > block()
: > }
: >
: > Oddly, if we make the first argument the
: > topic by default, the second block actually
: > gets &block as its topic. That's...strange.
:
: This would go away with the above scenario.

True, but I think C<mumble> has to be able to wrap its own idea of $_
around the block at compile time somehow. Perhaps we need to distinguish
the type of a "thunk" from a "sub" in the signature of C<mumble>.

sub mumble1 (Sub &block) { block($curtopic) }
sub mumble2 (Block &block) { block() }

Then

mumble1 { ... }

would compile to

mumble1 -> $_ { ... }

while

mumble2 { ... }

would compile to

mumble2 -> { ... }

forcing $_ to bind outward like a closure.

Possibly those are declared

sub mumble1 (&block(Scalar)) { block($curtopic) }
sub mumble2 (&block) { block() }

since code blocks are essentially typed by their signatures.

Larry

Brent Dax

unread,
Nov 21, 2002, 2:11:05 AM11/21/02
to Martin D Kealey, perl6-l...@perl.org
Martin D Kealey:
# On Wed, 2002-11-20 at 15:01, Brent Dax wrote:
# > We need that capability if we're going to have lexically-scoped
# > exports:
#
# Whilst it would be useful for pragmatic modules to access
# anything and everything in the current compilation scope, I
# submit that access to dynamic scope should (in general) be
# more closely controlled... and of course the former can be
# used to implement the latter:
#
# use visible '$topic';
#
# no visible '$_';

if($error) {
require Carp;
import Carp: 'croak';
croak($error);
}

Are you suggesting this?

if($error) {
use visible '&croak';
require Carp;
import Carp: 'croak';
croak($error);
}

That'll add up rather quickly, and further is dangerously easy to subtly
screw up.

--Brent Dax <bren...@cpan.org>
@roles=map {"Parrot $_"} qw(embedding regexen Configure)

"If you want to propagate an outrageously evil idea, your conclusion
must be brazenly clear, but your proof unintelligible."
--Ayn Rand, explaining how today's philosophies came to be

Me

unread,
Nov 21, 2002, 12:27:07 PM11/21/02
to Larry Wall, Allison Randal, perl6-l...@perl.org
> [perhaps]
> : bare blocks (even those passed as args) just

> : pick up from the surrounding lexical context.

This is definitely a significant simplification.
Is it a problem?

> Yes, that's the problem. A bare block would
> have to notice at run time that it was called
> with unexpected arguments and unbind its
> binding to the outer $_.

That would be ughly, but I don't understand why
you say it must necessarily be so.


> : What does this mean:
> :
> : $_ = 1; mumble -> { $_ = 2 }; print;
> :
> : perhaps the '->' could imply that $_ /is/
> : going to be private to the block somehow?
>
> As it stands now, explicitly telling it there
> are no arguments would have exactly the opposite
> effect, and bind $_ to the outer $_.

Oh.

I had the vague notion that (inline) bare blocks
don't do anything special beyond establishing
a nested lexical scope:

$_ = 1; { $_ = 2 }; print; # 2

whereas '->' means the topic gets set and is
private to the block (ignoring aliasing effects):

$_ = 1; for @foo -> $_ { $_ = 2 }; print; # 1

It seems to me that a logical conclusion would be
that a blank arg list after a '->' would mean the
topic remains private (and is set to undef).

Perhaps having bare blocks work the same simple
way whether or not they appear as an arg, and
have -> behave the same simple way whether or
not it is used with, say, a for, or as a sub
def, introduces problems or lost opportunities
elsewhere that nix the whole idea. But wait...


> I think C<mumble> has to be able to wrap its own
> idea of $_ around the block at compile time somehow.

Perhaps.

But presumably you agree that it would be
nice if the calling syntax naturally made
it clear how $_ was being bound.

And documenting this by the '->' distinction
described above (ie -> means private $_ set
by mumble, no -> means $_ is just the outer
lexical) would look natural as well being
logical and strikingly simple.


> Perhaps we need to distinguish the type of
> a "thunk" from a "sub" in the signature of
> C<mumble>.

This would not be necessary with the scenario
I describe above.


--
ralph

Larry Wall

unread,
Nov 21, 2002, 3:26:22 PM11/21/02
to Me, Allison Randal, perl6-l...@perl.org
On Thu, Nov 21, 2002 at 11:27:07AM -0600, Me wrote:
: And documenting this by the '->' distinction

: described above (ie -> means private $_ set
: by mumble, no -> means $_ is just the outer
: lexical) would look natural as well being
: logical and strikingly simple.

It would, however, force people to write:

grep -> { /foo/ } @list;

I'd like to avoid that. I think {...} can be somewhat context
sensitive. It's certainly context sensitive in Perl 5, though
we'd like to get away from kludges like the $a/$b thing for sort.
But Perl 5 knows which blocks take a local $_ and which ones don't.
We aren't implementing it by temporizing a global in Perl 6, but we
could still presumably know which blocks work which way.

I think maybe the best way to think of it is to say that every block
always binds its first argument to $_, but there's enough mechanism to
make sure that the binding is to the outer $_ where that's expected,
such as for bare blocks and control structures that don't pass arguments
to their closures. If that's known at compile time, it can be done
with ordinary lexical scoping of $_, but that's an implementation detail.

Larry

Me

unread,
Nov 21, 2002, 6:08:22 PM11/21/02
to Martin D Kealey, Brent Dax, perl6-l...@perl.org
> > Are you suggesting this?
> >
> > if($error) {
> > use visible '&croak';
> > require Carp;
> > import Carp: 'croak';
> > croak($error);
> > }
>
> No - that would be pointless as well as error-prone.
>
> My idea of "visible" is that it would make a lexically scoped thing
> accessible to an inner dynamic scope at run-time.
>
> By default that would only apply to $_, but the mechanism should be
> generalisable to any name.

Yes. Regardless of the exact syntax, the idea
is presumably that the default way in which a
called sub can see/modify its caller's lexical
space is that it can see $_, can't see other
existing lexicals, and can add new lexicals.
Or something like that.

--
ralph

Martin D Kealey

unread,
Nov 21, 2002, 5:54:53 PM11/21/02
to Brent Dax, perl6-l...@perl.org
On Thu, 2002-11-21 at 20:11, Brent Dax wrote:
> Are you suggesting this?
>
> if($error) {
> use visible '&croak';
> require Carp;
> import Carp: 'croak';
> croak($error);
> }

No - that would be pointless as well as error-prone.

My idea of "visible" is that it would make a lexically scoped thing
accessible to an inner dynamic scope at run-time.

By default that would only apply to $_, but the mechanism should be
generalisable to any name.

-Martin

Christopher E. Stith

unread,
Dec 19, 2002, 9:19:55 PM12/19/02
to
la...@wall.org (Larry Wall) wrote in message news:<2002112120...@wall.org>...


> I think maybe the best way to think of it is to say that every block
> always binds its first argument to $_, but there's enough mechanism to
> make sure that the binding is to the outer $_ where that's expected,
> such as for bare blocks and control structures that don't pass arguments
> to their closures. If that's known at compile time, it can be done
> with ordinary lexical scoping of $_, but that's an implementation detail.

What strikes me, and has been presenting itself to me this whole
thread, is a magical array.

@topic[0] is syntactic vinegar for $_
@topic[1] is my caller's topic
@topic[2] is my caller's caller's topic

Of course, s/topic/your favorite character(s) to do the job/;

What is nasty is the action in the body of the block. For subroutines
specifically, this could be fixed by making a scope for the magic
that is only visible inside the signature:

sub liminal ( $_ = @topic[x] ) {
# @topic is not valid here
# (or at least has an unrelated meaning, which option I don't like
# for purposes of confusion)
}

The topic defaults to your own new and polished topic if it's not
specified in the signature. If you actually need to conditionally
have or not have the same subroutine take or not take its topic in
this way...

sub liminal ( $arg1, $_ = @topic[$arg1] ) {
# with which @topic[0] means a new one other than any
# ancestor in the call stack
}

Of course, any number of args go with this, too:

sub liminal ( $arg1, ..., $argn, $_ = @topic[1] ) {
}

If you want a general way to alleviate action at a distance, there's
the (probably inelegant) hack of making a special block-inside-a-block
which must appear first inside its parent block:

{
special { $_ = @topic[1]; } ### valid
### continue the block
}

{
### do something
special{ $_ = @topic[1]; } ### invalid
### anything else
}

I of course am not attached to the notation.

Please, dismember the post and not the author.

Chris

0 new messages