Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Re^5: Confused as to why the "casting context" is mis-behaving (return array)

by tye (Sage)
on Oct 25, 2010 at 13:27 UTC ( #867228=note: print w/replies, xml ) Need Help??


in reply to Re^4: Confused as to why the "casting context" is mis-behaving (return array)
in thread Confused as to why the "casting context" is mis-behaving

The point was, when the function returns, the caller "can know" that some array was returned.

You'll have to explain how, then. The caller can't know that an array was involved because the caller only gets a list of scalar values pushed onto the stack.

By the way, your code examples don't prove that the copying happens before the return. They just prove, that the "for" loop works with copies of values. Nothing else.

Half of the code proves that the 'for' loop gets copies. The other half of the code proves that 'for' loops don't get copies when using an array. That's one of the major features of 'for' loops: They work on aliases not copies when possible. When calling a function, working on aliases isn't possible (because what gets pushed onto the stack is copies of each scalar value).

- tye        

  • Comment on Re^5: Confused as to why the "casting context" is mis-behaving (return array)

Replies are listed 'Best First'.
Re^6: Confused as to why the "casting context" is mis-behaving (return array)
by andal (Hermit) on Oct 26, 2010 at 09:34 UTC
    You'll have to explain how, then. The caller can't know that an array was involved because the caller only gets a list of scalar values pushed onto the stack.

    I gave you examples of difference between returning array and list. For example, "return @ab" is not the same as "return (@ab, 'txt')". In the first case assignment of returned value to scalar will produce the count of elements in the array. In the second case it will produce the 'txt'. You can try "return ('txt', @ab)" and again you'll get count of elements in @ab when assigning to scalar. So the caller gets not the list of scalar values, but the list of objects, some of which may be hashes or arrays and some scalars.

    The copying magic happens when transferring objects from stack into the destination. The destination gets the copy of what was on the stack, but the copy might be flattened. So, if the list of scalars is needed, then the arrays and hashes will be expanded. But if the single scalar is needed, then the last object from the stack will be taken and "converted" into scalar.

    Half of the code proves that the 'for' loop gets copies. The other half of the code proves that 'for' loops don't get copies when using an array. That's one of the major features of 'for' loops: They work on aliases not copies when possible. When calling a function, working on aliases isn't possible (because what gets pushed onto the stack is copies of each scalar value).

    This is only because the values from the stack are copied into the list and only after that "for" has a chance to alias them. If you use the array directly, then the values are not copied (there's no stack involved). So the "for" loop has chance to alias the elements of the array directly. Remember the rule. Returned on the stack values are always copied before they can be used!

      It is a nice fantasy you have built. It is nice that it works for you. It actually diverts from reality and it uses terminology (and concepts) quite at odds with how Perl is documented. So I don't consider it a good model for others to use.

      But I'm tired of trying to point out facts. You aren't interested in how things actually work and I'm not interested in trying to understand your made-up concepts of "OBJECTS" and "COLLECTIONS".

      "Remember the rule. Returned on the stack values are always copied before they can be used!"? Or learn the truth: 'returned on the stack from a function' values are already copies. But it is also just a simpler model, not having to invent an extra "it came from a function, so after returning, the values must be copied (for some mysterious reason)". How is this "it came from a function" information communicated to the for() loop so that it knows it has to take a copy? What have you invented to explain that?

      Did you know that for($x,$y,$z) actually pushes three scalar values (that are aliases) onto the stack as well? But for() doesn't make copies of those values when it pulls them from the stack. Perl uses a stack-based op-code-dispatch machine. It is a common concept in computing.

      I'm not advocating that there is only one correct mental model. That would be stupid. I'm just discouraging people from just making stuff up and then clinging to it. In particular, when you find an exception that your current mental model doesn't handle, don't just make up yet another thing to add to your mental model. That just leads to your mental model getting further and further from reality as you "learn" more and more about Perl.

      You want to cling to the idea that the array gets returned and then it gets turned into a scalar after the function returns. In reality, return @array; is implemented as something much closer to:

      return wantarray ? @array[0..$#array] : 1+$#array;

      Is there some way you think the caller can tell the above from return @array;?

      This is only because the values from the stack are copied into the list and only after that "for" has a chance to alias them.

      So the sub "returns the array" (whatever that means) then values from the stack are copied into a list and then for() aliases them? That's a lot of extra steps you have invented. In reality (if anybody cares), the sub pushes onto the stack (copies of the scalar values from the array) and the for() iterates over what is on the stack (just using them in-place).

      - tye        

        So the sub "returns the array" (whatever that means) then values from the stack are copied into a list and then for() aliases them? That's a lot of extra steps you have invented. In reality (if anybody cares), the sub pushes onto the stack (copies of the scalar values from the array) and the for() iterates over what is on the stack (just using them in-place).

        Maybe you'll then try to explain why "return (@a)" behaves differently than "return (@a, 'b')" and differently than "return ('b', @a)" when assigned to scalar? According to your explanation, everything is flattened to the list, and then the assignment to scalar should always pick up the last element from the list. But it does not.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://867228]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2018-10-21 16:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    When I need money for a bigger acquisition, I usually ...














    Results (119 votes). Check out past polls.

    Notices?