You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There are a number of places in our model of games where we have collections of objects. For example, we have the collection of information sets belonging to a player, or the collection of outcomes possible in the game.
We have to date allowed indexing these by integers so they are somewhat list-like. However, this poses the following issues:
We also allow indexing by text labels, and in our new model for games labels play a more important role. It is awkward for __getitem__ to allow two different modes of indexing; it means these collections are somewhat list-like and somewhat dict-like, which can be argued is a dubious design.
Indexing by integer is an implementation detail. For example, it so happens that we sort information sets in the order they are encountered in depth-first preorder traversal of an extensive game. While having such a canonical ordering is useful, in a general game model it might be impractical at best to ensure this (for example if we do not materialise a representation as physical objects in memory). So these are indeed more set-like objects. (Note that we have typically been careful to refer to these as "collections" of objects to avoid unintended identification with a specific model of list, dict, or set.)
We do not use this integer indexing (much?) in the more recent examples we have developed. There are a number of examples of this in the test suite among functions which were written very early in the development of pygambit. To pull out one at random, we have this function:
Perhaps what jumps out most from this is that it's actually quite opaque what this code even does! Rather than talking about information set 0 of each player, it would be much more clear and expressive to write this in terms of a member of the information set we are interested in. A (somewhat) casual survey of the test suite suggests that most of the uses of indexing by integers into collections could profitably be re-written similarly in a more expressive way, that actually makes the tests more meaningful as well.
We also propose that while this is a breaking change, we would strongly consider incorporating this into version 16.7 rather than just having a deprecation warning.
At the risk of combining two distinct issues into one, because iteration now becomes more central to these collections, we should ask what should happen when the contents of the collection change while iteration is in progress. This is of course a thorny problem with any container class in any language so by no means unique to us. It should be noted here that while games are mutable, we do keep a count of how many mutations have occurred in C++ using the GetVersion() member of a game. This could possibly be used to check at each iteration step, with iterators being invalidated (and throwing?) if version numbers don't match. There would be something of an empirical question here about whether that would cause performance problems when we are doing this in C++ in critical loops where we do need to iterate a lot and where the game should be guaranteed to be immutable. One could argue the bigger issue here is in Python, where users can write arbitrary scripts on the fly to transform game models; checking this at the C++ level might be less important because calling code in C++ is likely to be structured not to mutate objects it is iterating over. The cost of such a check in Python would be negligible (compared to all of the other overheads of using Python!)
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
There are a number of places in our model of games where we have collections of objects. For example, we have the collection of information sets belonging to a player, or the collection of outcomes possible in the game.
We have to date allowed indexing these by integers so they are somewhat list-like. However, this poses the following issues:
__getitem__to allow two different modes of indexing; it means these collections are somewhat list-like and somewhat dict-like, which can be argued is a dubious design.We do not use this integer indexing (much?) in the more recent examples we have developed. There are a number of examples of this in the test suite among functions which were written very early in the development of
pygambit. To pull out one at random, we have this function:Perhaps what jumps out most from this is that it's actually quite opaque what this code even does! Rather than talking about information set 0 of each player, it would be much more clear and expressive to write this in terms of a member of the information set we are interested in. A (somewhat) casual survey of the test suite suggests that most of the uses of indexing by integers into collections could profitably be re-written similarly in a more expressive way, that actually makes the tests more meaningful as well.
We also propose that while this is a breaking change, we would strongly consider incorporating this into version 16.7 rather than just having a deprecation warning.
At the risk of combining two distinct issues into one, because iteration now becomes more central to these collections, we should ask what should happen when the contents of the collection change while iteration is in progress. This is of course a thorny problem with any container class in any language so by no means unique to us. It should be noted here that while games are mutable, we do keep a count of how many mutations have occurred in C++ using the
GetVersion()member of a game. This could possibly be used to check at each iteration step, with iterators being invalidated (and throwing?) if version numbers don't match. There would be something of an empirical question here about whether that would cause performance problems when we are doing this in C++ in critical loops where we do need to iterate a lot and where the game should be guaranteed to be immutable. One could argue the bigger issue here is in Python, where users can write arbitrary scripts on the fly to transform game models; checking this at the C++ level might be less important because calling code in C++ is likely to be structured not to mutate objects it is iterating over. The cost of such a check in Python would be negligible (compared to all of the other overheads of using Python!)Beta Was this translation helpful? Give feedback.
All reactions