I thought `| should keep the order when used on arrays:
Pike v7.3 release 62 running Hilfe v3.5 (Incremental Pike Frontend)
({1,2,3}) | ({2,4,1,17});
(1) Result: ({ /* 5 elements */ 3, 2, 4, 1, 17 })
Looks like it keeps the order in the second array, but the remaining elements in the first are swapped in this case. I furthermore expected the elements in the first array to remain unchanged with precedence over those in the second, since that makes it behave more consistently when used as |=, in which case all the elements in the left operand would remain on the same indices.
Wasn't this discussed and supposedly fixed some time ago (half a year or so)?
[...] I furthermore expected the elements in the first array to remain unchanged with precedence over those in the second, since that makes it behave more consistently when used as |=, in which case all the elements in the left operand would remain on the same indices.
Consistant with what? Giving the right operand precedence is consistant with the other |(=) operators AFAIK:
Pike v7.3 release 62 running Hilfe v3.5 (Incremental Pike Frontend)
(["hej":17])|(["hej":42]);
(1) Result: ([ /* 1 element */ "hej":42 ])
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2002-12-03 19:06: Subject: `| and order on arrays
I thought `| should keep the order when used on arrays:
Pike v7.3 release 62 running Hilfe v3.5 (Incremental Pike Frontend)
({1,2,3}) | ({2,4,1,17});
(1) Result: ({ /* 5 elements */ 3, 2, 4, 1, 17 })
Looks like it keeps the order in the second array, but the remaining elements in the first are swapped in this case. I furthermore expected the elements in the first array to remain unchanged with precedence over those in the second, since that makes it behave more consistently when used as |=, in which case all the elements in the left operand would remain on the same indices.
Wasn't this discussed and supposedly fixed some time ago (half a year or so)?
/ Martin Stjernholm, Roxen IS
Consistent wrt the case I mentioned. It wouldn't work to try to make it consistent with mappings: A mapping equivalent to these arrays would be (based on that `[] still operates the same):
([0:1, 1:2, 2:3]) | ([0:2, 1:4, 2:1, 3:17]);
(1) Result: ([ /* 4 elements */ 0:2, 1:4, 2:1, 3:17 ])
I.e. ({1,2,3})|({2,4,1,17}) should produce ({2,4,1,17}) to make that isomorphism hold, which is clearly useless for `|.
/ Martin Stjernholm, Roxen IS
Previous text:
2002-12-03 19:11: Subject: `| and order on arrays
[...] I furthermore expected the elements in the first array to remain unchanged with precedence over those in the second, since that makes it behave more consistently when used as |=, in which case all the elements in the left operand would remain on the same indices.
Consistant with what? Giving the right operand precedence is consistant with the other |(=) operators AFAIK:
Pike v7.3 release 62 running Hilfe v3.5 (Incremental Pike Frontend)
(["hej":17])|(["hej":42]);
(1) Result: ([ /* 1 element */ "hej":42 ])
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Consistent wrt the case I mentioned.
The case you mentioned is one that doesn't exist right now, so I don't see how "consistency" with it would be any point in itself.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2002-12-03 19:27: Subject: `| and order on arrays
Consistent wrt the case I mentioned. It wouldn't work to try to make it consistent with mappings: A mapping equivalent to these arrays would be (based on that `[] still operates the same):
([0:1, 1:2, 2:3]) | ([0:2, 1:4, 2:1, 3:17]);
(1) Result: ([ /* 4 elements */ 0:2, 1:4, 2:1, 3:17 ])
I.e. ({1,2,3})|({2,4,1,17}) should produce ({2,4,1,17}) to make that isomorphism hold, which is clearly useless for `|.
/ Martin Stjernholm, Roxen IS
The consistency is between the first and third steps below:
1. if (foo[2] == 3) x(); 2. foo |= bar; 3. if (foo[2] == 3) x();
/ Martin Stjernholm, Roxen IS
Previous text:
2002-12-03 20:41: Subject: `| and order on arrays
Consistent wrt the case I mentioned.
The case you mentioned is one that doesn't exist right now, so I don't see how "consistency" with it would be any point in itself.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Today you have that "consistency" for the right element instead:
1. if (bar[-3] == 4) x(); 2. bar = foo | bar; 3. if (bar[-3] == 4) x();
You can't have both, and I don't see why one would be more important than the other.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2002-12-03 20:47: Subject: `| and order on arrays
The consistency is between the first and third steps below:
- if (foo[2] == 3) x();
- foo |= bar;
- if (foo[2] == 3) x();
/ Martin Stjernholm, Roxen IS
I can. All the op= operators are centered on the left operand. That (if nothing else) makes "left stable" operations much more common than "right stable" ones. It continues to carry down to the "left stable" realloc which often makes such operations more efficient too. Thus the main data collection is more commonly in the left operand and the (typically smaller) change to it in the right.
When it comes to `|, I believe it's more useful if the order of the main data collection takes precedence over that of the change since it's typically the existence of the elements and not the order that one wants from the change.
/ Martin Stjernholm, Roxen IS
Previous text:
2002-12-03 20:50: Subject: `| and order on arrays
Today you have that "consistency" for the right element instead:
- if (bar[-3] == 4) x();
- bar = foo | bar;
- if (bar[-3] == 4) x();
You can't have both, and I don't see why one would be more important than the other.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
I can. All the op= operators are centered on the left operand. That (if nothing else) makes "left stable" operations much more common than "right stable" ones.
Uh, I though that "right stable" operations were more common in Pike. Can you present some statistics which supports your claim?
When it comes to `|, I believe it's more useful if the order of the main data collection takes precedence over that of the change since it's typically the existence of the elements and not the order that one wants from the change.
All you have to do is put the "main data collection" to the right, and the "change" to the left, and you will get this.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2002-12-03 22:33: Subject: `| and order on arrays
I can. All the op= operators are centered on the left operand. That (if nothing else) makes "left stable" operations much more common than "right stable" ones. It continues to carry down to the "left stable" realloc which often makes such operations more efficient too. Thus the main data collection is more commonly in the left operand and the (typically smaller) change to it in the right.
When it comes to `|, I believe it's more useful if the order of the main data collection takes precedence over that of the change since it's typically the existence of the elements and not the order that one wants from the change.
/ Martin Stjernholm, Roxen IS
In code I write I make a conscious effort to arrange orders in arrays to be able to use a += ({17}) instead of a = ({17}) + a. In other code I also see constructs of the first kind far more often than the second. Do you really have the opposite perception of the situation?
All you have to do is put the "main data collection" to the right, and the "change" to the left, and you will get this.
No. Then I had to reverse the main collection both before and after the operation, or else start replacing the use of a += ({17}) with the both clumsier and slower a = ({17}) + a everywhere else.
/ Martin Stjernholm, Roxen IS
Previous text:
2002-12-03 23:25: Subject: `| and order on arrays
I can. All the op= operators are centered on the left operand. That (if nothing else) makes "left stable" operations much more common than "right stable" ones.
Uh, I though that "right stable" operations were more common in Pike. Can you present some statistics which supports your claim?
When it comes to `|, I believe it's more useful if the order of the main data collection takes precedence over that of the change since it's typically the existence of the elements and not the order that one wants from the change.
All you have to do is put the "main data collection" to the right, and the "change" to the left, and you will get this.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Well, the fact that `a = ({ 17 }) + a' is more clumsy to write than `a = a + ({ 17 })' is of course a syntactic misfeature. It would be quite nice (and much more symmetric) to have a syntax for compacting the first variant into an op-assignment as well. Any suggestions? IIRC, the `a =+ foo' syntax was abandoned by the C people because it led to ambiguities if the whitespaces was ommitted, so although a natural choice it would probably be an unsuitable candidate for a new syntax.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2002-12-03 23:30: Subject: `| and order on arrays
In code I write I make a conscious effort to arrange orders in arrays to be able to use a += ({17}) instead of a = ({17}) + a. In other code I also see constructs of the first kind far more often than the second. Do you really have the opposite perception of the situation?
All you have to do is put the "main data collection" to the right, and the "change" to the left, and you will get this.
No. Then I had to reverse the main collection both before and after the operation, or else start replacing the use of a += ({17}) with the both clumsier and slower a = ({17}) + a everywhere else.
/ Martin Stjernholm, Roxen IS
That's what the documentation states, anyway.
http://pike.ida.liu.se/generated/manual/ref/chapter_4.html#4:
When intersection, union or symmetric difference is used on an array each element in the array is considered by itself. So intersecting two arrays will result in an array with all elements that are present in both arrays. Example: ({7,6,4,3,2,1}) & ({1, 23, 5, 4, 7}) will return ({7,4,1}). The order of the elements in the returned array will always be taken from the left array.
...but it's been broken for ages. Those who want a workaround can use a + (b - a) instead of a | b but I'd rather see the bug fixed.
(While looking through the module reference for `| I also noticed that it incorrectly says that it performs _concatenation_ if the arguments are arrays.)
/ Jonas Walldén
Previous text:
2002-12-03 19:06: Subject: `| and order on arrays
I thought `| should keep the order when used on arrays:
Pike v7.3 release 62 running Hilfe v3.5 (Incremental Pike Frontend)
({1,2,3}) | ({2,4,1,17});
(1) Result: ({ /* 5 elements */ 3, 2, 4, 1, 17 })
Looks like it keeps the order in the second array, but the remaining elements in the first are swapped in this case. I furthermore expected the elements in the first array to remain unchanged with precedence over those in the second, since that makes it behave more consistently when used as |=, in which case all the elements in the left operand would remain on the same indices.
Wasn't this discussed and supposedly fixed some time ago (half a year or so)?
/ Martin Stjernholm, Roxen IS
I noticed that there's a test case in the testsuite that seemingly explicitly tests that the order in the right operand takes precedence in |:
test_equal( ({1,2,3,4,4}) | ({3,5,6}), ({1,2,4,4,3,5,6}))
Even so I'd like to change it, partly for the reasons I've given elsewhere in this comment tree, partly for consistency with &, which just as the manual says takes the order from the left operand.
The test was changed to this by Hubbe on October 3rd 1999 with the comment "operator fixes (I hope)". Does anyone remember any preceding discussion about it?
/ Martin Stjernholm, Roxen IS
Previous text:
2002-12-03 22:51: Subject: `| and order on arrays
That's what the documentation states, anyway.
http://pike.ida.liu.se/generated/manual/ref/chapter_4.html#4:
When intersection, union or symmetric difference is used on an array each element in the array is considered by itself. So intersecting two arrays will result in an array with all elements that are present in both arrays. Example: ({7,6,4,3,2,1}) & ({1, 23, 5, 4, 7}) will return ({7,4,1}). The order of the elements in the returned array will always be taken from the left array.
...but it's been broken for ages. Those who want a workaround can use a + (b - a) instead of a | b but I'd rather see the bug fixed.
(While looking through the module reference for `| I also noticed that it incorrectly says that it performs _concatenation_ if the arguments are arrays.)
/ Jonas Walldén
pike-devel@lists.lysator.liu.se