#21702 [Bgs->Opn]: nested foreach on same array using reference fails

2003-01-21 Thread vdvo
 ID:   21702
 User updated by:  [EMAIL PROTECTED]
 Reported By:  [EMAIL PROTECTED]
-Status:   Bogus
+Status:   Open
 Bug Type: Scripting Engine problem
 Operating System: Any
 PHP Version:  Any
 New Comment:

Reopening due to lack of evidence that this is not a bug. Derick has
not answered my email, he has not provided an explanation in his
bug-closing comment, I have not found any discussion about this in the
php-dev mailing list archive, and until recently, the behaviour has
been in direct contradiction with the manual (while now the manual is
unclear). Therefore, I have to assume that the statement "this is not a
bug" is unfounded. I thought that this was an open source project?

And even if the current behaviour was really intended, the
documentation needs to be clarified.

Let me ask three questions:
1) Is the current behaviour optimal?
2) If not, is it too late to correct it (because of backward
compatibility)?
3) If not, is it important enough to invest time in it?

My opinion: no, no, depends on who's time is in question. ;-)


Previous Comments:


[2003-01-17 12:12:19] [EMAIL PROTECTED]

Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

not a bug



[2003-01-17 11:55:33] [EMAIL PROTECTED]

> No matter what you call this, as a convention of open-source
> projects, documentation is generally supposed to come up
> after coding stuff.

"Supposed to"? I hope not. It does, usually, that's true. But in this
case, there _was_ documentation, and the program doesn't conform to it.
And we're talking about language semantics, not something insignificant
like configuration options.

> the codes determine the design

Tell me which programming language interpreter or compiler was created
this way?

As for the other nastiness example that you provided, it certainly does
seem nasty. Should that mean "there is at least another one nastiness,
so that is a good enough excuse to make ad-hoc language design
decisions"? I don't get it.

And yes, a language design decision it is, and it must be made. Either
we correct the documentation (it's still not completely clear, though
at least it's not so undoubtedly incorrect as two months ago), or we
correct the implementation. Judging by the lack of interest so far
(this is only the second bug report that I know of, and the docs have
been incorrect for more than two years), not many people are relying on
the current (broken) behaviour. (Anyway, why would anyone rely on such
a thing?) Thus, we have a great opportunity to do the Right Thing!

Anyway, I'm leaving for the weekend right now, so don't close this bug
before I can have another round at it on Monday, ok? ;-)



[2003-01-17 10:22:30] [EMAIL PROTECTED]

No matter what you call this, as a convention of open-source projects,
documentation is generally supposed to come up after coding stuff. In
other words, the codes determine the design, and the documents are
often elusive as there are some cases where they don't reflect the
actual behaviour.

Regarding the nastiness of references, it's special not only for
foreach, but also for the following case.



Surprisingly, this script results in
--
test
???
--
For more about this, see bug #20993 (this is also marked as a
doc-problem).




[2003-01-17 08:27:40] [EMAIL PROTECTED]

> Although I admit that the behaviour is quite inconsistent,
> we won't fix this anyway because the issue's all up to the
> language design.

Well, I dunno. In bug #8353, [EMAIL PROTECTED] says: "...the following
note exists in the foreach() entry of the manual and has for over two
years:

Note:  Also note that foreach operates on a copy of the specified
array, not the array itself, therefore the array pointer is not
modified as with the each()  construct and changes to the array element
returned are not reflected in the original array."

The documentation has been changed very recently.

To me, this seems like re-defining the language. (Or "changing the
rules in the middle of the game", if you prefer.) Instead of fixing the
bug, you say it's a feature and change the docs. That seems very
Microsoft-ish. Plus, such a language construct is inconsistent,
unintuitive and seriously limited in usability.

> foreach statement always makes use of a copy of the given
> array instead of the original itself unless the array is a
> reference or has a reference.

The "makes a copy" part is in the docs, and is what I expect. The
"unless..." part is (still) 

#21702 [Opn]: nested foreach on same array using reference fails

2003-01-17 Thread vdvo
 ID:   21702
 User updated by:  [EMAIL PROTECTED]
 Reported By:  [EMAIL PROTECTED]
 Status:   Open
 Bug Type: Scripting Engine problem
 Operating System: Any
 PHP Version:  Any
 New Comment:

> No matter what you call this, as a convention of open-source
> projects, documentation is generally supposed to come up
> after coding stuff.

"Supposed to"? I hope not. It does, usually, that's true. But in this
case, there _was_ documentation, and the program doesn't conform to it.
And we're talking about language semantics, not something insignificant
like configuration options.

> the codes determine the design

Tell me which programming language interpreter or compiler was created
this way?

As for the other nastiness example that you provided, it certainly does
seem nasty. Should that mean "there is at least another one nastiness,
so that is a good enough excuse to make ad-hoc language design
decisions"? I don't get it.

And yes, a language design decision it is, and it must be made. Either
we correct the documentation (it's still not completely clear, though
at least it's not so undoubtedly incorrect as two months ago), or we
correct the implementation. Judging by the lack of interest so far
(this is only the second bug report that I know of, and the docs have
been incorrect for more than two years), not many people are relying on
the current (broken) behaviour. (Anyway, why would anyone rely on such
a thing?) Thus, we have a great opportunity to do the Right Thing!

Anyway, I'm leaving for the weekend right now, so don't close this bug
before I can have another round at it on Monday, ok? ;-)


Previous Comments:


[2003-01-17 10:22:30] [EMAIL PROTECTED]

No matter what you call this, as a convention of open-source projects,
documentation is generally supposed to come up after coding stuff. In
other words, the codes determine the design, and the documents are
often elusive as there are some cases where they don't reflect the
actual behaviour.

Regarding the nastiness of references, it's special not only for
foreach, but also for the following case.



Surprisingly, this script results in
--
test
???
--
For more about this, see bug #20993 (this is also marked as a
doc-problem).




[2003-01-17 08:27:40] [EMAIL PROTECTED]

> Although I admit that the behaviour is quite inconsistent,
> we won't fix this anyway because the issue's all up to the
> language design.

Well, I dunno. In bug #8353, [EMAIL PROTECTED] says: "...the following
note exists in the foreach() entry of the manual and has for over two
years:

Note:  Also note that foreach operates on a copy of the specified
array, not the array itself, therefore the array pointer is not
modified as with the each()  construct and changes to the array element
returned are not reflected in the original array."

The documentation has been changed very recently.

To me, this seems like re-defining the language. (Or "changing the
rules in the middle of the game", if you prefer.) Instead of fixing the
bug, you say it's a feature and change the docs. That seems very
Microsoft-ish. Plus, such a language construct is inconsistent,
unintuitive and seriously limited in usability.

> foreach statement always makes use of a copy of the given
> array instead of the original itself unless the array is a
> reference or has a reference.

The "makes a copy" part is in the docs, and is what I expect. The
"unless..." part is (still) not in the docs and seems non-sensical. In
fact, in "What References Do", the manual says about what happens after
"$a =& $b" the following: "Note:  $a and $b are completely equal here,
that's not $a is pointing to $b or vice versa, that's $a and $b
pointing to the same place." Nowhere in the manual it says that
references are special. It just says that a reference is another name
for the same variable. I don't see why foreach treats them specially.

Note that I'm not advocating for changing the documentation; I'm
actually strongly supporting what the documentation says and has said
for a long time, and that means foreach is what needs to be changed.

BTW, does the "unless..." part of the above quotation mean that when I
do
$a =& $b;
foreach ($a as $elem)
$elem->change_self();
it will work - because foreach is not working with a copy of the array?
I suppose not, because it will surely make a copy of each element,
right? Can I then coerce it by first making an array of references to
every element, so that foreach will treat the elements specially?

Wow, this is even nastier than I thought! ;-)

Let's make a vote on the front page of php.net:
- Foreach Pro-consistency Front
program: repair foreach, return docs to previous state
- Conservative Foreach Party
program: keep foreach as is, make docs even more clear

#21702 [Opn]: nested foreach on same array using reference fails

2003-01-17 Thread vdvo
 ID:   21702
 User updated by:  [EMAIL PROTECTED]
 Reported By:  [EMAIL PROTECTED]
 Status:   Open
 Bug Type: Scripting Engine problem
 Operating System: Any
 PHP Version:  Any
 New Comment:

> Although I admit that the behaviour is quite inconsistent,
> we won't fix this anyway because the issue's all up to the
> language design.

Well, I dunno. In bug #8353, [EMAIL PROTECTED] says: "...the following
note exists in the foreach() entry of the manual and has for over two
years:

Note:  Also note that foreach operates on a copy of the specified
array, not the array itself, therefore the array pointer is not
modified as with the each()  construct and changes to the array element
returned are not reflected in the original array."

The documentation has been changed very recently.

To me, this seems like re-defining the language. (Or "changing the
rules in the middle of the game", if you prefer.) Instead of fixing the
bug, you say it's a feature and change the docs. That seems very
Microsoft-ish. Plus, such a language construct is inconsistent,
unintuitive and seriously limited in usability.

> foreach statement always makes use of a copy of the given
> array instead of the original itself unless the array is a
> reference or has a reference.

The "makes a copy" part is in the docs, and is what I expect. The
"unless..." part is (still) not in the docs and seems non-sensical. In
fact, in "What References Do", the manual says about what happens after
"$a =& $b" the following: "Note:  $a and $b are completely equal here,
that's not $a is pointing to $b or vice versa, that's $a and $b
pointing to the same place." Nowhere in the manual it says that
references are special. It just says that a reference is another name
for the same variable. I don't see why foreach treats them specially.

Note that I'm not advocating for changing the documentation; I'm
actually strongly supporting what the documentation says and has said
for a long time, and that means foreach is what needs to be changed.

BTW, does the "unless..." part of the above quotation mean that when I
do
$a =& $b;
foreach ($a as $elem)
$elem->change_self();
it will work - because foreach is not working with a copy of the array?
I suppose not, because it will surely make a copy of each element,
right? Can I then coerce it by first making an array of references to
every element, so that foreach will treat the elements specially?

Wow, this is even nastier than I thought! ;-)

Let's make a vote on the front page of php.net:
- Foreach Pro-consistency Front
program: repair foreach, return docs to previous state
- Conservative Foreach Party
program: keep foreach as is, make docs even more clear


Previous Comments:


[2003-01-17 07:36:09] [EMAIL PROTECTED]

Although I admit that the behaviour is quite inconsistent, we won't fix
this anyway because the issue's all up to the language design.

> Also, I find this very inconsistent. I didn't mention it in the
original
> description, but you know what? When you nest two foreach's using
the
> VERY SAME variable, it magically works! How is it possible that two
> references to the same variable are somehow more equivalent than the
> variable is to itself??? :-o

Well, it looks like a magic.

To say more precisely, foreach statement always makes use of a copy of
the given array instead of the original itself unless the array is a
reference or has a reference.

That's the reason you could get along with nested foreach loops in
general case. Thus the following while loop (A) is an equivalent to
(B).





Related bugs: http://bugs.php.net/bug.php?id=8353





[2003-01-17 06:29:20] [EMAIL PROTECTED]

> Marking this as a documentation problem.

I was sooo very much afraid you would do exactly this! :-(

So it is really intended to work like this? You don't find there is
anything wrong with the foreach construct?

Consider this: this means that you CAN'T use foreach at all in cases
where you don't know for certain whether you couldn't have possibly
been called from a foreach over the same array (or a reference to it,
in fact).

Also, you CAN'T use foreach in a case like mine, in which I found this
problem:

foreach ($obj->arr as $elem) {
...
$obj->method($elem);
...
}

What if the method also wants to iterate over the array? You don't
know, it wasn't you who wrote the class library...

Also, I find this very inconsistent. I didn't mention it in the
original description, but you know what? When you nest two foreach's
using the VERY SAME variable, it magically works! How is it possible
that two references to the same variable are somehow more equivalent
than the variable is to itself??? :-o

No, I don't agree that this is just a documentation problem. Marking as
a scrip

#21702 [Opn]: nested foreach on same array using reference fails

2003-01-17 Thread vdvo
 ID:   21702
 User updated by:  [EMAIL PROTECTED]
 Reported By:  [EMAIL PROTECTED]
 Status:   Open
-Bug Type: Documentation problem
+Bug Type: Scripting Engine problem
 Operating System: Any
 PHP Version:  Any
 New Comment:

> Marking this as a documentation problem.

I was sooo very much afraid you would do exactly this! :-(

So it is really intended to work like this? You don't find there is
anything wrong with the foreach construct?

Consider this: this means that you CAN'T use foreach at all in cases
where you don't know for certain whether you couldn't have possibly
been called from a foreach over the same array (or a reference to it,
in fact).

Also, you CAN'T use foreach in a case like mine, in which I found this
problem:

foreach ($obj->arr as $elem) {
...
$obj->method($elem);
...
}

What if the method also wants to iterate over the array? You don't
know, it wasn't you who wrote the class library...

Also, I find this very inconsistent. I didn't mention it in the
original description, but you know what? When you nest two foreach's
using the VERY SAME variable, it magically works! How is it possible
that two references to the same variable are somehow more equivalent
than the variable is to itself??? :-o

No, I don't agree that this is just a documentation problem. Marking as
a scripting engine problem again. You may disagree, of course, but
please, give it a thought. Or perhaps some discussion. Thanks.


Previous Comments:


[2003-01-17 06:20:26] [EMAIL PROTECTED]

Sorry, I meant the outer loop gets confused; not the deeper loop.




[2003-01-17 02:23:31] [EMAIL PROTECTED]

Actually this is a dupe of bug #14607, but this PR is much more
concise than that, so I'm going to keep 14607 bogus and make this
alive.

Since foreach() uses "internal array pointer" and references are
designed 
to share one such pointer, the deeper loop gets confused and your
script never
gives the expected result.

Virtually the script can be rewritten as...

\n";
for ($ptr = 0; $ptr < count($a); $ptr++) {
$c = $a[$ptr];
echo "inner: $c \n";
}
}
?>

Marking this as a documentation problem.
 




[2003-01-16 20:05:14] [EMAIL PROTECTED]

Try this:
\n";
foreach ($a as $c)
echo "-- inner: $c\n";
}
?>

The output is:
outer: 1
-- inner: 1
-- inner: 2
(i.e., the processing stops after the first iteration of the outer
foreach). If I understand the docs well, the output should be:
outer: 1
-- inner: 1
-- inner: 2
outer: 2
-- inner: 1
-- inner: 2
When you remove the ampersand from the assignment to $ref, it works as
expected.

The documentation is a bit unclear on this. It says "Also note that
foreach operates on a copy of the specified array, not the array
itself, therefore the array pointer is not modified as with the each()
construct...", which leads me to believe that the sample code should
work. But then it goes on to say: "However, the internal pointer of the
original array *is* advanced with the processing of the array.", which
seems to contradict the first quotation???

This is probably a dupe of bug #14607, but that one is closed as
"bogus" and I can't reopen it. Also see bug #5052, which is similar but
not quite, and it's closed.




-- 
Edit this bug report at http://bugs.php.net/?id=21702&edit=1




#21702 [NEW]: nested foreach on same array using reference fails

2003-01-16 Thread vdvo
From: [EMAIL PROTECTED]
Operating system: Linux (but probably any)
PHP version:  4.2.2
PHP Bug Type: Scripting Engine problem
Bug description:  nested foreach on same array using reference fails

Try this:
\n";
foreach ($a as $c)
echo "-- inner: $c\n";
}
?>

The output is:
outer: 1
-- inner: 1
-- inner: 2
(i.e., the processing stops after the first iteration of the outer
foreach). If I understand the docs well, the output should be:
outer: 1
-- inner: 1
-- inner: 2
outer: 2
-- inner: 1
-- inner: 2
When you remove the ampersand from the assignment to $ref, it works as
expected.

The documentation is a bit unclear on this. It says "Also note that
foreach operates on a copy of the specified array, not the array itself,
therefore the array pointer is not modified as with the each()
construct...", which leads me to believe that the sample code should work.
But then it goes on to say: "However, the internal pointer of the original
array *is* advanced with the processing of the array.", which seems to
contradict the first quotation???

This is probably a dupe of bug #14607, but that one is closed as "bogus"
and I can't reopen it. Also see bug #5052, which is similar but not quite,
and it's closed.
-- 
Edit bug report at http://bugs.php.net/?id=21702&edit=1
-- 
Try a CVS snapshot: http://bugs.php.net/fix.php?id=21702&r=trysnapshot
Fixed in CVS:   http://bugs.php.net/fix.php?id=21702&r=fixedcvs
Fixed in release:   http://bugs.php.net/fix.php?id=21702&r=alreadyfixed
Need backtrace: http://bugs.php.net/fix.php?id=21702&r=needtrace
Try newer version:  http://bugs.php.net/fix.php?id=21702&r=oldversion
Not developer issue:http://bugs.php.net/fix.php?id=21702&r=support
Expected behavior:  http://bugs.php.net/fix.php?id=21702&r=notwrong
Not enough info:http://bugs.php.net/fix.php?id=21702&r=notenoughinfo
Submitted twice:http://bugs.php.net/fix.php?id=21702&r=submittedtwice
register_globals:   http://bugs.php.net/fix.php?id=21702&r=globals
PHP 3 support discontinued: http://bugs.php.net/fix.php?id=21702&r=php3
Daylight Savings:   http://bugs.php.net/fix.php?id=21702&r=dst
IIS Stability:  http://bugs.php.net/fix.php?id=21702&r=isapi
Install GNU Sed:http://bugs.php.net/fix.php?id=21702&r=gnused