-
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
Add extra argument to CallListFunc, to wrap return value. #824
Conversation
b7e10d4
to
494342e
Compare
I wanted such a function for quite some time. The only issue I have is with naming. Maybe it is time to formalise the concept of an empty return value and give it a name (and wrap is probably not it ;)). I think you called it the "option type" before, I might call it "Maybe". I don't know whether there are any better names around. |
I didn't really like the name either. I also wondered about introducing an explicit 'option' type. It would be easy to do, but it would I think be about as efficient as this (empty list, plist of length 1 -- you could save 16 bytes on the plist of length 1 case), so I'm not sure it's worth adding a new C-level type for, unless someone wants to build a bunch of extra stuff around it. |
We could just give this pattern a name, and not introduce an explicit type, if people prefer that. It'd be good to get some input from others (@fingolfin, @stevelinton, @frankluebeck come to mind) here. |
How about mimicing what happens on C-level (where NULL is returned to indicate "no return value")? We could introduce a special GAP object, say with name |
The problem with We could forbid GAP-level functions from returning |
We could also make it so that Of course that would make NO_RETURN_VALUE a very special value. It propably should print as the empty string, for consistency (i.e. to match this:
and so on. Still, all in all I am not sure whether complicating the interpreter by adding this special case is a good idea? Is the benefit it provides really substantial enough to justify this? For a time, I thought it was a great idea, and I wanted a |
I'd suggest to go and merge this PR as it does useful thing. I am not sure about the need for a special |
What is the original motivation for this extension? Currently, GAP functions can return nothing or one object. The motivation here must be that there are situations where one does't know if a function returns something or not, and that one would like to find out what is the case. This doesn't seem to be something specific for If such situations really occur (who has convicing examples?), it would be sensible to change GAP such that every function call returns something, where a special object |
Here is my most recent reason, I'll see if I can think of any others. I have a function |
I tried adding a 'no return' / None value to GAP, in #829 . Turned out to be very little change, and (I believe) should be completely backwards compatible with any working code. |
Actually, I also wonder about use cases... And I don't quite recall requesting exactly this, despite what @ChrisJefferson wrote :-) [ don't get me wrong: I don't recall it, but I may very well have done so, and just forgotten. I do recall discussing things related to this for sure, e.g. concerning SuPeRFail etc.. ] As it is, I couldn't give a usecase for this function, though the one @ChrisJefferson mentions is compelling. Hmm, maybe I had a usecase for this in the context of unit testing, but since I am using |
@fingolfin : Maybe There seems to be a family of functions: call a function which may or may not return, and maybe catch if it throws. We can do:
|
In principle, I am fine with this; my only (somewhat weak) concern is that this feels a bit like adding another arbitrary name and function to GAP, in an ad-hoc fashion. Alas, it'll be a rarely used function for a rare problem; plus, GAP is already riddled with arbitrary function and inconsistent names, so this is a very weak counter argument So, all in all, I have no deep objection to this PR. Only question I'd like to raise is whether we want to official document this (in the reference manual), which would mean we essentially could never remove it again; or whether to keep the documentation comment, but not hook it up to the reference manual, thus leaving us a hypothetical way out... But perhaps I am just overly cautious. |
Alternative option: Give This would also let us add things like |
494342e
to
c055f91
Compare
Now changed CallFuncList to take an options record, which includes a single option |
c055f91
to
c088aa1
Compare
Current coverage is 49.49% (diff: 83.33%)@@ master #824 diff @@
==========================================
Files 424 424
Lines 223264 223274 +10
Methods 3429 3430 +1
Messages 0 0
Branches 0 0
==========================================
- Hits 110600 110516 -84
- Misses 112664 112758 +94
Partials 0 0
|
One problem with this version of the PR is that it changes the signature of Next, the GAP library calls The PR also changes Finally, if it was me, I wouldn't want to write code dealing with records on the C level if I didn't have to... in this particular case, I'd either ditch the record, and just use a single extra param; or I'd write a high-level GAP function doing the argument validation, and a low-level C function which takes the extracted params, without doing additional validation. All in all, I wonder if it wouldn't be much simpler and safer to just add a |
I should have looked to see if anyone was using CALL_FUNC_LIST. As you say no-one should, be let's leave it in place. I'll just go back to two C level functions (CALL_FUNC_LIST and CALL_FUNC_LIST_WRAP). That still leaves the issue of the GAP-level function of course. |
I remember why I didn't implement |
Seeing as git, and github, are a bit annoying, I destroyed my original calllistfuncwrap editing this pull request. Woops. |
I'm going to hold on this for a minute, as I think fixing #953 might fix this as part of the fallout. |
@ChrisJefferson I don't understand your explanation why you didin't implement And then you are free to handle record arguments on the GAP level. That said, I am still not convinced this genericy (with a record argument) is necessary. If there was a compelling future usecase, even a purely hypothetical one, OK; but at this point, it seems to just add complexity with no gain. |
c088aa1
to
6fd721a
Compare
Now back to something super-simple. Could technically just have one C function and 2 at the GAP level, but this avoid making a list and unwrapping it if I just had CALL_FUNC_LIST_WRAP at the C level. |
I am fine with merging this. Thouh I still wonder what the usecase is that @ChrisJefferson had in mind... ? i.e. will this be immediately used for something? Or is it more of a theoretical exercise... ? |
I want to use it for generic wrapping for timing. I have a number of functions that look a bit like this:
So I can wrap any functions I want easily, to check which functions are taking time. You can do this with the function profiler, but sometimes I want to record the time taken by every call of a function, to draw nice plots, for example. At the moment I have an extra argument to timeFunction, which records if the function returns a value or not, so I can use |
This has been previously requested by @fingolfin and myself.
Basically, CallListFunc (and GAP in general) doesn't provide a generic way of calling a function and capturing the return value of a function if one exists, but not breaking if there is not.
This adds
CallListFuncWrap
which is exactly the same asCallListFunc
, except it returns a list of size 0 if the function returns nothing, and size 1 if there is a return value (containing that return value).Description of changes (for the release notes)
Add CallListFuncWrap, an extension to CallListFunc which allows generic code to handle functions which may or may not return a value.