-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Flaw in recursive conversion in gap_to_julia
#275
Comments
Here is an updated version of the example which actually demonstrates the issue (converting to
So what happens here is that we convert But at least we got an error, that's good! Perhaps we should change all conversion methods to use the That would then actually be one way to safely resolve the issue, in that we provide minimal consistent behavior; in particular we remove buggy behavior, before people start relying on it. Then if somebody requests it, we can think about whether we can allow some or all of these cases. Some approaches that come to mind:
|
I would lean towards option 3., I think this should be almost free performance-wise, and probably doesn't add more complexity than other options. |
Yes, I would also prefer option 3. I will provide a pull request. |
I wonder whether option 3 is really a good idea, though, and that it wouldn't produce weird or surprising results. I don't have an example ready, and they might in fact not exist, but I worry about something like the following:
Of course this actually produces an error right now, as This is kinda a very special situation; my point just is that once we started to accept this and process it in a certain way, people will eventually start to rely on it and then it'll become difficult to change again. |
That's a good point; it could be made into an error. But I now lean towards option 1. :) |
This is a hypothetical bug, though I am fairly certain one can construct actual problematic examples:
gap_to_julia
caches conversion results in anIdDict
with namerecursion_dict
. This is meant to ensure that if an object occurs multiple times in the input, it is each time mapped to the same / identical object in the output.But at the same time, we allow the user some degree of control over outputs, and so in some cases a GAP Obj may not be converted at all (i.e., left as a Julia object of type
MPtr
), while in other cases it could be converted to something else, e.g. a Julia array. Now it is conceivable that for some inputs, the same object is converted twice, but in each case is supposed to be converted to different output types. E.g. perhaps we ask Julia to produce aTuple{MPtr, String}
and give it as input a GAP list[ x, x ]
wherex
is a GAP strings.I think (w/o having tried it) that in this case, things will go wrong: because we end up storing in
recursion_dict
thatx
is mapped to itself (because for the first tuple element, we asked it to be left as a GAP string), and then when it comes to set the second entry, we are supposed to convert the GAP string to a Julia string -- but because a conversion forx
is already cached inrecursion_dict
, we don't, and so instead return the GAP string once again.Trying to do this (see below) right now actually does not produce a failure. But that's just because our tuple conversion function is buggy and does not use
recursion_dict
:-). But note that this problem is not necessarily exclusive to tuples.To fix this, I think we need to cache not just the object we converted, but also the type we asked it to be converted to. But that opens a new can of works: If we once ask the object to be converted to
String
and onceAbstractString
, we may very well get two objects of typeString
. But should the conversion result here be two identical Julia strings, or not? If yes: how do we implement this?In any case, it seems we really really need to document the (intended) semantics of this, and add far more tests to check for other such problems systematically.
The text was updated successfully, but these errors were encountered: