here is ( a liitle bit ) poished version of
http://archive.develooper.com/perl6-language%40perl.org/msg12393.html
just if somebody want to use it .
I left some of the comments by Damian Conway because when I tryed to (
thought of ) saying it myself , it lost clarity/brevity/intensity .
But some comments by him I did incorporated in the text.
What I have in mind is to have some (informal & clear & simple & not
too vague & selfcontained ) introduction to the general structure (
which is beautiful ) of the language . I am not sure I fit the role
.. But I would be happy to participate in the effort .
anyway :
=section Variable : Name -> Container -> Value
=head1 short intro to compile/run phase
perl execution of you program may be roughly divided in two phases :
=over
=item *
compile phase . everything happening at that time is said to
happen at compile-time. At this phase perl read the perl source,
parse it, and evntually output Parrot assembly , which is the
"mashine language" of perl.
=item *
run phase. at that stage the programm is actually executed
at run phase parrot code is
executed by parrot virtual mashine ( which "physically" may be
almost everything -- from mailing the bytecode to your friend
to ... just executing it ).
=back
from the point of view of perl programmer all actions are taken by
perl either at comile-time or at run-time . And all entities are
sprung to existence / living / destroyed either at compile time or at
run time ( or both ) .
=head1 what is variable
perl as any other language manipulate data through "variables". since
perl have very rich semantic structure it is best to keep some picture
of its structure.
in perl, "variable" embrace 3 *mostly* independent concepts
=over
=item 1)
variable-name . live "symbol-tables", also known as in
namespaces.
=item 2)
actually "variables" or *containers* . live in perl parser
memory at compile-time-phase. But may persist to run-time.
=item 3)
values . live everywhere .
=back
So , perl Variable can be viewed as the following 3 - level thing
my $a = 5 ;
1) name | '$a'
| |
| V
2) container | (.)
| |
| V
3) value | some number e.g., 5
=over Variable names
dc> Though, in Perl, those restrictions aren't terribly
dc> restrictive. Here, for example, is a variable whose name is
dc> (phonetically):
dc>
dc> NEWLINE-NEWLINE-ALLO-ALLO-SPACE-the-SPACE-sky-SPACE-is-TAB-falling-BANG-BANG-BANG
dc>
dc> and yet it is perfectly legal in Perl:
dc>
dc> *{'
dc>
dc> �� the sky is falling!!!'} = \[0]->[0];
dc> while (${'
dc>
dc> �� the sky is falling!!!'}<10) {
dc> print ${'
dc>
dc> �� the sky is falling!!!'}, "\n";
dc> ${'
dc>
dc> �� the sky is falling!!!'}++;
dc> }
Variable names
names ( variable-names ) are strings. they may be virtually everything
( see \cite<Variable names> ) although perl may interpret specially
the first character -- the sigil. Names *live* in symbol-tables.
that is, perl keep tables that make a bookkeeping of known symbols
also known as variable-names. each name refer to a container. Perl
have 4 general classes of names differing by the sigil - the first
character. '$thing' , @thing' , '%thing' , &thing' . the type of
symbol-table, (such as: global, package, lexical and so on), defines
the *scope* of variable-name and its life-circle ( but only for
variable-name ). special modifiers "my" or "our" help perl to
understand in which "variable-namespace" you want to place your
variable-name.
=item * Containers
container is mystical ( or may be not so - after reading this )
intermediate between value and variable name.
<DConway>
dc> Mystical? I'd have said that the container is the *least* mystical
dc> part of the symbiosis. It's the only tangible piece of the puzzle.
</DConway>
Its a wheels and sticks inside the clock . we don't see it but it
is necessary to "de-mystify" - how the clock *knows* what time is
it.
Container's life-circle , its life or death question is
controlled by only one RULE: "Be referred by something" : container
is dead as soon as it is not referred by anybody.
In perl variable
may have properties . Actually containers and values have.
=item *Values
value is actual data - the 0's and 1's that actually run here and
there when program runs.
<DConway>
dc> Not quite. The value is the *interpretation* of the 1's and 0's.
dc> For example, the same bitsequence (say 01010101) may be part of
dc> a (very short) string, or an integer, or a floating point number, or a
dc> reference. And no two of those interpretations will necessarily
dc> represent the same "value.
</DConway>
value is always a scalar - some number,
although it may be a reference ( which is also number ) to some more
elaborate structure ( as in perl is almost always the case even for
references themselves as far as I know, but ???) .
So , actually , a perl "variable" is an association of a container
and a name. But container may not be *directly* referenced by
some name , in which case it is anonymous container.
here is some terminology clearing :
=back
=over <glossary>
=item * "variable" -
a variable-name associated with ( referencing )
container.
=item * variable-name -
an entry in the symbol-table that contains a name
- string beginning with *sigil* . otherwize
absolutly arbitrary. one sigil for each class of
containers -- see below.
=item * "container" -
a "box" that may contain some values . Containers may
be "scalar" , "Array" , Hash" , "Pair" and other
???? . containers are inherently anonymous , in the
sence that they dont have name *on their own* . but
the can be *directly* refeferenced by entry in
symbol-table, in which case they are "named" , but
only in the sence that what what is usually called
variable , is ( see above ) association between
variable-name and container. In perl there is one
additional rule . Perl names always begin with
*sigil* . Perl keep track of what happens and makes
sure that if the container is *named* ( that is,
refernced by a entry in symbol-table *directly* ) its
name's sigil correspond to container class. Perl is
doing that by chosing appropriate container if
variable is declared or first used or creating
appropriate container if varible is assigned or
aliased . see below . Usually variable names spring to
existance when declared or first used .
=item * "anonymous variable" -
container not *directly* referenced
by some "variable-name" , so in that sence it
doesnot have name (directly) associated with
it. and to close any gaps -- in that sence any
container is anonymous : name may be associated
with it but does not have to.
=back
<\glossary>
??? probably irrelevant question : is it possible for name *not* to be
associated wit container ? dont know if its important .
dc> All containers are inherently anonymous. In a sense, a variable is
dc> merely the association of a container and a name.
in perl, variable and values may have properties .
*compile time* properties are attached to *containers*
they are introduced by "is" operator ( actually at run time
containers may already be unneeded , they did all the "semantic"
work and the may go ,
but I am not sure ????)
dc> Sometimes they can be optimized away; sometimes not.
*run time properties are attached to values ; they are introduced
with "but" operator ; they begin to function at run-time, but
perl at compiler time may well be aware of them ( ??? ) .
dc> Yes, it may be. If the value is a compile-time value such as:
dc>
dc> return 0 but true;
dc>
dc> then the compiler might well optimize that somehow.
examples :
my $x is constant = 1 ;
our $y = 0 but true ;
* "my" "our" tells where ( and how long and where visible ) the
*variable-name* '$x', '$y' lives.
and this create the following structure :
1) name | '$x' ( lives in MY:: namespace )
| |
| V
2) container | (.)->props->{ "constant"=>1 , ... }
| |
| V
3) value | 1->props->{ ... }
1) name | '$x' ( lives in Main:: namespace )
| |
| V
2) container | (.)->props->{ ... }
| |
| V
3) value | 0->props->{ true=>1 }
( I am not sure about the runtime property ???)
Apocalypsis 3 and Exercise 3
dc> Apotheosis 3 and Excoriation 3?
dc> Apoplexy 3 and Exorcism 3?
dc> Apogee 3 and Escapevelocity 3?
have lots of examples of properties .
variables types , subroutine signatures , lots of other staff is
unified in perl6 under the concept of compile time properties --
everything that is useful for compiler to help keep your program
clear, consistent, and simple.
Above we have seen an example of scalar container -- the (.) thing.
perl have other containers. Array.
Array can be pictured like that .
my @b = ( 1 ,2 , 3 ,4 ,5 ) ;
'@b'
|
|
................|.......................
|
|
(.------.-----.-----.-----.-----.)
| | | | | |
.........................................
| | | | | |
| | | | | |
(0) (1) (2) (3) (4) (5)
| | | | | |
| | | | | |
V V V V V V
a b c d e g
( numbers instead of points in the "containers" are just to mark them
for next pictures )
* '@a' is a variable-name.
* the thing between dotted line is "Array container " .
* Array container entries can refer directly to values or to other
containers. here they point to other scalar containers.
'@c'
|
|
................|.......................
|
|
(.------.-----.-----.-----.-----.)
| | | | | |
.........................................
| | | | | |
| | | | | |
V V V V V V
0 1 2 3 4 5
we can define more "low level" arrays where Array container entries
points to values of specific type always and compiler takes care to
assure it:
Again, All this description is modulo the fact that the *actual*
implementation or *what's going on inside* may be quite far from
this. But perl make its best to *make you think that this is what
is going on. But maybe there is much simpler or different
explanation to all that .
Anyway.
my int @b = (1 .. 5); here property , something like C<is
type('returns int')> is attached to *Array container*
dc> Close enough. It's probably something more like the
dc> C<is type('returns int')> property that's being attached
dc> to the container.
so when perl see
@b[3] , @c[3]
and is asked to *evaluate* it , that is to give the value , in
both cases it reach to some value ( 'd' , 4 respectively ) . if
"on the way" to value perl encounter container it just keep going
"down" the tree to reach the value .
when perl see
@a = ( 1, 2, 3 ) ;
it creates the whole structure described by (1,2,3) evaluating
right hand side and then "hangs" it under '@a' variable-name .
there is also pair container. something like this :
'@b'
|
|
................|.......................
|
|
(.----------- => ---------------.)
| |
.........................................
| |
| |
(key) (value)
| |
| |
| |
"name" "Adam"
and so on .
??? iterators ???
dc> This is a subtle and deep question, which I shall not attempt to
dc> answer here.
--------------------------------
Assignment and binding .
--------------------------------
assignment :
--------------------------------
when perl see
( @a , @b ) = ( @c , @d ) *1*
( $x , $y ) = (@a) *2*
@a = ( 1 , 2 , 3 ) ; *3*
@a = *( @b, @c )
it is doing the following :
1) evaluate the right hand side . that is create or have an idea of
the *value* on RHS .
2) distribute that value among variables it find at the left side.
both evaluation and distribution is according to perl context
rules. By default, properties of the variable containers on the
right side do not pass to the ( variable containers on the ) left
side ( because containers are constructed anew ) . Although values
properties do ( because values *are* copied ). So assignment
creates new containers for the values on the right hand side or use
existing containers hanging under variable-names at the left
side. or both . but after the assignment *containers enclosing the
values on the left side and right side are different. values they
contain are the same.
------------------
binding :
------------------
when perl see
( $x , $y ) := ($y, $x)
*@a := ( @b, @c )
it does something different . It make some contextual decisions and
*binds* *variables-names* ( and *not* containers ) on the left side
to the *containers* on the right side .
*No value is detached from its containers* .
dc> Correct (except for the values in the containers of the symbol
dc> tables, of course ;-)
So
* all *containers* retain their compile-time properties .
( and values too )
* changing values "through" the right hand side variables
changes what is seen by left-hand side variable. and vice-versa .
so
<glossary>
in perl6
"alias" -- means "refer to the same container" -- for
scalars or "refer to the same set of containers" -- for
Arrays. Two ( or more ) variables ( strictly speaking
-- variable-names ) are said to be aliased to each
other if they refer to the same containers , but for
details see examples below.
<\glossary>
( although , new properties can be added to containers , as,
e.g. in sub arguments binding : the the new aliased variables are
read only ) .
examples :
my $a = 5;
my $b := $a; # $b now points to the same thing as $a
name | '$a' '$b'
| | |
| V |
container | (.)<------------
| |
| V
value | Number 5
$a = 10;
print $a; # prints "10"
print $b; # prints "10";
($alpha , $beta ) := ( $beta , $alpha );
before :
name | '$alpha' '$beta'
| | |
| V |
container | (.) (.)
| | |
| V |
value | Number 5 number 1
after :
name | '$alpha' '$beta'
| | |
| ------ -------
container | \ /
| X
| / \
| ------ -------
| | |
| V V
container | (.) (.)
| | |
| V V
value | number 5 number 1
(@a,@b) := (@b,@a); # works for lists and other data types, too!
here it is the same . just the two containers are two different array
containers.
the less trivial example is the following :
*@a := ( @b , @c ) ; eq.*1*
'*' is just a context tip for := operator . It just tells the perl
that you want @a to be bound to array containing @b and @c ;
this could be understood lake that :
initially :
* name '@b' points to Array container .
* each entry of that container points to a container of
corresponding Array entry variables .
something like that :
'@b'
|
V
.------.-----.-----.-----.-----.
| | | | | |
(0) (1) (2) (3) (4) (5)
| | | | | |
| | | | | |
V V V V V V
"fo0" "fo1" "fo2" "fo3" "fo4" "fo5"
( numbers instead of points in the "containers" are just to mark
them for next pictures )
and same for @c ( with containers marked by , say 10 .. 20 ).
now , after the binding @a will have the following picture :
'@a'
|
V
.------.-----.-----.-----.-----.
| | | | | |
(0) ... (5) (10) ... (20)
| | | | | |
| | | | | |
V V V V V V
"fo1" "f.." "fo6" "foA" "f.." "foK"
so '@a' 's container refer to the *same* containers that were
enclosing values in the @b and @c arrays *And* @b and @c
*continue* to *refer* to containers 0..5 and 10..20 as before
. this is all the magic . Now we can acsess the containers ( and
that means values inside and enjoy compile-time properties ) 0..5
and 10..20 *either* "through" @a[0..16] or "through" their
original "cloth" @b and @c.
dc> Correct.
dc>
dc> For those who are in shock at this point, recall that this is
dc> standard behavior in Perl 5. The Perl 5 code:
dc>
dc> # Perl 5 code...
dc> sub foo {
dc> for my $i (0..$#_) {
dc> print $_[$i], "\n";
dc> }
dc> }
dc> @b = 0..4;
dc> @c = 5..9;
dc> foo(@b,@c);
dc>
dc> does indeed print the values 0 through 9 from the one @_ array
dc> within C<foo>.
dc>
dc> Better yet, we can get back that magical "composite" array like
dc> so:
dc>
dc> # Perl 5 code...
dc> sub baz { return \@_ }
dc>
dc> @b = 0..4;
dc> @c = 5..9;
dc>
dc> *a = baz(@b,@c);
dc>
dc> for my $i (0..9) {
dc> print $a[$i], "\n"; # prints 0 through 9
dc> }
dc>
dc> $a[1] = 10; # sets $b[1] to 10 (!)
dc> $a[6] = 10; # sets $c[1] to 10 (!!!!)
dc>
dc> In Perl 6, to get the same "slurp-it-up-like-@_-used-to" effect
dc> on an array parameter, you use the unary * operator:
dc>
dc> sub baz (*@a) { return \@a }
dc>
dc> And, since calling a subroutine binds the arguments to the
dc> parameters using :=, the magical joining together of @b and @c
dc> under the name of @a is just:
dc>
dc> *@a := (@b, @c);
dc>
dc> ^^^ ^^^^^^^^
dc> | |
dc> | looks like argument list to baz
dc> |
dc> looks like parameter list of baz
dc>
( ??? lazy arrays ??? )
dc> Another deep and difficult question, beyond the scope of this
dc> discussion.
to distinguish this from assignment :
@a = *( @b, @c ) ;
@a would become
'@a'
|
V
.------.-----.-----.-----.-----.
| | | | | |
(a) ... (.) (.) ... (z)
| | | | | |
| | | | | |
V V V V V V
"fo0" "f.." "fo5" "foA" "f.." "foK"
with the whole structure under '@a' line created *anew* . New
containers . New properties of those containers ( probably none ).
Although old values. Changing @a will generally not affect @b or
@c, because perl will manipulate different containers. Although if
values are not just scalars but more elaborate structures , since
"=" did not created a full "clone" of those values changing @a
*may* change @b or @c ;
More examples :
sub foo ( *@a is rw ) { ... ; @a[5] = 1 ; ... } ;
@a = (1,2,3,4,5,6);
@b = qw( a b c d e f g ) ;
#@a[5] = 5 ;
foo @a, @b ;
#@a[5] = 1 ;
Subroutine arguments are *bound* aliased to the variables in
signature according *Exactly* the same context rules as in
:= .
dc> *Exactly* the same context rules as for :=
<Exercice 3>
And because := works that way, we can also use the flattening
operator (unary *) on either side of such bindings. For example:
(@x, *@y) := (@a, $b, @c, %d);
aliases @x to @a, and causes @y to bind to the remainder of the
lvalues -- by flattening out $b, @c, and %d into a list and then
slurping up all their components together.
Note that @y is still an alias for those various slurped
components. So @y[0] is an alias for $b, @y[[EMAIL PROTECTED]] are
aliases for the elements of @c, and the remaining elements of @y
are aliases for the interlaced keys and values of %d.
<\Exercise 3>
Now we have :
here @x refers to *the same container* as @a
here @y[[EMAIL PROTECTED]] refers to *the same containers* as $b
here @y[0] refers to *the same container* as @c
here remaining elements of @y
refers to *the same containers* as
the corresponding ( interlaced keys
and values ) containers of %d.
property example :
e.g.
$a is constant = 1;
$b = 5;
($a,$b) := ($b,$a) ;
$b = 7 #!!!! error cannot change constant .
another issue : how we know that always under '@a' array variable
is hanging array -type container ? Perl compiler creates and
manipulate containers . So when we declare
my @a = ( 1,2) ;
it creates appropriate container. we cannot manipulate containers
"directly" . only through names or something that refers them . so
perl always takes care that the declared correspondence between
name sigil ant type of container be preserved.
dc> Unless, of course, we specifically ask that it not be preserved:
dc>
dc> my @a is MagicArray; # @a implemented by MagicArray
dc> class, not Array class.
If needed it destroys
unnecessary containers and creates new.
anyway this is my flow of (un) -consciousness. my feeling is that
these things will be confusing for non-perl people.
dc> But only until they are explained to them properly. ;-)
dc>
dc>
dc> Damian