Let me start by saying that I understand that what I'm asking about in the title is dubious practice (as explained here), but my lack of understanding concerns the syntax involved.
When I first tried to bind a scalar to a sigilless symbol, I did this:
my \a = $(3);
thinking that $(...)
would package the Int 3 in a Scalar (as seemingly suggested in the documentation), which would then be bound to symbol a. This doesn't seem to work though: the Scalar is nowhere to be found (a.VAR.WHAT
returns (Int), not (Scalar)).
In the above-referenced post, raiph mentions that the desired binding can be performed using a different syntax:
my \a = $ = 3;
which works. Given the result, I suspect that the statement can be phrased equivalently, though less concisely, as: my \a = (my $ = 3)
, which I could then understand.
That leaves the question: why does the attempt with $(...)
not work, and what does it do instead?
What
$(…)
does is turn a value into anitem
.(A value in a scalar variable (
$a
) also gets marked as being an item)Basically it is there to prevent a value from flattening. The reason for its existence is that Perl 6 does not flatten lists as much as most other languages, and sometimes you need a little more control over flattening.
The following only sort-of does what you want it to do
A bare
$
is an anonymousstate
variable.The problem shows up when you run that same bit of code more than once.
Note that variable is shared between calls.
The first Promise halts at the
sleep
call, and then the second sets the state variable before the first runs++a
.If you use
my $
instead, it now works properly.The thing is that sigiless “variables” aren't really variables (they don't vary), they are more akin to lexically scoped (non)constants.
Basically the whole point of them is to be as close as possible to referring to the value you assign to it. (Static Single Assignment)
Note that above I wrote the following:
Normally in the declaration of a state var, the assignment only happens the first time the code gets run. Bare
$
doesn't have a declaration as such, so I had to prevent that behaviour by putting the declaration in parens.