Thread: Re: [GD-Windows] Array foreach in scripting languages
Brought to you by:
vexxed72
From: Carsten O. <car...@se...> - 2006-08-13 06:08:39
|
The reason I'd like to have this work is that it is a recurring pattern in lots of code I see (iterating a list and deleting/inserting entries). =20 If I go the route with tracked iterators, any insert or delete operation will work as expected since then I'm dealing with these cases per iterator: =20 - delete item before or at current position -> decrement position and size - delete item after current position -> decrement size - insert item before or at current position -> increment position and size - insert item after current position -> increment size =20 The case "delete item at current position" potentially has to deal with the actual element being deleted. In C++ this would be a problem but in my scripting language the list entry would go away but the actual value referenced will stay around due the iterator still holding onto it. =20 I'm quite surprised that the C# docs don't even mention this situation. I'm even more surprised to find that MS added a "for each" to C++. It's supposed to be only for managed code but it worked fine in my standard STL unmanaged test. =20 Simply banning this scenario would mean that users have to write such code: =20 int i,iC=3DList.GetSize(); for(i=3D0;i<iC;i++) { if(Condition(List[i])) { List.Delete(i); i--;iC--; } }; =20 manually. Which is goes against the whole idea of pro- viding a foreach and IMHO even more error-prone. I'm not sure if I more dislike the C#/STL behaviour of throwing an exception or the Python behaviour of simply ignoring the problem. =20 <rant> In my case, an exception is not an option since I'm not going to clutter my cute little scripting language with a concept (exceptions) that I consider totally broken in the first place. There's no place in a game for such stuff. It has to run, period. So you have to handle all error conditions anyway. </rant> =20 Best regards, =20 Carsten Orthbandt Founder + Development Director SEK SpieleEntwicklungsKombinat GmbH http://www.sek-ost.de Wenn ich Visionen habe, gehe ich zum Arzt. - Helmut Schmidt =20 =20 ________________________________ Von: gam...@li... im Auftrag von = Kent Quirk Gesendet: So 13.08.2006 04:39 An: Game Development for MS Windows Betreff: Re: [GD-Windows] Array foreach in scripting languages In Python, I was shocked to find that this succeeds: L =3D range(20) for i in L: print i if i=3D=3D4: del L[6] Result: ------- 0 1 2 3 4 5 7 8 9 I fully expected it to fail. I consider messing with the list you're traversing with an iterator to be on a par with sawing off the branch you're standing on, unless, as you imply, the list is known to be implemented as a linked list. In python, you can surprise yourself. Consider this: for i in L: print i if i=3D=3D4: del L[3] # delete one of the items BEFORE the one you're = on =20 0 1 2 3 4 6 7 8 9 So what happened is that we ended up skipping element #5, even though we deleted element 3. This is really dependent on the implementation details of the particular interpreter, and probably isn't guaranteed by the average language spec. If you feel strongly about being able to do this, you have to deal with the case of deleting the item you're on right now, and also about deleting the last element while you're at the last element. Check this = out: >>> L ['h', 'e', 'l', 'l', 'o'] >>> for c in L: if c=3D=3D'l': L.remove(c) >>> L ['h', 'e', 'l', 'o'] In other words, even though I intended to remove BOTH 'l' characters, only one of them was removed because deleting one caused me to skip the next element. I think this stuff is so fraught with potential errors by the user, even if YOU get it right, that I'd prefer to just ban the practice and make people use a "filter" concept like in python, or a remove_if as in STL. Kent Carsten Orthbandt wrote: > I'm currently building a small scripting language for interactive = stuff. Now I > know there's plenty out there, I'm just doing this for fun. >=20 > A tricky question came up and I'd like to collect opinions and = experiences on > this. It's about foreach for dynamic arrays. Consider this C++-like = pseudo code: >=20 > DynamicArray<int> list; > int i; > for(i=3D0;i<20;i++){list.Add(i);}; > foreach(i in list){ > print(i); > if(i=3D=3D8){list.Delete(12);}; > }; >=20 > The obvious question is how should an active iterator react if the = traversed list > changes? To answer this, I simply tried it out in two languages I know = that do > provide both dynamic arrays and foreach: STL, Tcl and C#. >=20 > In STL C++ code, I get an exception because of iterator = incompatibility. > In Tcl this problem isn't one because the iterator takes a snapshot of = the list > object on start and there's no language construct to actually change = this instance. > In C# with the List<int> generic, I get an exception because the = iterated object > changes (interestingly, this happens on ANY change to the list, even = appending). >=20 > Now what I'd like to know: > - how do other languages cope with this? (Tcl doesn't need to, C++/C# = simply fails) > - what do YOU think would be sensible behaviour? >=20 > Currently I'm considering having all iterators be elements of a = double-linked list > and let the array object be the dl-list head. So if the number of = array elements > changes, it can run through all attached iterators and fix their = indices or stop them. >=20 > =20 -------------------------------------------------------------------------= Using Tomcat but need to do more? Need to support web services, = security? Get stuff done quickly with pre-integrated technology to make your job = easier Download IBM WebSphere Application Server v.1.0.1 based on Apache = Geronimo http://sel.as-us.falkag.net/sel?cmd=3Dlnk&kid=3D120709&bid=3D263057&dat=3D= 121642 _______________________________________________ Gamedevlists-windows mailing list Gam...@li... https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows Archives: http://sourceforge.net/mailarchive/forum.php?forum_id=3D555 |
From: Carsten O. <car...@se...> - 2006-08-13 11:25:24
|
I'm afraid I wasn't clear. The actual data structure of the list or array may be anything. In the case at hand, it is not a linked list. The linked list I was referring to would be a linked list of all iterators attached to a specific array instance specifically for adjusting the iterators on list changes. So yes, that's what I was about to do. Modifying arrays poses some serious challenges for multi-threaded operation anyway, I don't think it's getting much harder with this iterator scheme in place. I was planning to do heavy multi-threading through thread pools and task lists that operate in higher level chunks as to not spend to much time on the threading itself. =20 Best regards, =20 Carsten Orthbandt Founder + Development Director SEK SpieleEntwicklungsKombinat GmbH http://www.sek-ost.de Wenn ich Visionen habe, gehe ich zum Arzt. - Helmut Schmidt =20 =20 ________________________________ Von: gam...@li... im Auftrag von = Richard Fabian Gesendet: So 13.08.2006 12:13 An: Game Development for MS Windows Betreff: Re: [GD-Windows] Array foreach in scripting languages Dunno if it suits how you work, but you could always attach the = iterators to the linked list on iterator construction. this way you can tell all the currently attached iterators that element = X is gone, handle it. with thiis in place, we've never had any problems with our iterators, = but i suspect that we may have problems in the future with PS3 and such = because this technique doesn't lend itself to threaded access. On 8/13/06, Carsten Orthbandt <car...@se...> wrote:=20 The reason I'd like to have this work is that it is a recurring pattern in lots of code I see (iterating a list and deleting/inserting entries). =09 If I go the route with tracked iterators, any insert or delete operation will work as expected since then=20 I'm dealing with these cases per iterator: =09 - delete item before or at current position -> decrement position and size - delete item after current position -> decrement size - insert item before or at current position=20 -> increment position and size - insert item after current position -> increment size =09 The case "delete item at current position" potentially has to deal with the actual element being deleted.=20 In C++ this would be a problem but in my scripting language the list entry would go away but the actual value referenced will stay around due the iterator still holding onto it. =09 I'm quite surprised that the C# docs don't even mention=20 this situation. I'm even more surprised to find that MS added a "for each" to C++. It's supposed to be only for managed code but it worked fine in my standard STL unmanaged test. =09 Simply banning this scenario would mean that users have=20 to write such code: =09 int i,iC=3DList.GetSize(); for(i=3D0;i<iC;i++) { if(Condition(List[i])) { List.Delete(i); i--;iC--; } }; =09 manually. Which is goes against the whole idea of pro-=20 viding a foreach and IMHO even more error-prone. I'm not sure if I more dislike the C#/STL behaviour of throwing an exception or the Python behaviour of simply ignoring the problem. =09 <rant> In my case, an exception is not an option since I'm not=20 going to clutter my cute little scripting language with a concept (exceptions) that I consider totally broken in the first place. There's no place in a game for such stuff. It has to run, period. So you have to handle all=20 error conditions anyway. </rant> =09 Best regards, =09 Carsten Orthbandt Founder + Development Director SEK SpieleEntwicklungsKombinat GmbH http://www.sek-ost.de=20 =09 Wenn ich Visionen habe, gehe ich zum Arzt. - Helmut Schmidt =09 =09 =09 ________________________________ =09 Von: gam...@li... im Auftrag von = Kent Quirk Gesendet: So 13.08.2006 04:39 An: Game Development for MS Windows Betreff: Re: [GD-Windows] Array foreach in scripting languages =09 =09 =09 In Python, I was shocked to find that this succeeds:=20 =09 L =3D range(20) for i in L: print i if i=3D=3D4: del L[6] =09 Result: ------- 0 1 2 3 4 5 7 8 9 =09 I fully expected it to fail. I consider messing with the list you're=20 traversing with an iterator to be on a par with sawing off the branch you're standing on, unless, as you imply, the list is known to be implemented as a linked list. In python, you can surprise yourself. Consider this:=20 =09 for i in L: print i if i=3D=3D4: del L[3] # delete one of the items BEFORE the one you're = on =09 =09 0 1 2 3 4 6 7 8 9 =09 So what happened is that we ended up skipping element #5, even though = we=20 deleted element 3. =09 This is really dependent on the implementation details of the = particular interpreter, and probably isn't guaranteed by the average language = spec. =09 If you feel strongly about being able to do this, you have to deal with = the case of deleting the item you're on right now, and also about deleting the last element while you're at the last element. Check this = out: =09 >>> L ['h', 'e', 'l', 'l', 'o'] >>> for c in L:=20 if c=3D=3D'l': L.remove(c) =09 >>> L ['h', 'e', 'l', 'o'] =09 In other words, even though I intended to remove BOTH 'l' characters, only one of them was removed because deleting one caused me to skip the = next element. =09 I think this stuff is so fraught with potential errors by the user, = even if YOU get it right, that I'd prefer to just ban the practice and make people use a "filter" concept like in python, or a remove_if as in STL. = =09 Kent =09 =09 Carsten Orthbandt wrote: > I'm currently building a small scripting language for interactive = stuff. Now I > know there's plenty out there, I'm just doing this for fun. > > A tricky question came up and I'd like to collect opinions and = experiences on=20 > this. It's about foreach for dynamic arrays. Consider this C++-like = pseudo code: > > DynamicArray<int> list; > int i; > for(i=3D0;i<20;i++){list.Add(i);}; > foreach(i in list){=20 > print(i); > if(i=3D=3D8){list.Delete(12);}; > }; > > The obvious question is how should an active iterator react if the = traversed list > changes? To answer this, I simply tried it out in two languages I = know that do=20 > provide both dynamic arrays and foreach: STL, Tcl and C#. > > In STL C++ code, I get an exception because of iterator = incompatibility. > In Tcl this problem isn't one because the iterator takes a snapshot = of the list=20 > object on start and there's no language construct to actually change = this instance. > In C# with the List<int> generic, I get an exception because the = iterated object > changes (interestingly, this happens on ANY change to the list, even = appending).=20 > > Now what I'd like to know: > - how do other languages cope with this? (Tcl doesn't need to, C++/C# = simply fails) > - what do YOU think would be sensible behaviour? > > Currently I'm considering having all iterators be elements of a = double-linked list=20 > and let the array object be the dl-list head. So if the number of = array elements > changes, it can run through all attached iterators and fix their = indices or stop them. > > =09 =09 = -------------------------------------------------------------------------= =20 Using Tomcat but need to do more? Need to support web services, = security? Get stuff done quickly with pre-integrated technology to make your job = easier Download IBM WebSphere Application Server v.1.0.1 based on Apache = Geronimo=20 = http://sel.as-us.falkag.net/sel?cmd=3Dlnk&kid=3D120709&bid=3D263057&dat=3D= 121642 _______________________________________________=20 Gamedevlists-windows mailing list Gam...@li... https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows Archives: http://sourceforge.net/mailarchive/forum.php?forum_id=3D555 =09 =09 =09 = -------------------------------------------------------------------------= Using Tomcat but need to do more? Need to support web services, = security? Get stuff done quickly with pre-integrated technology to make your job = easier=20 Download IBM WebSphere Application Server v.1.0.1 based on Apache = Geronimo = http://sel.as-us.falkag.net/sel?cmd=3Dlnk&kid=3D120709&bid=3D263057&dat=3D= 121642=20 _______________________________________________ Gamedevlists-windows mailing list Gam...@li... https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows Archives: http://sourceforge.net/mailarchive/forum.php?forum_id=3D555 =09 --=20 fabs();=20 |
From: Mat N. \(BUNGIE\) <Mat...@mi...> - 2006-08-13 19:00:29
|
If it's a scripting language, don't allow direct manipulation of a = container while iterating through it. =20 If you want the side effects of such an operation, defer them until all = iterators have been destroyed. =20 MSN ________________________________ From: gam...@li... on behalf of = Carsten Orthbandt Sent: Sun 8/13/2006 4:21 AM To: Game Development for MS Windows Subject: Re: [GD-Windows] Array foreach in scripting languages I'm afraid I wasn't clear. The actual data structure of the list or array may be anything. In the case at hand, it is not a linked list. The linked list I was referring to would be a linked list of all iterators attached to a specific array instance specifically for adjusting the iterators on list changes. So yes, that's what I was about to do. Modifying arrays poses some serious challenges for multi-threaded operation anyway, I don't think it's getting much harder with this iterator scheme in place. I was planning to do heavy multi-threading through thread pools and task lists that operate in higher level chunks as to not spend to much time on the threading itself. Best regards, Carsten Orthbandt Founder + Development Director SEK SpieleEntwicklungsKombinat GmbH http://www.sek-ost.de <http://www.sek-ost.de/>=20 Wenn ich Visionen habe, gehe ich zum Arzt. - Helmut Schmidt =20 ________________________________ Von: gam...@li... im Auftrag von = Richard Fabian Gesendet: So 13.08.2006 12:13 An: Game Development for MS Windows Betreff: Re: [GD-Windows] Array foreach in scripting languages Dunno if it suits how you work, but you could always attach the = iterators to the linked list on iterator construction. this way you can tell all the currently attached iterators that element = X is gone, handle it. with thiis in place, we've never had any problems with our iterators, = but i suspect that we may have problems in the future with PS3 and such = because this technique doesn't lend itself to threaded access. On 8/13/06, Carsten Orthbandt <car...@se...> wrote: The reason I'd like to have this work is that it is a recurring pattern in lots of code I see (iterating a list and deleting/inserting entries). =20 If I go the route with tracked iterators, any insert or delete operation will work as expected since then I'm dealing with these cases per iterator: =20 - delete item before or at current position -> decrement position and size - delete item after current position -> decrement size - insert item before or at current position -> increment position and size - insert item after current position -> increment size =20 The case "delete item at current position" potentially has to deal with the actual element being deleted. In C++ this would be a problem but in my scripting language the list entry would go away but the actual value referenced will stay around due the iterator still holding onto it. =20 I'm quite surprised that the C# docs don't even mention this situation. I'm even more surprised to find that MS added a "for each" to C++. It's supposed to be only for managed code but it worked fine in my standard STL unmanaged test. =20 Simply banning this scenario would mean that users have to write such code: =20 int i,iC=3DList.GetSize(); for(i=3D0;i<iC;i++) { if(Condition(List[i])) { List.Delete(i); i--;iC--; } }; =20 manually. Which is goes against the whole idea of pro- viding a foreach and IMHO even more error-prone. I'm not sure if I more dislike the C#/STL behaviour of throwing an exception or the Python behaviour of simply ignoring the problem. =20 <rant> In my case, an exception is not an option since I'm not going to clutter my cute little scripting language with a concept (exceptions) that I consider totally broken in the first place. There's no place in a game for such stuff. It has to run, period. So you have to handle all error conditions anyway. </rant> =20 Best regards, =20 Carsten Orthbandt Founder + Development Director SEK SpieleEntwicklungsKombinat GmbH http://www.sek-ost.de <http://www.sek-ost.de/>=20 =20 Wenn ich Visionen habe, gehe ich zum Arzt. - Helmut Schmidt =20 =20 =20 ________________________________ =20 Von: gam...@li... im = Auftrag von Kent Quirk Gesendet: So 13.08.2006 04:39 An: Game Development for MS Windows Betreff: Re: [GD-Windows] Array foreach in scripting languages =20 =20 =20 In Python, I was shocked to find that this succeeds: =20 L =3D range(20) for i in L: print i if i=3D=3D4: del L[6] =20 Result: ------- 0 1 2 3 4 5 7 8 9 =20 I fully expected it to fail. I consider messing with the list = you're traversing with an iterator to be on a par with sawing off the = branch you're standing on, unless, as you imply, the list is known to = be implemented as a linked list. In python, you can surprise = yourself. Consider this: =20 for i in L: print i if i=3D=3D4: del L[3] # delete one of the items BEFORE the one = you're on =20 =20 0 1 2 3 4 6 7 8 9 =20 So what happened is that we ended up skipping element #5, even = though we deleted element 3. =20 This is really dependent on the implementation details of the = particular interpreter, and probably isn't guaranteed by the average = language spec. =20 If you feel strongly about being able to do this, you have to = deal with the case of deleting the item you're on right now, and also = about deleting the last element while you're at the last element. = Check this out: =20 >>> L ['h', 'e', 'l', 'l', 'o'] >>> for c in L: if c=3D=3D'l': L.remove(c) =20 >>> L ['h', 'e', 'l', 'o'] =20 In other words, even though I intended to remove BOTH 'l' = characters, only one of them was removed because deleting one caused me to = skip the next element. =20 I think this stuff is so fraught with potential errors by the = user, even if YOU get it right, that I'd prefer to just ban the practice = and make people use a "filter" concept like in python, or a remove_if as = in STL. =20 Kent =20 =20 Carsten Orthbandt wrote: > I'm currently building a small scripting language for = interactive stuff. Now I > know there's plenty out there, I'm just doing this for fun. > > A tricky question came up and I'd like to collect opinions and = experiences on > this. It's about foreach for dynamic arrays. Consider this = C++-like pseudo code: > > DynamicArray<int> list; > int i; > for(i=3D0;i<20;i++){list.Add(i);}; > foreach(i in list){ > print(i); > if(i=3D=3D8){list.Delete(12);}; > }; > > The obvious question is how should an active iterator react if = the traversed list > changes? To answer this, I simply tried it out in two = languages I know that do > provide both dynamic arrays and foreach: STL, Tcl and C#. > > In STL C++ code, I get an exception because of iterator = incompatibility. > In Tcl this problem isn't one because the iterator takes a = snapshot of the list > object on start and there's no language construct to actually = change this instance. > In C# with the List<int> generic, I get an exception because = the iterated object > changes (interestingly, this happens on ANY change to the = list, even appending). > > Now what I'd like to know: > - how do other languages cope with this? (Tcl doesn't need to, = C++/C# simply fails) > - what do YOU think would be sensible behaviour? > > Currently I'm considering having all iterators be elements of = a double-linked list > and let the array object be the dl-list head. So if the number = of array elements > changes, it can run through all attached iterators and fix = their indices or stop them. > > =20 =20 = -------------------------------------------------------------------------= Using Tomcat but need to do more? Need to support web services, = security? Get stuff done quickly with pre-integrated technology to make = your job easier Download IBM WebSphere Application Server v.1.0.1 based on = Apache Geronimo = http://sel.as-us.falkag.net/sel?cmd=3Dlnk&kid=3D120709&bid=3D263057&dat=3D= 121642 _______________________________________________ Gamedevlists-windows mailing list Gam...@li... = https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows Archives: http://sourceforge.net/mailarchive/forum.php?forum_id=3D555 =20 =20 =20 = -------------------------------------------------------------------------= Using Tomcat but need to do more? Need to support web services, = security? Get stuff done quickly with pre-integrated technology to make = your job easier Download IBM WebSphere Application Server v.1.0.1 based on = Apache Geronimo = http://sel.as-us.falkag.net/sel?cmd=3Dlnk&kid=3D120709&bid=3D263057&dat=3D= 121642 _______________________________________________ Gamedevlists-windows mailing list Gam...@li... = https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows Archives: http://sourceforge.net/mailarchive/forum.php?forum_id=3D555 =20 -- fabs(); -------------------------------------------------------------------------= Using Tomcat but need to do more? Need to support web services, = security? Get stuff done quickly with pre-integrated technology to make your job = easier Download IBM WebSphere Application Server v.1.0.1 based on Apache = Geronimo http://sel.as-us.falkag.net/sel?cmd=3Dlnk&kid=3D120709&bid=3D263057&dat=3D= 121642 _______________________________________________ Gamedevlists-windows mailing list Gam...@li... https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows Archives: http://sourceforge.net/mailarchive/forum.php?forum_id=3D555 |
From: Richard F. <ra...@de...> - 2006-08-13 20:39:43
|
On 8/13/06, Carsten Orthbandt <car...@se...> wrote: > > I'm afraid I wasn't clear. The actual data structure of the list > or array may be anything. In the case at hand, it is not a linked > list. for the sake of one word difference ;) "but you could always attach the iterators to the linked list on iterator construction." "but you could always attach the iterators to a linked list on iterator construction." hehe The linked list I was referring to would be a linked list > of all iterators attached to a specific array instance specifically > for adjusting the iterators on list changes. So yes, that's what > I was about to do. yes, this is what we do. Modifying arrays poses some serious challenges for multi-threaded > operation anyway, I don't think it's getting much harder with this > iterator scheme in place. I was planning to do heavy multi-threading > through thread pools and task lists that operate in higher level > chunks as to not spend to much time on the threading itself. My impression of working multi-threaded has been that we have to stop hoping, and start proactivley ensuring. I agree with Mat Noguchi, we should really dissallow the modification of any containers contents while we are iterating them. We used to do it this way in our scheduler, and may return to it once we start fulltime development on the next gen platforms. -- fabs(); |
From: Carsten O. <car...@se...> - 2006-08-14 05:50:07
|
I tested this with both, my DynamicArray and std::vector. Since we're talking about a scripting language here, the actual implementation doesn't matter. It can be alinked list, contigous memory block, hashmap, whatever. Simply think of it as a resizeable array. As stated before, even the case where the current element gets removed from the list can be handled correctly because I can control the real lifetime of any object. So if the current element is removed in the foreach, there's still a reference to it from the iterator. Therefor it won't be freed immediately. Best regards, Carsten Orthbandt Founder + Development Director SEK SpieleEntwicklungsKombinat GmbH http://www.sek-ost.de Wenn ich Visionen habe, gehe ich zum Arzt. - Helmut Schmidt =20 > -----Original Message----- > From: gam...@li...=20 > [mailto:gam...@li...]=20 > On Behalf Of Jon Watte > Sent: Sunday, August 13, 2006 10:05 PM > To: Game Development for MS Windows > Subject: Re: [GD-Windows] Array foreach in scripting languages >=20 > What's confusing is that your code uses the name DynamicArray=20 > (which I=20 > suppose is close to ArrayList in .NET), and your C++ test sample=20 > probably used std::vector, but you keep referring to the=20 > container as a=20 > "list". They are very different kinds of containers. >=20 > You will note that C++ allows you to insert and delete objects in a=20 > std::list, but not in a std::vector. The reason is that vectors are=20 > guaranteed to be contiguous, and thus iterators (which may be simple=20 > pointers) would get invalidated when resizing the underlying storage.=20 > Meanwhile, when deleting from a list, the only iterator that gets=20 > invalidated is an iterator pointing to the element being deleted. >=20 > Cheers, >=20 > / h+ >=20 >=20 > Carsten Orthbandt wrote: > > The obvious question is how should an active iterator react=20 > if the traversed list > > changes? To answer this, I simply tried it out in two=20 > languages I know that do > > provide both dynamic arrays and foreach: STL, Tcl and C#. > > =20 >=20 >=20 >=20 > -------------------------------------------------------------- > ----------- > Using Tomcat but need to do more? Need to support web=20 > services, security? > Get stuff done quickly with pre-integrated technology to make=20 > your job easier > Download IBM WebSphere Application Server v.1.0.1 based on=20 > Apache Geronimo > http://sel.as-us.falkag.net/sel?cmd=3Dlnk&kid=3D120709&bid=3D263057& > dat=3D121642 > _______________________________________________ > Gamedevlists-windows mailing list > Gam...@li... > https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows > Archives: > http://sourceforge.net/mailarchive/forum.php?forum_id=3D555 >=20 |
From: Jon W. <hp...@mi...> - 2006-08-14 17:15:43
|
Carsten Orthbandt wrote: > I tested this with both, my DynamicArray and std::vector. > Since we're talking about a scripting language here, the > actual implementation doesn't matter. It can be alinked > list, contigous memory block, hashmap, whatever. > The actual implementation DOES matter, because std::list<> makes the guarantee that you can delete items ahead of, or behind, the current iterator, without ill effects. An array, on the other hand, explicitly forbids that practice. Thus, depending on which semantic you prefer to expose, you should choose one, or the other. That's one of the reasons that C++ defines both data types, and lets the programmer decide. In the case where you're using a data type that invalidates iterators, I suggest that you (at least in debug mode) detect the invalid iterator and assert out on first use. The sooner you detect potentially invalid usage, the better. Cheers, / h+ |
From: Richard F. <ra...@de...> - 2006-08-13 10:13:49
|
Dunno if it suits how you work, but you could always attach the iterators to the linked list on iterator construction. this way you can tell all the currently attached iterators that element X is gone, handle it. with thiis in place, we've never had any problems with our iterators, but i suspect that we may have problems in the future with PS3 and such because this technique doesn't lend itself to threaded access. On 8/13/06, Carsten Orthbandt <car...@se...> wrote: > > The reason I'd like to have this work is that it is a > recurring pattern in lots of code I see (iterating a > list and deleting/inserting entries). > > If I go the route with tracked iterators, any insert > or delete operation will work as expected since then > I'm dealing with these cases per iterator: > > - delete item before or at current position > -> decrement position and size > - delete item after current position > -> decrement size > - insert item before or at current position > -> increment position and size > - insert item after current position > -> increment size > > The case "delete item at current position" potentially > has to deal with the actual element being deleted. > In C++ this would be a problem but in my scripting > language the list entry would go away but the actual > value referenced will stay around due the iterator > still holding onto it. > > I'm quite surprised that the C# docs don't even mention > this situation. I'm even more surprised to find that MS > added a "for each" to C++. It's supposed to be only for > managed code but it worked fine in my standard STL > unmanaged test. > > Simply banning this scenario would mean that users have > to write such code: > > int i,iC=List.GetSize(); > for(i=0;i<iC;i++) > { > if(Condition(List[i])) > { > List.Delete(i); > i--;iC--; > } > }; > > manually. Which is goes against the whole idea of pro- > viding a foreach and IMHO even more error-prone. > I'm not sure if I more dislike the C#/STL behaviour of > throwing an exception or the Python behaviour of simply > ignoring the problem. > > <rant> > In my case, an exception is not an option since I'm not > going to clutter my cute little scripting language with > a concept (exceptions) that I consider totally broken > in the first place. There's no place in a game for such > stuff. It has to run, period. So you have to handle all > error conditions anyway. > </rant> > > Best regards, > > Carsten Orthbandt > Founder + Development Director > SEK SpieleEntwicklungsKombinat GmbH > http://www.sek-ost.de > > Wenn ich Visionen habe, gehe ich zum Arzt. - Helmut Schmidt > > > > ________________________________ > > Von: gam...@li... im Auftrag von > Kent Quirk > Gesendet: So 13.08.2006 04:39 > An: Game Development for MS Windows > Betreff: Re: [GD-Windows] Array foreach in scripting languages > > > > In Python, I was shocked to find that this succeeds: > > L = range(20) > for i in L: > print i > if i==4: > del L[6] > > Result: > ------- > 0 > 1 > 2 > 3 > 4 > 5 > 7 > 8 > 9 > > I fully expected it to fail. I consider messing with the list you're > traversing with an iterator to be on a par with sawing off the branch > you're standing on, unless, as you imply, the list is known to be > implemented as a linked list. In python, you can surprise yourself. > Consider this: > > for i in L: > print i > if i==4: > del L[3] # delete one of the items BEFORE the one you're on > > > 0 > 1 > 2 > 3 > 4 > 6 > 7 > 8 > 9 > > So what happened is that we ended up skipping element #5, even though we > deleted element 3. > > This is really dependent on the implementation details of the particular > interpreter, and probably isn't guaranteed by the average language spec. > > If you feel strongly about being able to do this, you have to deal with > the case of deleting the item you're on right now, and also about > deleting the last element while you're at the last element. Check this > out: > > >>> L > ['h', 'e', 'l', 'l', 'o'] > >>> for c in L: > if c=='l': > L.remove(c) > > >>> L > ['h', 'e', 'l', 'o'] > > In other words, even though I intended to remove BOTH 'l' characters, > only one of them was removed because deleting one caused me to skip the > next element. > > I think this stuff is so fraught with potential errors by the user, even > if YOU get it right, that I'd prefer to just ban the practice and make > people use a "filter" concept like in python, or a remove_if as in STL. > > Kent > > > Carsten Orthbandt wrote: > > I'm currently building a small scripting language for interactive stuff. > Now I > > know there's plenty out there, I'm just doing this for fun. > > > > A tricky question came up and I'd like to collect opinions and > experiences on > > this. It's about foreach for dynamic arrays. Consider this C++-like > pseudo code: > > > > DynamicArray<int> list; > > int i; > > for(i=0;i<20;i++){list.Add(i);}; > > foreach(i in list){ > > print(i); > > if(i==8){list.Delete(12);}; > > }; > > > > The obvious question is how should an active iterator react if the > traversed list > > changes? To answer this, I simply tried it out in two languages I know > that do > > provide both dynamic arrays and foreach: STL, Tcl and C#. > > > > In STL C++ code, I get an exception because of iterator incompatibility. > > In Tcl this problem isn't one because the iterator takes a snapshot of > the list > > object on start and there's no language construct to actually change > this instance. > > In C# with the List<int> generic, I get an exception because the > iterated object > > changes (interestingly, this happens on ANY change to the list, even > appending). > > > > Now what I'd like to know: > > - how do other languages cope with this? (Tcl doesn't need to, C++/C# > simply fails) > > - what do YOU think would be sensible behaviour? > > > > Currently I'm considering having all iterators be elements of a > double-linked list > > and let the array object be the dl-list head. So if the number of array > elements > > changes, it can run through all attached iterators and fix their indices > or stop them. > > > > > > > ------------------------------------------------------------------------- > Using Tomcat but need to do more? Need to support web services, security? > Get stuff done quickly with pre-integrated technology to make your job > easier > Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 > _______________________________________________ > Gamedevlists-windows mailing list > Gam...@li... > https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows > Archives: > http://sourceforge.net/mailarchive/forum.php?forum_id=555 > > > > ------------------------------------------------------------------------- > Using Tomcat but need to do more? Need to support web services, security? > Get stuff done quickly with pre-integrated technology to make your job > easier > Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 > _______________________________________________ > Gamedevlists-windows mailing list > Gam...@li... > https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows > Archives: > http://sourceforge.net/mailarchive/forum.php?forum_id=555 > -- fabs(); |
From: Alen L. <ale...@cr...> - 2006-08-14 20:45:47
|
> The reason I'd like to have this work is that it is a > recurring pattern in lots of code I see (iterating a > list and deleting/inserting entries). In my experience, rather than trying to get the "modification of the list while walking it" right, it is much easier to instead just change the algorithm slightly to work by rewriting the input list into an output list. Simple and fool-proof. And for a scripting language, it should be a very useable solution. Cheers, Alen |