Re: state and = vs :=

2014-10-02 Thread Jonathan Worthington

On 10/2/2014 16:03, Elizabeth Mattijsen wrote:

On 01 Oct 2014, at 07:48, Father Chrysostomos  wrote:

Does ‘state’ govern ‘:=’ the way it governs ‘=’?  In other words, just as this:

state $x = 1;

only assigns to $x once (per closure), does the same apply to this?

state $x := $y;

I can’t find anything in the specs that implies that it does.

The reason I ask is that I am currently implementing binding for Perl 5, but 
the syntax is different—

\$x = \$y;

(The reason for the different syntax is that, when we tried to use :=, we could 
not find a coherent way to handle edge cases [e.g., flattening vs not 
flattening].  Reusing existing Perl 5 syntax seemed the most straightforward 
and intuitive approach.)

—and I am debating whether \state $x = \$y should bind only once or every time 
the surrounding code is executed.  I could argue it either way (though I am 
leaning toward the latter), so I thought to find out what Perl 6 does.

It would seem that binding state variables will be something that will be 
prohibited in Perl 6, until such time we find a good use case for it.


[15:55:36] well, all of this was because of a question of 
Father Chrysostomos (a very productive p5p contributor) on p6l
[15:57:01]  OK. Well, I'll leave it at, I'm happy enough with 
the current semantics, so unless TimToady++ feels they have to chnage, then I'm not 
inclined to do much about the status quo.
[15:57:44]  (Where by "the current semantics" I mean, what Moar 
does, and I'm about certain what we do on JVM. I don't actually know how things are on Parrot.)
[15:57:59] eh, but the current semantics silently do the wrong 
thing, no ?
[15:59:11]  lizmat: Depends how you define the semantics of 
state.
[15:59:44]  lizmat: Note that if you go binding a temp or let 
var you are in equal trouble.
[16:00:03] moritzwouldn't mind compile-time disallowing rebinding 
temp/let/state vars
[16:00:05]  'cus those are certainly about value, not container
[16:00:14]moritz +1
[16:00:18]  I took state to be wanting the same semantics
[16:00:31]  Yeah, I could go with a conservative approach of "just 
disallow it"
[16:00:53] I'll answer FC

To expand a little, all of state/temp/let are implemented under the 
assumption that you'll be doing assignment to the container you applied 
them to. That is, when I:


temp $x;

Then I'm really saying "stash away a pair (the-cont = $x, current-value 
= the value in $x), and at block LEAVE time then do the-cont = 
old-value". It's the same container throughout, and if you re-bind $x 
then temp has no clue about it. For state, containers are created at 
first entry to a given closure clone, stashed away in the closure's code 
object, and those same containers are used in the frames (specifically, 
lexical storage) of future invocations of the same closure.


Generally in Perl 6, binding is a quite low-level operation. An operation:

$x := $y;

Might be JITted to just a couple of instructions (perhaps even if $x has 
a static type constraint that needs checking, since type specialization 
might prove the check isn't needed). Binding can be understood as 
directly replacing the contents of a slot (that is, just setting a 
pointer), and has no effect on any container that used to be there. 
Since state is implemented by keeping another reference to the container 
in the closure's code object, re-binding a state variable in a call 
frame will have no effect beyond the lifetime of that frame:


> sub foo() { state $x = 42; say $x++; $x := 99; say $x; }; foo() 
for ^5

42
99
43
99
44
99
45
99
46
99

It's also worth noting that:

state $x = 42;

And a later:

$x = 42;

Are parsed rather differently. The same goes for := and ::=. The former 
kind of construct is parsed as a declarator with an initializer; the 
latter is parsed as the familiar infix operators. Curiously, since we 
figure out what to do by declarator scope (so a different code-path for 
state than my), it turns out that := and ::= initializers on a state var 
are completely ignored at present.


I suspect instead of ignoring them, we'll go down to line of giving an 
error on:


state $x := something;

...because it's hard to imagine it being anything except programmer 
error. That is, unless Larry comes along and declares that state should 
have got "save what's in the lexpad back to the per-closure storage at 
scope exit" semantics, in which case it would do something arguably 
useful...and increase the cost of state vars, frustrate inlining (in a 
perhaps fixable way), and make something once immutable become 
mutable...you might imagine I'm hoping we don't go this way. :-)


But to answer the original question, if we *do* end up doing something 
that runs code in a "state $x := ..." rather than complain about it, 
then it will surely be once per closure clone, not every time,

Re: state and = vs :=

2014-10-02 Thread Elizabeth Mattijsen
On 01 Oct 2014, at 07:48, Father Chrysostomos  wrote:
> Does ‘state’ govern ‘:=’ the way it governs ‘=’?  In other words, just as 
> this:
> 
>state $x = 1;
> 
> only assigns to $x once (per closure), does the same apply to this?
> 
>state $x := $y;
> 
> I can’t find anything in the specs that implies that it does.
> 
> The reason I ask is that I am currently implementing binding for Perl 5, but 
> the syntax is different—
> 
>\$x = \$y;
> 
> (The reason for the different syntax is that, when we tried to use :=, we 
> could not find a coherent way to handle edge cases [e.g., flattening vs not 
> flattening].  Reusing existing Perl 5 syntax seemed the most straightforward 
> and intuitive approach.)
> 
> —and I am debating whether \state $x = \$y should bind only once or every 
> time the surrounding code is executed.  I could argue it either way (though I 
> am leaning toward the latter), so I thought to find out what Perl 6 does.

It would seem that binding state variables will be something that will be 
prohibited in Perl 6, until such time we find a good use case for it.


[15:55:36]   well, all of this was because of a question of Father 
Chrysostomos (a very productive p5p contributor) on p6l
[15:57:01]OK. Well, I'll leave it at, I'm happy enough with the 
current semantics, so unless TimToady++ feels they have to chnage, then I'm not 
inclined to do much about the status quo.
[15:57:44](Where by "the current semantics" I mean, what Moar 
does, and I'm about certain what we do on JVM. I don't actually know how things 
are on Parrot.)
[15:57:59]   eh, but the current semantics silently do the wrong 
thing, no ?
[15:59:11]lizmat: Depends how you define the semantics of state.
[15:59:44]lizmat: Note that if you go binding a temp or let var 
you are in equal trouble.
[16:00:03] moritzwouldn't mind compile-time disallowing rebinding 
temp/let/state vars
[16:00:05]'cus those are certainly about value, not container
[16:00:14]  moritz +1
[16:00:18]I took state to be wanting the same semantics
[16:00:31]Yeah, I could go with a conservative approach of "just 
disallow it"
[16:00:53]   I'll answer FC


Hope this answer your question,


Liz