IWETHEY v. 0.3.0 | TODO
1,095 registered users | 0 active users | 0 LpH | Statistics
Login | Create New User
IWETHEY Banner

Welcome to IWETHEY!

New Atonm, list, hash...
And what the hell are references? And why can't I have a list of lists, only a list of references to lists? Or can I?
--

This guy's ahead of his time! He's using quantum programming methods: in universes where invalid data is passed to this function, it does not return. Thus you are ensured that you will only have valid data after calling it. Optimally you'd destroy the universe on failure, but computers haven't quite advanced to that level yet.

-- [link|http://thedailywtf.com/archive/2004/10/26/2920.aspx|The] Daily WTF

New References are essentially pointers
but with a bit of built in smarts.

How about you describe the type of data structure you are trying to implement and we go from there.

New I am not trying to build anything in particular just now
I am trying to grok Perl.

For examlple, in TCL I can write

set A {aaa aaa {bbb bbb} }

and that would be list of lists

In Perl, can I write

my @A = ("aaa", "aaa", ("bbb", "bbb"));

and have a list of lists? Or will it be flattened? Or will I get (aaa, bbb, 3) because list literal is evaluated in scalar context, yelding the list's size? I now have to look it up. I need some guiding principle that makes sense.
--

This guy's ahead of his time! He's using quantum programming methods: in universes where invalid data is passed to this function, it does not return. Thus you are ensured that you will only have valid data after calling it. Optimally you'd destroy the universe on failure, but computers haven't quite advanced to that level yet.

-- [link|http://thedailywtf.com/archive/2004/10/26/2920.aspx|The] Daily WTF

New some answers
my @A = ("aaa", "aaa", ("bbb", "bbb"));

is equivilent to
my @A = ("aaa", "aaa", "bbb", "bbb");
what you probably want is
my @A = ("aaa", "aaa", ["bbb", "bbb"]);
This will create an array with three elements: 'aaa', 'aaa' and an anonymous array containing the two elements 'bbb' and 'bbb'.

Perhaps [link|http://www.oreilly.com/catalog/advperl/excerpt/ch01.html|this chapter] will help.
Have fun,
Carl Forde
New OK, another arbitrary distinction to remember
I guess Larry Wall is a linguist - must be an English language linguist. Just enough rules to make exceptions really hurt.

Here is another question: when we take a reference with \\@xxx syntax, do we take the reference to xxx variable or to the data structure it contains? In other words, say we have this piece of code:

@xxx = (1, 2, 3);
$rx = \\@xxx;
@xxx = (9,8,7);
print($rx->[0] . "\\n");

What gets printed? I'd like to guess that it's "1", but I am just confused enough to be unsure.
--

This guy's ahead of his time! He's using quantum programming methods: in universes where invalid data is passed to this function, it does not return. Thus you are ensured that you will only have valid data after calling it. Optimally you'd destroy the universe on failure, but computers haven't quite advanced to that level yet.

-- [link|http://thedailywtf.com/archive/2004/10/26/2920.aspx|The] Daily WTF

New It's easy enough to test...
Here is another question: when we take a reference with \\@xxx syntax, do we take the reference to xxx variable or to the data structure it contains? In other words, say we have this piece of code:

@xxx = (1, 2, 3);
$rx = \\@xxx;
@xxx = (9,8,7);
print($rx->[0] . "\\n");

What gets printed? I'd like to guess that it's "1", but I am just confused enough to be unsure.


the question you're asking is if once you've created the reference if you change the data that the reference was accessing, does it maintain the original data?

A better question might be : how do you gain access to the data to change it?

Compare it to :
   @xxx = (1,2,3);
   $rx = \\@xxx;
   my @xxx = (9,8,7);
   print ($x->[0] . "\\n");


New Yes it is easy to test.
I want a lojical explanation, not "look up this", "test that". Don't you think it's abysmal when such a fundamental and simple question gets the answer along the lines of "test it"?

The answer is "9".

Sooooo. $rx refers to the _variable_name_ @xxx.

It's not a pointer, not really. It's more like a true C++ reference. In C++, there is a world of difference between

char *a = b;

and

char *&a = b;

On the other hand, when we do $rx = [1,2,3]; it behaves like true pointer.

There is a simple rule in there, just waiting to pop out. I can't quite grasp it. My stream of consciousness follows.

I guess the point would be that in Perl, variables are not names of (pointers to) memory areas, but rather "resizable" and type-safe memory areas themselves. It's like having a virtual machine where the word at a given address can contain arbitrary-size array, or either string or number - no matter. The address (variable name) stays the same.

On the other hand, the "kind" of variable cannot be changed (array, hash, scalar, typeglob(?))

In this context, the difference between [] amd () becomes very interesting... I have a feeling that one of them is a literal, the other an operator. Or something.



OK, I am rambling. But I think that the learned company here is pushing me in the right direction. Thank you.
--

This guy's ahead of his time! He's using quantum programming methods: in universes where invalid data is passed to this function, it does not return. Thus you are ensured that you will only have valid data after calling it. Optimally you'd destroy the universe on failure, but computers haven't quite advanced to that level yet.

-- [link|http://thedailywtf.com/archive/2004/10/26/2920.aspx|The] Daily WTF

New Testing has some disadvantages....
...it's possible that a particular piece of code may be ambigious - meaning that the compiler writer can choose how to implement it.

So, simply "testing it" isn't always a solution.

However, in this case, the question of what is happening (and why) require first understanding what did happen. (Thus, "test it")

My rambling non-official option:

  • scalars are probably implemented as pointers (they point to something) with logic to do necessary things, such as convert between integer and characters on the fly
  • arrays are a structure, with each element being a scalar.
  • hashes are a structure (same as array), except that key and value are scalars


So...an array and a hash cannot be a member of an array or hash. (Back to that whole reference thing).

@xxx = (1, 2, 3); --- creates an array xxx and give its the values to the list (1,2,3) (lists and arrays are different - lists are a collection of scalars, lacking the structure of an array. ie: can't get a size of a list, iirc)

$rx = [1,2,3]; --- the [] create an anonymous array (ie: this IS an array). and allows the $rx to reference this array.

so @xxx = (1,2,3), $rx = \\@xxx; is very different from @xxx = (1,2,3), $rx = [1,2,3]; (there are 2 arrays created in the 2nd example).

now...to really play with your mind, 2 things....

  1. You can create N number of references to a variable...

    $reference4 = \\\\\\\\"hello!";

    How to reference this reference to a reference to a reference?
    print $$$$$refenence4;

  2. Perl also has Symbolic references -
    $variablex = 1;
    $symbolic_x = "variablex";

    print $$symbolic_x;







New It isn't arbitrary
You're just not paying attention to the grammar of the language, so it looks arbitrary. If you ignore the grammar of English you'll constantly get tripped up as well. That's life. If you approach Perl saying, "Here's how it should work", you'll be disappointed and shortly after that very frustrated. If you approach it asking, "How does it work?" you'll find that there are rules and it really works according to them.

In Perl there are two basic contexts. List context. And scalar context. In list context any data structure will try to produce a flat list. In scalar context you'll get one thing. The distinction is entirely grammatical. Generally assign stuff somewhere that takes a list, and you get list context. Pass data into a function and you'll get list context. Assign it to a scalar and you'll get scalar context.

So when you see my @A = ("aaa", "aaa", ("bbb", "bbb")); what happens is that there is a list context imposed on the RHS (you're assigning to an array, which takes a list of things) so the RHS is flattened out into a list. Namely ("aaa", "aaa", "bbb", "bbb"). Nothing strange going on with data structures. It is all a question of what the grammar says.

Now to answer the question you had here, the \\ operator takes a reference to something. Think of it as like taking a pointer to a variable in C or C++. (Except that the memory-management is taken care of for you.) Therefore $rx points to whatever @xxx currently has. Updating @xxx is the same as updating @$rx, and vice versa.

If this bothers you, please describe what you'd expect from similar code with pointers in C or C++. Perl is just acting the same way.

If you want a private array you can use the anonymous array constructor, []. In the example that you gave, you'd get the result you were hoping for from:
\n@xxx = (1, 2, 3);\n$rx = [@xxx];\n@xxx = (9,8,7);\nprint($rx->[0] . "\\n");\n

Cheers,
Ben
I have come to believe that idealism without discipline is a quick road to disaster, while discipline without idealism is pointless. -- Aaron Ward (my brother)
New References: pointers in languages that don't have pointers
New okay...look at it this way....
a scalar is a LISP atom...the basic unit in Perl, and you get to it via a $.

An array is a collection of scalars. This is why you have to have a reference to have a list of lists.

Likewise a hash is a collection of keys, which have to be scalars (see the Tie module if you want it to be something else) to scalars.

A Perl reference merely is a scalar to something else (such as a scalar, array or hash).
    $scalarRef = \\$scalar
    $listRef = \\@list
    $hashRef = \\%hash

To access -
   $scalar = $$scalarRef
    @list = @$listRef
    $hashRef = %$hashRef (iirc)
New PERL DOES NOT STORE LISTS!!!
You'll save yourself a lot of confusion if you memorize the above sentence.

A list in Perl is a temporary data structure that (in list context) is passed somewhere. Once the operation is done, the list is gone. Vanished. Kaput. You might store the list in an array. But an array is not a list. An array is a bag that contains a list of things.

So you can't create a list of lists in Perl. Doesn't exist. If you try you'll get one long flat list. You can create an array of references to arrays which accomplishes the same goal. But it isn't a list of lists.

Cheers,
Ben
I have come to believe that idealism without discipline is a quick road to disaster, while discipline without idealism is pointless. -- Aaron Ward (my brother)
New OK, in that case, what is (a,b,c) ?
[a,b,c] is an anonymous array constryctor. That I understand. What is (...) thing? What does it produce?
--

This guy's ahead of his time! He's using quantum programming methods: in universes where invalid data is passed to this function, it does not return. Thus you are ensured that you will only have valid data after calling it. Optimally you'd destroy the universe on failure, but computers haven't quite advanced to that level yet.

-- [link|http://thedailywtf.com/archive/2004/10/26/2920.aspx|The] Daily WTF

New In which context?
In list context it produces a list that something is hopefully done with. In scalar context it returns the last element in the list (if the list is empty, then undef).

But my point is that the list is a transient thing. It is not a data structure that will exist to the next statement: it is produced and consumed within one statement. It is how Perl passes data around, not how Perl stores data.

If you try to think of it as anything other than the semantics indicated by Perl's grammar, you'll confuse yourself. Because that is all it is.

Cheers,
Ben
I have come to believe that idealism without discipline is a quick road to disaster, while discipline without idealism is pointless. -- Aaron Ward (my brother)
New In the context of grammar and syntax
What kind of syntactic structure is it? For examply, in

@a = (1,2,3);

and in

myfunc(1,2,3)

are the (...) constructs syntactically different? They are in C++.

Also, what is "list"? I sort of understand "array". But that ephemeral "list" thing just throws me off.
--

This guy's ahead of his time! He's using quantum programming methods: in universes where invalid data is passed to this function, it does not return. Thus you are ensured that you will only have valid data after calling it. Optimally you'd destroy the universe on failure, but computers haven't quite advanced to that level yet.

-- [link|http://thedailywtf.com/archive/2004/10/26/2920.aspx|The] Daily WTF

New Simple answer: there is no syntactic difference
In most code the two behave exactly the same. If you're trying to build a simple model of how Perl works, stop there.

Now for some the gory details and minor quibbles. In function calls you can get a slightly different behaviour, and it is a judgement call about whether to think about this as there being a syntactic difference, or whether you think of the way it behaved in assignment to be the same as the function case - just with the default behaviour. I'd lean towards saying that the syntax is the same - but only functions can specify non-default behaviour.

Explaining that will take a bit.

First of all what is a list? A list is what you'd guess naively, an ordered list of things. Think of shoving a bunch of stuff on the stack - that's a list. In fact I believe that that's how Perl actually works internally, it sticks pointers to the list on the stack, and calls an operation that is supposed to do something with those arguments. When the opcode finishes, the stack is cleared. This all happens at the C-level, all actual Perl data structures are kept in the heap. They have to be because their lifetime is indeterminate when the data is created. (Note that in Perl 6 even lists will be created in the heap to allow continuations to be added to the language. This is very similar to Python vs Stackless Python.)

Arrays and hashes and most functions will accept a list and do something intelligent with it. If you assign the list to an array, the array is filled with that list, element 0 goes to element 0, element 1 goes to element 1 and so on. If you assign the list to a hash, it is interpreted as a list of key/value pairs and the hash is set up accordingly. If you call a function the elements of the list are aliased to @_, and the function is supposed to get the arguments from there.

Hopefully the idea of a list is fairly clear - it is supposed to be straightforward.

Now we come to the non-straightforward part. Normally when you call a function, everything is expanded out. So if you see something like:
\n  foo(@stuff, @more_stuff, bar());\n

then foo will get a list containing everything in @stuff followed by everything in @more_stuff followed by what bar() returned. But there are exceptions. For instance:
\n  push(@stuff, @more_stuff, bar());\n

adds the contents of @more_stuff and the return of bar() to the end of @stuff. The push built-in has something (mis)named a prototype that causes the generated list to be (\\@stuff, @more_stuff). You still get a list - just a slightly different one than you would expect.

This was originally shoehorned in for backwards compatibility. In Perl 1-4 these built-ins had special behaviour, and there was no good way to get the same behaviour for user-defined functions because you didn't have references. Through Perl 5 the capability to write functions that behave the same way as these special built-ins has been added. Using this capability is generally a very, very bad idea. For a full explanation of how it works, what it does, and why it is a bad idea, read [link|http://library.n0i.net/programming/perl/articles/fm_prototypes/|FMTYEWTK About Prototypes].

Now that I've explained this whole prototype thing, you see that it is possible for functions to get a slightly different list than you'd expect just looking at the argument list. However the default behaviour is, "expand everything expandable out into a flat list". If you're assigning to array you get this same default behaviour. With functions you have some control over how this list expansion works. With array assignment you don't.

Cheers,
Ben
I have come to believe that idealism without discipline is a quick road to disaster, while discipline without idealism is pointless. -- Aaron Ward (my brother)
New OK, I think I get it.
Here goes:

Perl has scalars, arrays and hashes for data structures (scalars can be references). For passing a few things around, Perl uses lists. Lists are not goddamned arrays, goddamn your goddamned eyes, you goddamned sissy puspus programmer! Got it?

In all seriouosness, I think I understand much better now. Thank you very much for taking your (even more valuable now) time and producing a lucid explanation. This deserves to be written in some kind of global FAQ place, if it's not already there.
--

This guy's ahead of his time! He's using quantum programming methods: in universes where invalid data is passed to this function, it does not return. Thus you are ensured that you will only have valid data after calling it. Optimally you'd destroy the universe on failure, but computers haven't quite advanced to that level yet.

-- [link|http://thedailywtf.com/archive/2004/10/26/2920.aspx|The] Daily WTF

New Yup, sounds like you've got it
As for a global FAQ, the perldata manpage attempts to explain this, along with the full syntax involved. The information is there - but the problem for the reader is extracting the information that you need from the mass of information that you might possibly need. (A problem which is complicated by the fact that different people need different pieces of information.)

Cheers,
Ben
I have come to believe that idealism without discipline is a quick road to disaster, while discipline without idealism is pointless. -- Aaron Ward (my brother)
     One line description of data model for Perl - (Arkadiy) - (33)
         Yep, you got it right. - (admin) - (1)
             You're not helping - (Arkadiy)
         Perl: Everything is... - (ChrisR)
         Over simplifying - (broomberg) - (1)
             linquistic versus data personalities - (tablizer)
         To pick up from what Barry said. - (static) - (4)
             No, everything is whatever Barry needs it to be - (Arkadiy) - (3)
                 The logic - (ben_tilly) - (2)
                     Keys... - (Simon_Jester) - (1)
                         Tie is NOT a module (and it sucks) - (ben_tilly)
         Well, Lisp - everything is a list or an atom... - (Simon_Jester) - (18)
             Atonm, list, hash... - (Arkadiy) - (17)
                 References are essentially pointers - (broomberg) - (7)
                     I am not trying to build anything in particular just now - (Arkadiy) - (6)
                         some answers - (cforde) - (5)
                             OK, another arbitrary distinction to remember - (Arkadiy) - (4)
                                 It's easy enough to test... - (Simon_Jester) - (2)
                                     Yes it is easy to test. - (Arkadiy) - (1)
                                         Testing has some disadvantages.... - (Simon_Jester)
                                 It isn't arbitrary - (ben_tilly)
                 References: pointers in languages that don't have pointers -NT - (FuManChu)
                 okay...look at it this way.... - (Simon_Jester)
                 PERL DOES NOT STORE LISTS!!! - (ben_tilly) - (6)
                     OK, in that case, what is (a,b,c) ? - (Arkadiy) - (5)
                         In which context? - (ben_tilly) - (4)
                             In the context of grammar and syntax - (Arkadiy) - (3)
                                 Simple answer: there is no syntactic difference - (ben_tilly) - (2)
                                     OK, I think I get it. - (Arkadiy) - (1)
                                         Yup, sounds like you've got it - (ben_tilly)
         lets try another viewpoint - (daemon)
         Sorry for not responding in this thread earlier - (ben_tilly) - (2)
             No worries. - (Arkadiy) - (1)
                 :-) -NT - (ben_tilly)

Mandatory cayenne enemas would have the same effect.
92 ms