-
Notifications
You must be signed in to change notification settings - Fork 162
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
Alternative to handle functions returning no value #831
Conversation
This is an experiment to allow users statements like a := fu(); even if fu() does not return a value. In this case the statement unbinds 'a' so that one can detect that fu() did not return a value by 'IsBound(a);'. The behaviour is similar for assignments to lists or record components where statements like l[i] := fu(); r.comp := fu(); in case of fu() not returning a value have the effect of Unbind(l[i]); Unbind(r.comp);
When I wanted to propose a simpler way to create a 'NoValue' object in GAP on GAP level (see "Add a generic 'no return' value to GAP" #829) and thought about a sensible behaviour of this special object, an alternative idea occurred to me. In short: assigning results of functions which do not return a value behaves like unbinding. Here is an example session with the code from this pull request:
This should be completely backward compatible with correct current GAP code. It only allows one to use statements which ran into an error before (and now can be catched by the user, or will lead to an error in some other place). Does this look reasonable. (This is a quick hack for an experiment. It is likely, that more changes are needed and that some of the current changes can be achieved a bit easier.) |
I really like this idea, it mirrors what assign "None" to an array or hash entry does in Python, without forcing us to introduce a new singleton variable. Still feel I should think a bit more about the consequence, though :-). |
default: | ||
ASS_REC( record, rnam, rhs ); | ||
break; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nitpick: This looses the optimization (?) for T_COMOBJ. But since AssPRec
was modified to deal with rhs==0 anyway, the if (rhs == 0)
check could be moved right next to ASS_REC.
Or, going one further, one could modify ASS_REC (andd ASS_LIST, ASSB_LIST, ...) to perform that check, thus making many other changes in this PR redundant. Alas, this might incur a speed penalty. Not sure how bad that would be in practice, though?
One (minor?) concern is the loss of "transitivity of assignment". I.e.
but this does not:
Based on this, a logical extrapolition would be to allow assigning or returning unbound variables (with the effecting of unbinding the target resp. returning nothing) -- but don't get me wrong, I am not claiming this is a good idea, to the contrary, I am sceptical... That said, this is right now just a hypothetical concern. But I'd like to think this through very carefully before making this change... |
Having thought about this, I think it's "too clever", I don't think it will get much use, but I think it will confuse people when functions don't return values. I'd prefer to go back to Remark by @alex-konovalov: |
Is this really "too clever"? Python essentialy does the same, and nobody seems to consider it confusing -- but then, of course, they have an expicit Of course this feature would be very, very rarely used to begin with. And of course one would have to be careful about documenting it clearly... And this method is certainly more convenient than having to use Now, my only concerns with So I guess for now the conservative choice is to add |
My issue with this is how many people would do this on purpose, and how many people will assign the return value of a function that doesn't return a value accidentally, and then get confused? I suspect the second would be more common. |
I still think this is an interesting idea. But I have no objections if this experimental pull request is rejected and ChrisJefferson's variant of |
While I like this idea, I think we are in agreement it's too big a change -- certainly without more support. Just because it is closed doesn't mean someone can't bring it back if they want to champion it and/or improve it. |
This is an experiment to allow users statements like
a := fu();
even if fu() does not return a value. In this case the statement
unbinds 'a' so that one can detect that fu() did not return a value
by 'IsBound(a);'.
The behaviour is similar for assignments to lists or record components
where statements like
l[i] := fu();
r.comp := fu();
in case of fu() not returning a value have the effect of
Unbind(l[i]);
Unbind(r.comp);