gap
gap copied to clipboard
Add a convenient way to display bindings inside of closures
Consider this:
gap> f := ApplicableMethod( OrbitsDomain, [ SymmetricGroup(5), [1..5] ] );;
gap> Display(f);
function ( G, D )
if D = MovedPoints( G ) then
return op( G );
else
TryNextMethod();
fi;
return;
end
Quick, what is "op" standing for here?...
Well, of course again for OrbitsDomain
.
Code that generates code by using closures can be super helpful and nice, but a nighmare to debug, largely because it can be so tricky to figure out the bindings inside a closure. A more direct example would be this:
gap> makeFun:=n -> x -> x + n;;
gap> f:=makeFun(42);;
gap> Display(f);
function ( x )
return x + n;
end
If you hadn't seen the definition of f
here, you'd have no way to know what n
is. This should be different.
Note by @wilfwilson: Since creating this PR, @fingolfin has added the function BindingsOfClosure
, which allows one to see and to access these variables in PR #3606. Thus we now get:
gap> BindingsOfClosure(f);
rec( n := 42 )
Note that this function is undocumented, so it might be nice to have some kind of documentation for it if someone feels like it while addressing this issue. End of note by @wilfwilson.
I suggest that we use BindingsOfClosure
to add a way to view the local bindings of a function; at least the ones that are actually used in it. We could then show it when "Displaying" the function.
gap> Display(f);
# function closure with bindings:
# n = 42
function ( x )
return x + n;
end
Of course the "bindings" are strictly speaking all locals (including arguments) of the parent function of the given function (and this can potentially go back recursively). Coming back to the initial OrbitsDomain
example, the parent function is OrbitsishOperation
and it starts like this:
BindGlobal( "OrbitsishOperation", function( name, reqs, usetype, NewAorP )
local op;
# Create the attribute or property.
op:= NewAorP( name, IsExternalSet );
...
So the "bindings" in my initial example actually also include name
, reqs
, usetype
and NewAorP
. But I think that's usually actually quite helpful.