Re: something between state and my

2006-02-03 Thread Larry Wall
On Fri, Feb 03, 2006 at 06:45:23AM +, Luke Palmer wrote:
: On 2/3/06, Dave Whipp [EMAIL PROTECTED] wrote:
: sub factorial(Int $x) {
: temp state Int $result = 1;
: $result *= $x;
: factorial $x-1 if $x  2;
: return $result if want;
: }
: say factorial 6;
: 
: That's precisely what env variables are for.  The right way:
: 
: sub factorial(Int $x) {
: env $result = 1;
: my sub fact(Int $x) {
: $+result *= $x;
: fact($x - 1) if $x  2;
: return $result;
: }
: fact($x);
: }
: 
: Of course, you can view env variables as implicit parameters.  Given
: that, this function might be able to reduce to:
: 
: sub factorial(Int $x) {
: env $+result = 1;   # expecting $+result
: # param, default to 1
: $+result *= $x;
: fact($x - 1) if $x  2;
: return $result;
: }

Hmm, that won't work in my current mental model, where an env is
used only in the outermost dynamic scope to declare the existence of
that outermost scope, and within that scope it behaves exactly like a
my variable.  But that means that the assignment happens every time,
not as some kind of default.

If you don't have an outermost scope declarator, you've just basically
reinvented a less efficient version of globals and temp, since env
$+result would always have to assume there was an outer dynamic scope
and scan outward to the root dynamic scope.

But that's just my current mental model, which history has shown
is subject to random tweakage.  And maybe env $+result could be a
special squinting construct that does create-unless-already-created.
Doesn't feel terribly clean to me though.  If we stick with the +
twigil always meaning at least one CALLER::, then clarity might be
better served by

env $result := $+result // 1;

assuming that $+result merely returns undef in the outermost env context.

Larry


Re: something between state and my

2006-02-03 Thread Dave Whipp

Larry Wall wrote:


But that's just my current mental model, which history has shown
is subject to random tweakage.  And maybe env $+result could be a
special squinting construct that does create-unless-already-created.
Doesn't feel terribly clean to me though.  If we stick with the +
twigil always meaning at least one CALLER::, then clarity might be
better served by

env $result := $+result // 1;

assuming that $+result merely returns undef in the outermost env context.


Wouldn't that bind $result to a constant at the outermost scope -- and 
therefore to that same constant in all inner scopes? If so, then later 
attempts to assign $result would be an error.


Re: something between state and my

2006-02-03 Thread Larry Wall
On Fri, Feb 03, 2006 at 12:41:47PM -0800, Dave Whipp wrote:
: Larry Wall wrote:
: 
: But that's just my current mental model, which history has shown
: is subject to random tweakage.  And maybe env $+result could be a
: special squinting construct that does create-unless-already-created.
: Doesn't feel terribly clean to me though.  If we stick with the +
: twigil always meaning at least one CALLER::, then clarity might be
: better served by
: 
: env $result := $+result // 1;
: 
: assuming that $+result merely returns undef in the outermost env context.
: 
: Wouldn't that bind $result to a constant at the outermost scope -- and 
: therefore to that same constant in all inner scopes? If so, then later 
: attempts to assign $result would be an error.

Hmm, well, it wouldn't work anyway since env variables are readonly
by default outside their my scope.  I ought to at least have said

env $result is rw := $+result // 1;

As for

my $answer := 42;

I would hope that binding a constant to a rw location is smart enough
to make an anonymous rw copy (or COW).  I think that's what most
existing Perl programmers would expect.  I'm sure a C++ programmer would
argue it the other way though.

But whichever way that goes, certainly if you want to make $answer
a constant, the current design encourages you to do it explicitly with

constant $answer = $mumble;

rather than as an accidental side effect of binding a value that just
happens to be a constant.  And I think a good argument can be made that

my $foo := some text;

is a great way of sharing some text among all default instances of $foo,
whereas

my $foo = some text;

would be required to force a copy, at least in the abstract.
Of course, the existence of a COW string implementation can be taken
as an argument either way.  It really kind of depends on whether you
see some text as an object or as primitive data that autoboxes when
a container reference is requested.

Larry


Re: something between state and my

2006-02-02 Thread Luke Palmer
On 2/3/06, Dave Whipp [EMAIL PROTECTED] wrote:
sub factorial(Int $x) {
temp state Int $result = 1;
$result *= $x;
factorial $x-1 if $x  2;
return $result if want;
}
say factorial 6;

That's precisely what env variables are for.  The right way:

sub factorial(Int $x) {
env $result = 1;
my sub fact(Int $x) {
$+result *= $x;
fact($x - 1) if $x  2;
return $result;
}
fact($x);
}

Of course, you can view env variables as implicit parameters.  Given
that, this function might be able to reduce to:

sub factorial(Int $x) {
env $+result = 1;   # expecting $+result
# param, default to 1
$+result *= $x;
fact($x - 1) if $x  2;
return $result;
}

Luke