Arcadi wrote:

this is not a description or definition of something. It is just set
of questions and confusions that I have when I encounter words like
"variable" , "name" , "alias", "assign" in perl . In the form of
explanation. But actually these are questions .
These are answers. In the form of answers. ;-)



perl have 3 *mostly* independent concepts i) variable-names ( live in namespaces ) 2) actually variables or *containers* live in perl memori at
compile-time-phase .
Or run-time (e.g. lexicals, anonymous variables)


3) values live everywere and are the MOSTIMPORTANTTHING.
That is a philosophical position. I could also argue that
values are the LEASTIMPORTANTTHING: that they are merely
trivial "special cases" of the abstractions embodied by
the variables. I could also argue that even variables are
UNIMPORTANTTHINGS; that only the relationships between
variables, as represented by the algorithm, matter.

All just philosophical positions. ;-)


Variable is the following 3-level thing

1) name | '$a' | |
| V
2) container | (.) | |
| V
3) value | some number e.g., 5
Yes. This is a deep understanding. Excellent.


names are strings that can be chosen according to some
restrictions.
Though, in Perl, those restrictions aren't terribly restrictive. Here, for example,
is a variable whose name is (phonetically):

	 NEWLINE-NEWLINE-ALLO-ALLO-SPACE-the-SPACE-sky-SPACE-is-TAB-falling-BANG-BANG-BANG

and yet it is perfectly legal in Perl:

	*{'
	
	«» the sky is	falling!!!'} = \[0]->[0];
	while (${'
	
	«» the sky is	falling!!!'}<10) {
		print ${'
	
	«» the sky is	falling!!!'}, "\n";
		${'
	
	«» the sky is	falling!!!'}++;
	}


	
Names *live* in *namespace* .  that is, perl keep some
tables ( aka  as namespaces ) that list known variable-names. and each
name refer to a container.  the type of namespace: global, package,
lexical and so on defines the *scope* of variable-name, life-circle of
variable-name and so on ( but everything for variable-name ).
Another deep insight. Well done.

special modifiers "my" "our" help to place the variable-name in the desired
"variable-namespace".
container is mystical intermediate between value and variable
name.
Mystical? I'd have said that the container is the *least* mystical
part of the symbiosis. It's the only tangible piece of the puzzle.


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.

In perl variable may have properties . Actually containers have.
And values may have them too.


value is actual data - the 0's and 1's that actually run here and
there when program runs.
Not quite. The value is the *interpretation* of the 1's and 0's.
For example, the same bitsequence (say 01010101) may be part of
a (very short) string, or an integer, or a floating point number, or a
reference. And no two of those interpretations will necessarily
represent the same "value.


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 ???) .

ha, and also, variable ( actually the container ) may be anonymous (
All containers are inherently anonymous. In a sense, a variable is
merely the association of a container and a name.


as most of variables in usual perl program ), in that case it is not
referenced to by some "variable-name" *directly* ; but it is
definitely referenced by something -- otherwize it is dead.

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 ????)
Sometimes they can be optimized away; sometimes not.


 *run time properties are attached to values ; they are introduced
  with "but"; they begin to function at run-time, but perl at compiler
  time may well be aware of them ( ??? ) .
Yes, it may be. If the value is a compile-time value such as:

	return 0 but true;

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 to whom 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 | 1->props->{ true=>1 }

( I am not sure about the runtime property ???)
The value should be:

  3) value                |    0->props->{ true=>1 }



Apocalypsis 3 and Exercise 3
Apotheosis 3 and Excoriation 3?
Apoplexy 3 and Exorcism 3?
Apogee 3 and Escapevelocity 3?


have lots of examples of properties .
Types of variables , 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 . and in fashion.
here we have seem an example of scalar container -- the (.) thing.
perl have other container classes. Array. Array can be pictured like that .
my @b = ( 1 ,2 , 3 ,4 ,5 ) ;

'@b' |
|
.................|.......................
|
|
(.------.-----.-----.-----.-----.)
| | | | | |
.........................................
| | | | | |
| | | | | |
(1) (2) (3) (4) (5) (6) | | | | | |
| | | | | |
V V V V V V
a b c d e g
For consistency, those indexes probably should start from zero.


( 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 point directly to values or to other
containers. here they point to other scalar containers. ???

we can define more "low level" arrays where Array container entries
points to data of specific type always and compiler takes care to
assure it: Again, All that 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 "returns int" is attached to *Array container* ????( but maybe I am wrong) ????
Close enough. It's probably something more like the
C<is type('returns int')> property that's being attached
to the container.


so when perl see
@a[3] , @b[3]
and is asked to *evaluate* it , that is to give the value , in both cases it reach to some value ( 'c' , 3 respectively ) . if if on the way to value perl encounter container it just keep going.
when perl see
@a = ( 1, 2, 3 ) ;
it creates the whole structure evaluating right hand side and then
"hangs" it under '@a' variable-name .

there is also pair container. something like this :
'@b' |
|
.................|.......................
|
|
(.----------- => ----------------.)
| |
.........................................
| |
| |
(key) (val) | |
| |
| |
"name" "Adam"
The value component will probably be called C<value>, not C<val>.


and so on . ??? iterators ???
This is a subtle and deep question, which I shall not attempt to 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 defaults properties of the variables on the right side do not pass
to the left side . 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 on the left and right side are different * . although
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* or appropriate containers  on the left side
No, never containers. Always names.


to the *containers* on the right side .
This bit is correct.


*No value is detached from its containers* .
Correct (except for the values in the containers of the symbol tables, of course ;-)


So * all *variables* remain with their ( compile-time) properties . ( and and values too )
Better to say that all *containers* retain their compile-time properties.


* changing values "through" the right hand side variables changes what is seen by left-hand side variable. and vice-versa .
Correct.



so perl6 "alias" means refer to the same container. ( for scalars) or refer to the same set of containers for Arrays.
Correct.


( although , new properties can be added to containers , as, e.g. in sub arguments binding : the the new aliase variables are read only ) .
True.


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

Correct.


  $a = 10;
  print $a;    # prints "10"
  print $b;    # prints "10";
Correct.



------------------------
  ($a,$b) := ($b,$a);
You should use different variable names here, to make it clear that this
is a different example.


before :
name | '$a' '$b' | | | | V | container | (.) (.)
| | |
| V |
value | Number 5 number 1

after :
name | '$a' '$b' | | | | ------ ------- container | \ / | X | / \ | ------ ------- | | |
| V V
container | (.) (.)
| | |
| V V
value | Number 5 number 1
Correct.


(@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 entrie variables .
something like that :
'@b' |
V
.------.-----.-----.-----.-----. | | | | | |
(1) (2) (3) (4) (5) (6) | | | | | |
| | | | | |
V V V V V V
"fo1" "fo2" "fo3" "fo4" "fo5" "fo6"
( 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
.------.-----.-----.-----.-----. | | | | | |
(1) ... (6) (10) ... (20) | | | | | |
| | | | | |
V V V V V V
"fo1" "f.." "fo6" "foA" "f.." "foK" while still @a *points* to containers 1..6 as before and @c -- to
containers 10-20.

???
Correct.

For those who are in shock at this point, recall that this is standard behaviour
in Perl 5. The Perl 5 code:

	# Perl 5 code...
	sub foo {
	    for my $i (0..$#_) {
	        print $_[$i], "\n";
	    }
	}
	@b = 0..4;
	@c = 5..9;
	foo(@b,@c);

does indeed print the values 0 through 9 from the one @_ array within C<foo>.

Better yet, we can get back that magical "composite" array like so:

	# Perl 5 code...
	sub baz { return \@_ }

	@b = 0..4;
	@c = 5..9;

	*a = baz(@b,@c);

        for my $i (0..9) {
	    print $a[$i], "\n";    # prints 0 through 9
	}

	$a[1] = 10;   # sets $b[1] to 10 (!)
	$a[6] = 10;   # sets $c[1] to 10 (!!!!)

In Perl 6, to get the same "slurp-it-up-like-@_-used-to" effect on an array
parameter, you use the unary * operator:

	sub baz (*@a) { return \@a }

And, since calling a subroutine binds the arguments to the parameters using :=,
the magical joining together of @b and @c under the name of @a is just:

	*@a := (@b, @c);

        ^^^    ^^^^^^^^
	 |        |
         |        looks like argument list to baz
	 |
	 looks like parameter list of baz




( ??? lazy arrays ??? )
Another deep and difficult question, beyond the scope of this discussion.


to distinguish this from assignment :
@a = *( @b, @c ) ;
@a would become
'@a' |
V
.------.-----.-----.-----.-----. | | | | | |
(a) ... (.) (.) ... (z) | | | | | |
| | | | | |
V V V V V V
"fo1" "f.." "fo6" "foA" "f.." "foK"
with the whole structure under '@a' line created *anew* . New
containers . 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 ;
Correct.



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 to
> more or less the same context rules as in := .

*Exactly* the same context rules as for :=



exe3 > And because := works that way, we can also use the flattening operator exe3 > (unary *) on either side of such bindings. For example: exe3 > exe3 > (@x, *@y) := (@a, $b, @c, %d);
exe3 > aliases @x to @a, and causes @y to bind to the remainder of the
exe3 > lvalues -- by flattening out $b, @c, and %d into a list and then
exe3 > slurping up all their components together. exe3 > exe3 > exe3 > Note that @y is still an alias for those various slurped
exe3 > components. So @y[0] is an alias for $b, @y[[EMAIL PROTECTED]] are aliases
exe3 > for the elements of @c, and the remaining elements of @y are aliases
exe3 > for the interlaced keys and values of %d.

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 .
Correct.


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.
Unless, of course, we specifically ask that it not be preserved:

	my @a is MagicArray;	# @a implemented by MagicArray class, not Array class.


If needet it destrys
unnecessary contauiners and creates new.


anyway this is my flow of (un) -consciousness. my feeling is that these things will be confusing for non-perl people.
But only until they are explained to them properly. ;-)


Damian

Reply via email to