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







Reply via email to