In version 10.4.1 (Win 7 Ent) I am implementing an algorithm that needs to update a list after each pass. I initially coded this with Nothing by removing items in the list that where no longer needed after each processing pass. This did not result in the expected outcome and I eventually sourced the error to the use of Nothing. A very minimal example follows.
SeedRandom[19384];
datN = RandomInteger[{1, 5}, 10]
(* {2, 1, 3, 5, 1, 2, 5, 2, 2, 2} *)
For this minimal example FirstPosition[5]@datN will represent the index of the item that needs to be removed after each processing pass. (I'm not trying to delete all 5's in the real code.) There are two 5's. I would expect the first in position 4 to be removed at the end of the first pass.
datN[[Echo@First@FirstPosition[5]@datN]] = Nothing;
datN
>> 4
(* {2, 1, 3, 1, 2, 5, 2, 2, 2} *)
Success! The first pass finds the first 5, removes it, and updates datN. Or does it? Lets try the second pass which should remove the 5 in position 6.
datN[[Echo@First@FirstPosition[5]@datN]] = Nothing;
datN
>> 6
(* {2, 1, 3, 1, 5, 2, 2, 2} *)
What has happened here? The correct position of 6 was identified but instead of removing the 5 there it removed the 2 in position 5. Let us try one more time to remove the 5 now in position 5.
datN[[Echo@First@FirstPosition[5]@datN]] = Nothing;
datN
>> 5
(* {2, 1, 3, 5, 2, 2, 2} *)
It has done it again. The correct position of 5 has been identified but the 1 in position 4 has been removed instead.
Now it gets interesting. On the fourth try and every subsequent try after the fourth it simply refuses to remove anything.
datN[[Echo@First@FirstPosition[5]@datN]] = Nothing;
datN
>> 4
(* {2, 1, 3, 5, 2, 2, 2} *)
The output above will repeat with the datN never being altered from the forth try onwards. Very odd.
Have I completely missed something or is this a bug? If so, is it still around in version 11?
Update
Clearly I have to live with it as it is. However, at this moment, I don't feel it is intuitively correct. I would understand the hold behavior if I used SetDelayed but having used Set it seems a reasonable expectation that the Nothings be removed. At least I understand its mechanism. I am dating myself a bit here but I was expecting a ReDim Preserve type of behavior. 10 Internet points to anyone that gets that reference without looking it up.
datNwas a5, that is alreadyNothingnow. – Karsten7 Aug 15 '16 at 21:56Trace[datN[[Echo@First@FirstPosition[5]@datN]] = Nothing, TraceInternal -> True]after doing all these steps. There is a{2, 1, 3, Nothing, Nothing, Nothing, 5, 2, 2, 2}in it. – Karsten7 Aug 15 '16 at 22:03Nothingin the documentation.Nothingshould be removed fromList.datNis a list. In addition, there are noHold*attributes ondatN. – Edmund Aug 15 '16 at 22:07datNis neither held nor inactive. – Edmund Aug 15 '16 at 22:13datNin your code is modified in place without evaluation of the whole struct. Hence it is actually held unevaluated! – Alexey Popkov Aug 15 '16 at 22:16Set, notSetDelayed. – Edmund Aug 15 '16 at 22:18Nothing. This question will remain as a guidepost, but if desirable someone may wish to edit the original question to includeNothingas well. – Mr.Wizard Aug 15 '16 at 22:28