Re: How to default? (was Unary dot)

2002-04-13 Thread Allison Randal

On Fri, Apr 12, 2002 at 05:34:13PM -0700, Glenn Linderman wrote:
 Allison Randal wrote:
   In a message dated Fri, 12 Apr 2002, Glenn Linderman writes:
$_ becomes lexical
 
  Sound logic. And it almost did go that way. But subs that access the
  current $_ directly are far too common, and far to useful.
 
 One thing I'm missing is how those common useful subs that access the
 current $_ directly will be affected by $_ becoming lexical...
 
 Or perhaps $_ stays global, but gets automatically restored at the end
 of blocks in which it is changed, so that it appears lexical in value,
 even though it is global in the name space ???
 
No, it is truly lexical. Absolutely, positively. 

And you're right that this should present a problem. The lexical scope
of a subroutine is the lexical scope where it was defined, not the
lexical scope where it was evaluated. So, typical subs can only access
global external variables, while closures and lexical subs access
external variables from the scope in which they were defined. 

I suspect I've imperfectly represented the original idea, but I'll
proceed as devil's advocate, for the sake of discussion...

What if $_ were dynamically scoped, but only for subroutines? Dynamic
scoping is not necessarily the same thing as a global $_. It would
merely pretend (only for $_) that the subroutine had been defined in the
scope where it was evaluated. But that could get you into trouble with
recursion. So then you would want some way to explicitly either turn on,
or turn off, dynamic scoping for a specific subroutine. The Cis given
(or Cis topic) property would be an obvious way to turn it off (since
it would create a $_ scoped to the subroutine). But, what if you wanted
it off by default? It could be turned on either as a characteristic of
the sub as a whole, or as a characteristic of an individual parameter:

sub foo is dynamic_topic {
...
}

sub foo ($bar is topic_preserving, $baz) {
...
}

The property Cis topic_preserving would be both binding the value of
the $_ in the calling scope to $bar and making $bar the current topic in
the scope of the sub.

The subroutine property would be basically the same, but wouldn't give
you a named variable, and also wouldn't require you to include an extra
parameter (which could be nice).

Allison



Re: How to default? (was Unary dot)

2002-04-13 Thread Glenn Linderman

Allison Randal wrote:

 What if $_ were dynamically scoped, but only for subroutines? Dynamic
 scoping is not necessarily the same thing as a global $_. It would
 merely pretend (only for $_) that the subroutine had been defined in the
 scope where it was evaluated. But that could get you into trouble with
 recursion. So then you would want some way to explicitly either turn on,
 or turn off, dynamic scoping for a specific subroutine. The Cis given
 (or Cis topic) property would be an obvious way to turn it off (since
 it would create a $_ scoped to the subroutine). But, what if you wanted
 it off by default? It could be turned on either as a characteristic of
 the sub as a whole, or as a characteristic of an individual parameter:
 
 sub foo is dynamic_topic {
 ...
 }
 
 sub foo ($bar is topic_preserving, $baz) {
 ...
 }
 
 The property Cis topic_preserving would be both binding the value of
 the $_ in the calling scope to $bar and making $bar the current topic in
 the scope of the sub.
 
 The subroutine property would be basically the same, but wouldn't give
 you a named variable, and also wouldn't require you to include an extra
 parameter (which could be nice).

OK, I can see how all these things could work.  Off hand, it seems like
defaulting to is dynamic_topic would make more of those common useful
$_-dependent subroutines work without change, but I guess if the perl 5
to 6 translator can detect use of $_ before definition of $_ within a
sub accurately, that it could provide the appropriate annotation during
conversion.  And personally, I haven't written subs that assume dynamic
$_ usage (I think), so I'm not too concerned about which way the default
goes.  I'm not a real heavy user of $_ for everything, as some people
seem to be.  It's useful at times, but can also be confusing at times.

Regarding is topic_preserving: I assume that it would not have to be the
first parameter; it would generally be more useful as the last, I
expect, as in split, or the first optional parameter.  Of course, there
are cases where first and last are the same, or the other parameters can
also be usefully defaulted when the first one is, etc.

There'd be an interaction between is topic_preserving, default parameter
values, and explicit parameter values which should be clarified.  Now I
understand why someone suggested using  //= $_  instead of is
topic_preserving, somewhere along the line.  Clearly if the user
supplies the parameter, is topic_preserving would limit itself to making
that parameter available as $_ within the sub.  If the user supplied
both  //= 3  and  is topic_preserving, that would either be a bug or a
feature.  I guess as a feature, it would use $_, but if $_ were undef,
then it would use 3 ???

-- 
Glenn
=
Remember, 84.3% of all statistics are made up on the spot.



Re: How to default? (was Unary dot)

2002-04-13 Thread Luke Palmer

 There'd be an interaction between is topic_preserving, default parameter
 values, and explicit parameter values which should be clarified.  Now I
 understand why someone suggested using  //= $_  instead of is
 topic_preserving, somewhere along the line.  Clearly if the user
 supplies the parameter, is topic_preserving would limit itself to making
 that parameter available as $_ within the sub.  If the user supplied
 both  //= 3  and  is topic_preserving, that would either be a bug or a
 feature.  I guess as a feature, it would use $_, but if $_ were undef,
 then it would use 3 ???

Personally, I like //= $_. It's clear, such that a reader would 
immediately know what it's doing. topic_preserving, despite being more 
verbose, is not so clear. Plus, if someone didn't know about that feature, 
that's probably the first thing they would do (provided they knew about 
defaults) to accomplish that task.

Luke




Re: How to default? (was Unary dot)

2002-04-13 Thread Allison Randal

On Sat, Apr 13, 2002 at 08:53:41AM -0700, Glenn Linderman wrote:
 
 Off hand, it seems like defaulting to is dynamic_topic would make
 more of those common useful $_-dependent subroutines work without
 change, but I guess if the perl 5 to 6 translator can detect use of $_
 before definition of $_ within a sub accurately, that it could provide
 the appropriate annotation during conversion.  
 ...

I agree dynamic scoping of $_ in subroutines by default would make for
an easier transition between 5 and 6. And at first I preferred it. 
But I'm gradually leaning in the opposite direction. The lexical scoping
of $_ encourages encapsulation (good coding practice), and minimizes
unexpected side effects.

 I'm not a real heavy user of $_ for everything, as some people seem to
 be. It's useful at times, but can also be confusing at times.

I think the two most confusing aspects of $_ in 5 are the fact that it
isn't created consistently (only when there isn't a named alias) and how
easy it is to accidentally clobber it. Both of which should be
eliminated in 6. :)

 Regarding is topic_preserving: I assume that it would not have to be
 the first parameter; it would generally be more useful as the last, I
 expect, as in split, or the first optional parameter.  Of course,
 there are cases where first and last are the same, or the other
 parameters can also be usefully defaulted when the first one is, etc.

Yeah, any of the properties or //= should work on any parameter in the
list.

 There'd be an interaction between is topic_preserving, default parameter
 values, and explicit parameter values which should be clarified.  Now I
 understand why someone suggested using  //= $_  instead of is
 topic_preserving, somewhere along the line. 

Well, topic_preserving wasn't intended as a defaulting mechanism, just
as a way of keeping the value of $_ across subroutines, even though it's
lexically scoped. That's why I prefer the subroutine property, it makes
it clearer that we're fundamentally altering the behaviour of
subroutines, instead of making it look like we're just monkeying around
with the parameters.

For defaulting to the current topic, I'd probaly choose a property name
topic_default instead. 

Possibly it would be helpful to be explicit about the options we're
discussing:

sub foo ($bar //= $_, ...

The parameter can be passed a value, but it will default to the outer $_
if not passed a value. It will not set the value of $bar as topic within
the subroutine, so the inner $_ will be undefined (unless there was a
global $_ defined, which would produce really anti-dwim behaviour). One
thing to consider here is that we're already abusing the $_ is lexical
concept to make the $_ of the calling scope accessible as a value for
the parameter. 

If you wanted to also make $bar the topic within the sub, you'd have to
use the property Cis given:

sub foo ($bar //= $_ is given, ...

So, the Cis topic_default property would condense the two behaviours
into one. I would guess that if you've defaulted to $_ you would expect
it to also be $_ within the sub anyway.

sub foo ($bar is topic_default, ...

It also makes it clearer that this isn't your ordinary //= default
happening, but a special lexical scope bending one.

The other proposed property, Cis topic_preserving, wouldn't accept a
value passed in, it would only and always be the $_ of the calling
scope, and make it the topic within the subroutine scope.

sub foo ($bar is topic_preserving, ...

Okay, looking at the details laid out like this, I would probably ditch
the topic_preserving property in favor of topic_default.

But topic_default isn't going to give us perl 5 behaviour. Neither
would topic_preserving, because both alter the parameter structure of
the sub.

So, my favorite final solution: Use the subroutine property
dynamic_topic for perl 5 behaviour, topic_default to create Cprint
type subs.

 If the user supplied both //= 3 and  is topic_preserving, that would
 either be a bug or a feature. I guess as a feature, it would use $_,
 but if $_ were undef, then it would use 3 ???

I'd say a bug. I don't know, can you:

sub foo ($bar //= $some_value //= 3, ...

(Presuming that $some_value is a true global or otherwise accessible in
the scope where the sub was defined.)

If you can do that, then it should probably work the same for $_
defaulting.

Allison



Re: How to default? (was Unary dot)

2002-04-12 Thread Piers Cawley

Trey Harris [EMAIL PROTECTED] writes:

 I think I've missed something, even after poring over the archives for
 some hours looking for the answer.  How does one write defaulting
 subroutines a la builtins like print() and chomp()? Assume the code:

   for  {
  printRec;
   }
   printRec Done!;

   sub printRec {
  chomp;
  print :$_:\n;
   }

You could take advantage of subroutine signatures and multi-dispatch

sub printRec() { printRec($_) } # No args, therefore no new topic.
sub printRec($rec) { .chomp; print :$rec:\n } # 1 arg

Assuming we *get* multidispatch that is. It would be nice to hope that
the compiler could optimize that...

-- 
Piers

   It is a truth universally acknowledged that a language in
possession of a rich syntax must be in need of a rewrite.
 -- Jane Austen?




Re: How to default? (was Unary dot)

2002-04-12 Thread Aaron Sherman

On Fri, 2002-04-12 at 04:26, Piers Cawley wrote:
 Trey Harris [EMAIL PROTECTED] writes:
 
  I think I've missed something, even after poring over the archives for
  some hours looking for the answer.  How does one write defaulting
  subroutines a la builtins like print() and chomp()? Assume the code:
 
for  {
   printRec;
}
printRec Done!;
 
sub printRec {
   chomp;
   print :$_:\n;
}
 
 You could take advantage of subroutine signatures and multi-dispatch
 
 sub printRec() { printRec($_) } # No args, therefore no new topic.
 sub printRec($rec) { .chomp; print :$rec:\n } # 1 arg

I think was he was saying is that your first printRec would not have a
$_ available to it (lexically scoped, as I understand it).

You've got a problem here, which I don't think there's a mechanism for.
Perhaps

sub printRec(-$rec)

I'm just throwing that out, but some way to say that the argument
defaults to getting the topic would seem to be called for.





Re: How to default? (was Unary dot)

2002-04-12 Thread Jonathan Scott Duff

On Fri, Apr 12, 2002 at 09:40:16AM -0400, Aaron Sherman wrote:
 On Fri, 2002-04-12 at 04:26, Piers Cawley wrote:
  Trey Harris [EMAIL PROTECTED] writes:
  
   I think I've missed something, even after poring over the archives for
   some hours looking for the answer.  How does one write defaulting
   subroutines a la builtins like print() and chomp()? Assume the code:
  
 for  {
printRec;
 }
 printRec Done!;
  
 sub printRec {
chomp;
print :$_:\n;
 }
  
  You could take advantage of subroutine signatures and multi-dispatch
  
  sub printRec() { printRec($_) } # No args, therefore no new topic.
  sub printRec($rec) { .chomp; print :$rec:\n } # 1 arg
 
 I think was he was saying is that your first printRec would not have a
 $_ available to it (lexically scoped, as I understand it).
 
 You've got a problem here, which I don't think there's a mechanism for.

If $_ is lexical by default (did larry say this somewhere?), then I'm
sure we can make it dynamic on request ala:

for $_ is temp  {
   printRec;
}

I may have the syntax slightly borked but you get the idea.

I read the original posters message the same as Piers though.

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]



Re: How to default? (was Unary dot)

2002-04-12 Thread Graham Barr

On Fri, Apr 12, 2002 at 09:26:45AM +0100, Piers Cawley wrote:
 Trey Harris [EMAIL PROTECTED] writes:
 
  I think I've missed something, even after poring over the archives for
  some hours looking for the answer.  How does one write defaulting
  subroutines a la builtins like print() and chomp()? Assume the code:
 
for  {
   printRec;
}
printRec Done!;
 
sub printRec {
   chomp;
   print :$_:\n;
}
 
 You could take advantage of subroutine signatures and multi-dispatch
 
 sub printRec() { printRec($_) } # No args, therefore no new topic.
 sub printRec($rec) { .chomp; print :$rec:\n } # 1 arg

Hm, I wonder if

  sub printRec($rec=$_) { ... }

or someother way to specify that the current topic be used
as a default argument, might be possible

Graham.



Re: How to default? (was Unary dot)

2002-04-12 Thread Aaron Sherman

On Fri, 2002-04-12 at 09:52, Jonathan Scott Duff wrote:
 On Fri, Apr 12, 2002 at 09:40:16AM -0400, Aaron Sherman wrote:

   sub printRec() { printRec($_) } # No args, therefore no new topic.
   sub printRec($rec) { .chomp; print :$rec:\n } # 1 arg
  
  I think was he was saying is that your first printRec would not have a
  $_ available to it (lexically scoped, as I understand it).
  
  You've got a problem here, which I don't think there's a mechanism for.
 
 If $_ is lexical by default (did larry say this somewhere?), then I'm
 sure we can make it dynamic on request ala:

Nope, I don't think that works. If the caller of printRec has to do
something special, we're meeting the original request which is to be
able to write print, which scoops up $_ without any special case code.

Now, we can say, you just can't ever write print. I can understand why
we would, but why NOT just allow the subroutine author to indicate that
the subroutine acquires the current topic as a parameter default? It
would seem nice and clean. Either

foo($a=$_){}

as Graham suggests, or

foo(-$a){}

which was mine. Either one works. I guess with the aliasing of $_,
Graham's seems cleaner to me.

Of course, the other conversation pending, we might end up with:

foo($a//=$_){}

which doesn't do the same thing as print, but may be the best we can do
with the syntax we have.

 I read the original posters message the same as Piers though.

Ok, what did you get from it that's different?





Re: How to default? (was Unary dot)

2002-04-12 Thread Ashley Winters

- Original Message - 
From: Graham Barr [EMAIL PROTECTED]
 Hm, I wonder if
 
   sub printRec($rec=$_) { ... }
 
 or someother way to specify that the current topic be used
 as a default argument, might be possible

Would it would be reasonable to have given default to the caller's topic?

sub printRec {
given {
# $_ is now the caller's topic in this scope
}
}

Perhaps Cgiven caller.topic {} would work as well.

Ashley Winters




Re: How to default? (was Unary dot)

2002-04-12 Thread Trey Harris

In a message dated Fri, 12 Apr 2002, Ashley Winters writes:
 Would it would be reasonable to have given default to the caller's topic?

 sub printRec {
 given {
 # $_ is now the caller's topic in this scope
 }
 }

 Perhaps Cgiven caller.topic {} would work as well.

Yes, something like that would be nice.  Of course, you could say, Cgiven
caller.MY{'$_'}, but I think there's two separate things going on here:

1) There should probably be something in the syntax to allow for
   retopicalization of the up-scope topic

2) It may be useful to have some way to allow single-parameter blocks to
   take the up-scope topic as a first parameter.

Trey




Re: How to default? (was Unary dot)

2002-04-12 Thread Luke Palmer

On Fri, 12 Apr 2002, Trey Harris wrote:

 I think I've missed something, even after poring over the archives for
 some hours looking for the answer.  How does one write defaulting
 subroutines a la builtins like print() and chomp()? Assume the code:
 
   for  {
  printRec;
   }
   printRec Done!;
 
   sub printRec {
  chomp;
  print :$_:\n;
   }
 
 Assuming the input file 1\n2\n3\n, I want to end up with:
 
 :1:
 :2:
 :3:
 :Done!:
 
 I assume I'm missing something in the sub printRec { line.  But what?
 (I also assume, perhaps incorrectly, that I won't have to resort to
 anything so crass as checking whether my first parameter is defined...)


Couldn't you do it with old-style Perl5 subs?

sub printRec {
  my $p = chomp(shift // $_);
  print :$_:\n
}

Or am _I_ missing something?

Luke




Re: How to default? (was Unary dot)

2002-04-12 Thread Trey Harris

In a message dated Fri, 12 Apr 2002, Luke Palmer writes:
 Couldn't you do it with old-style Perl5 subs?

 sub printRec {
   my $p = chomp(shift // $_);
   print :$_:\n
 }

 Or am _I_ missing something?

That definitely won't work (aside from the $p/$_ swap which I assume is
unintentional), because $_ is now lexical.  If my understanding is correct
and $_ is always the topic, and the first parameter of any block is always
the topic, that would make your code somewhat equivalent to:

  sub printRec {
my $p;
if (defined _[0]) {
  $p = shift;
} else {
  $p = _[0];
}
print :$p:\n;
  }


Or is the topic of a block mutable (i.e., will a shift cause the topic to
shift as well)?  If so, I guess your code is actually is equivalent to:

  sub printRec {
my $p = chomp(shift // shift);
print :$p:\n;
  }

Either way, bizarre, no?  What I *think* you meant to say is:

  sub printRec {
my $p = chomp(shift // caller.MY{'$_'});
print :$p:\n
  }

which should certainly work, it just makes my skin crawl--vestiges of
Perl 4 still coming to bite us, or something.

Trey




Re: How to default? (was Unary dot)

2002-04-12 Thread Trey Harris

Oops, caught my own mistake...

In a message dated Fri, 12 Apr 2002, Trey Harris writes:
 In a message dated Fri, 12 Apr 2002, Luke Palmer writes:
  sub printRec {
my $p = chomp(shift // $_);
print :$_:\n
  }

[Should be equivalent to]

   sub printRec {
 my $p = chomp(shift // shift);
 print :$p:\n;
   }

Actually, it should be equivalent to

  sub printRec {
my $p = chomp(shift // _[0]);
print :$p:\n;
  }

No shifting is happening just by referring to $_.

Because $_ is always the topic, which is always the first parameter to a
block, which in subroutines is _[0], right?  So in a sub, $_ == _[0].
The only question I have is if you modify _ with a shift, does $_
continue to point at the old _[0], or does it now point at the new _[0],
the original _[1]?

Trey




Re: How to default? (was Unary dot)

2002-04-12 Thread Trey Harris

In a message dated Fri, 12 Apr 2002, Glenn Linderman writes:
 $_ becomes lexical
 $_ gets aliased to the first topic of a given clause (hence changes
 value more often, but the lexical scoping helps reduce that impact)

Okay.  But it sounds like you're saying that Cgiven, and Cgiven only,
introduces a topic, and that can't be right.  From Ex4:

This is a fundamental change from Perl 5, where $_ was only aliased to
the current topic in a for loop. In Perl 6, the current topic -- whatever
its name and however you make it the topic -- is always aliased to $_.

And later:

In a Perl 6 method, the invocant (i.e. the first argument of the method,
which is a reference to the object on which the method was invoked) is
always the topic

And obviously a CCATCH block introduces a topic (though I guess we
can pretend that CCATCH is a special kind of Cgiven).

So I had (wrongly, I guess?) extended this logic to: all blocks taking
parameters introduce a topic, which is the first parameter.  Which made
me think that Csub blocks, too, introduce a topic, which would be
equivalent to _[0].

So where did I go wrong?

Trey





Re: How to default? (was Unary dot)

2002-04-12 Thread Allison Randal

On Fri, Apr 12, 2002 at 02:44:38AM -0400, Trey Harris wrote:
 I think I've missed something, even after poring over the archives for
 some hours looking for the answer.  How does one write defaulting
 subroutines a la builtins like print() and chomp()? Assume the code:
 
   for  {
  printRec;
   }
   printRec Done!;
 
   sub printRec {
  chomp;
  print :$_:\n;
   }
 
 Assuming the input file 1\n2\n3\n, I want to end up with:
 
 :1:
 :2:
 :3:
 :Done!:
 
 I assume I'm missing something in the sub printRec { line.  But what?
 (I also assume, perhaps incorrectly, that I won't have to resort to
 anything so crass as checking whether my first parameter is defined...)

The first call to printRec, where you simply want to use the same $_
works without changes. Larry decided that ordinary subs don't
topicalize, partly for this very reason.

But you will be able to tell your subs to topicalize, using a property.
It hasn't been decided yet if this property will be is topic or
is given, probably the latter.

sub printRec ($msg is given) {
...
}

So for the second call to printRec, you could do something like:

sub printRec ($msg //= $_ is given) {
...
}

Which would allow you to default to the outer $_ and make the first
argument the topic. It's kind of ugly, though, and wouldn't deal with
subsequent parameters in quite the way you would want. I much prefer
handling the problem with overloading:

sub printRec {
chomp;
print :$_:\n;
}

sub printRec ($msg is given) {
printRec;
}

Allison



Re: How to default? (was Unary dot)

2002-04-12 Thread Allison Randal

Okay, first thing to keep in mind, this hasn't been finally-finalized
yet. Alot was hashed out in the process of proofing E4, but there will
be more to come.

On Fri, Apr 12, 2002 at 07:39:17PM -0400, Trey Harris wrote:
 In a message dated Fri, 12 Apr 2002, Glenn Linderman writes:
  $_ becomes lexical
  $_ gets aliased to the first topic of a given clause (hence changes
  value more often, but the lexical scoping helps reduce that impact)
 
 Okay.  But it sounds like you're saying that Cgiven, and Cgiven only,
 introduces a topic, and that can't be right.  From Ex4:
 
You are correct, Cgiven is not the only topicalizer. Cfor is too,
and -, etc...

 This is a fundamental change from Perl 5, where $_ was only aliased to
 the current topic in a for loop. In Perl 6, the current topic -- whatever
 its name and however you make it the topic -- is always aliased to $_.

You could really say topic is just another name for $_.

 In a Perl 6 method, the invocant (i.e. the first argument of the method,
 which is a reference to the object on which the method was invoked) is
 always the topic

Emphasis on method.

 And obviously a CCATCH block introduces a topic (though I guess we
 can pretend that CCATCH is a special kind of Cgiven).
 
Yes.

 So I had (wrongly, I guess?) extended this logic to: all blocks taking
 parameters introduce a topic, which is the first parameter.  Which made
 me think that Csub blocks, too, introduce a topic, which would be
 equivalent to _[0].

Sound logic. And it almost did go that way. But subs that access the
current $_ directly are far too common, and far to useful.

(Drat! Now I have to leave for several hours, just when it's getting
interesting...)

Allison



Re: How to default? (was Unary dot)

2002-04-12 Thread Glenn Linderman

Allison Randal wrote:
  In a message dated Fri, 12 Apr 2002, Glenn Linderman writes:
   $_ becomes lexical

 Sound logic. And it almost did go that way. But subs that access the
 current $_ directly are far too common, and far to useful.

One thing I'm missing is how those common useful subs that access the
current $_ directly will be affected by $_ becoming lexical...

Or perhaps $_ stays global, but gets automatically restored at the end
of blocks in which it is changed, so that it appears lexical in value,
even though it is global in the name space ???

Guess I haven't got all the Apocalypses memorized :)

-- 
Glenn
=
Remember, 84.3% of all statistics are made up on the spot.