gap icon indicating copy to clipboard operation
gap copied to clipboard

`ProfileGlobalFunctions` vs. `ProfileFunctionsInGlobalVariables`

Open ThomasBreuer opened this issue 5 months ago • 5 comments

Since GAP 4.12.0, it is recommended to use DeclareGlobalName instead of DeclareGlobalFunction where possible. Still there is a documented function ProfileGlobalFunctions that deals with the functions created with DeclareGlobalFunction. There is also the undocumented ProfileFunctionsInGlobalVariables, which would be more appropriate from the viewpoint that more and more entries might disappear from the list GLOBAL_FUNCTION_NAMES. I admit that ProfileFunctionsInGlobalVariables is something different, since it considers many more functions than ProfileGlobalFunctions ever did.

Would it make sense to document ProfileFunctionsInGlobalVariables, and to mention in the documentation of ProfileGlobalFunctions that the function may be no longer meaningful, due to the switch from DeclareGlobalFunction to DeclareGlobalName?

ThomasBreuer avatar Aug 11 '25 10:08 ThomasBreuer

After a discussion with @fingolfin, we think that an easy "fix" would be to change DeclareGlobalName such that those variables that have these names and are functions are considered by ProfileGlobalFunctions.

This will just help to avoid confusions about some functions suddenly disappearing from the profiling results in a new GAP version where DeclareGlobalName is used instead of DeclareGlobalFunction. Since many variables in GAP get bound with BindGlobal or even by a plain assignment (without write protection), the set of functions described by ProfileGlobalFunctions has always been quite arbitrary.

Perhaps @ChrisJefferson has some comments?

ThomasBreuer avatar Aug 13 '25 08:08 ThomasBreuer

As a result of seeing this conversation, I have changed the 24 instances of DeclareGlobalFunction in the Utils package. There are 84 further instances in packages which I maintain - I presume it is sensible to change these also?

cdwensley avatar Aug 13 '25 08:08 cdwensley

I presume it is sensible to change these also?

In principle yes, but one has to be a bit careful with that change:

If you introduce a function in package A, and another package B accesses this function (for example by putting it into a list or a record) AND if the code of package B gets read before the code of package A then GAP runs into an error if only the name of the function has been declared in package A, whereas DeclareGlobalFunction has already created the function.

In such a situation, the clean solution is that package B moves code where the function from package A is used into a package extension, dependent on package A. This code will then be read only after package A has been loaded completely. (In fact, it is then even possible to call the function from package A inside the code of such a package extension.) However, this requires a change in package B, and in general this is a task for someone else.

That said, the way to find out whether such a problem occurs is to make the changes, and to see what happens.

ThomasBreuer avatar Aug 13 '25 09:08 ThomasBreuer

Thanks for that detailed explanation, which I do not altogether understand.

That said, the way to find out whether such a problem occurs is to make the changes, and to see what happens.

I think that advice also applies to the function SubdirectProductWithEmbeddings in Utils, so I will delete that material, release a new Utils, and indeed see what happens.

cdwensley avatar Aug 13 '25 09:08 cdwensley

The situation Thomas described, were someone took a function declared via DeclareGlobalFunction but not yet defined, and stored it somewhere, will indeed run into an error if one uses DeclareGlobalName instead. In so far such a change is "safe": while it could break code, it can only do so in a loud, obvious way; it cannot cause silent breakage.

And personally I would consider finding and resolving such situations an improvement. However, I don't recall encountering such a situation.

Anyway, all in all, I am not much concerned about code using DeclareGlobalFunction, and I don't see a strong reason to change code to not to use it.

I am far more concerned about uses of DeclareGlobalVariable with values that are not "plain" objects (i.e., plain lists, plain records, plain strings, ...). Luckily I think by now we eliminated all such uses (see PR #6067)

fingolfin avatar Aug 24 '25 20:08 fingolfin