FMTWYENTK about := ( :-)

0 views
Skip to first unread message

fear...@figaro.weizmann.ac.il

unread,
Nov 5, 2002, 1:03:12 PM11/5/02
to perl6-language

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 .


so , what follows is not the "how it actually works" but just how I
can look at it and be able to understand what's going on. but probably
thats not very far from what *actually* going on there. The good
analogy is from physics. we invent Quantum mechanics for us to be able
to understand ( more exactly - to follow ) what's going on with
... electron. Electron *himself* ( and nature generally) *most
probably* *cannot add 2+2* , not to speak about solving Schroedinger
equation. and what I am going to say is definitely much simpler then QM.
just for fun.

So that is *my* picture of what is going on when I see := , = and such.
And it well may happen that I am wrong or imprecise. well...

Language manipulate the data. but in order to do it effectively ( or
just elegantly ) it abstract or hide it. Data is values - all sorts of
0's and 1's that are moving around in the computer when the program is
running. and program is the one to instruct the computer to move data
around . generally program don't know what *is* the actual value of
data . programs are usually useful fore *generating* new previously
unexisted values of data. although there is a lot more , since e.g.
the "in the beginning" of computer language books <<print "Hello, I
did something">> ; does not generate new data , but still make a lot
of noise and have many important concepts in it. the program abstracts data
and manipulate it through *variable* . in the language ( which is some (meaningful ) text ) variable is a name. but in order to understand the structure of what is going on we need the following *picture* of variable .

so again, variable is "language interface" to values. Values is what
actually matters and is really important, but language prefer to
introduce an intermediate level between it and values.

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 . Are needed for compiler to manipulate and keep
track of values .
3) values live everywere and are the MOSTIMPORTANTTHING.

Variable is the following 3-level thing


1) name | '$a'
| |
| V
2) container | (.)
| |
| V
3) value | some number e.g., 5

names are strings that can be chosen according to some
restrictions. 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 ). special
modifiers "my" "our" help to place the variable-name in the desired
"variable-namespace".

container is mystical intermediate between value and variable
name. 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. One
second.


value is actual data - the 0's and 1's that actually run here and
there when program runs. 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 (
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 ????)
*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 ( ??? ) .

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

Apocalypsis 3 and Exercise 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

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

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"

and so on .
??? iterators ???


--------------------------------
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 to
the *containers* on the right side . *No value is detached from its
containers* . So
* all *variables* remain with their ( compile-time) properties .
( and and values too )
* changing values "through" the right hand side variables
changes what is seen by left-hand side variable. and vice-versa .

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

( although , new properties can be added to containers , as, e.g. in sub arguments binding : the the new aliase 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";


------------------------
($a,$b) := ($b,$a);

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



(@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.

???

( ??? lazy arrays ??? )

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 ;

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 := .


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[1..@c.length] 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[1..@c.length] 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. 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.

thanks.

arcadi.

Damian Conway

unread,
Nov 11, 2002, 6:31:39 AM11/11/02
to perl6-l...@perl.org
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.

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.

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[1..@c.length] 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[1..@c.length] 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 all
Reply to author
Forward
0 new messages