gap-system / gap

Main development repository for GAP - Groups, Algorithms, Programming, a System for Computational Discrete Algebra
https://www.gap-system.org
GNU General Public License v2.0
813 stars 161 forks source link

SYNTAX_TREE does not handle nested functions correctly #5166

Open ChrisJefferson opened 2 years ago

ChrisJefferson commented 2 years ago

Consider the following function (which returns a function, which refers to a variable it's outer scope). x := function() local a; a:=2; return function() return a; end; end;

Calling SYNTAX_TREE(x) works completely fine. However, SYNTAX_TREE(x()) (that is, on the inner function) loses where a is, and SYNTAX_TREE_CODE(SYNTAX_TREE(x()) produces an invalid function, which can't be printed and produces invalid answers when called.

It's not immediately obvious how to fix this -- we could store the "parent" member of the LVARS, and restore it, but then the result of SYNTAX_TREE would no longer just be "data", it would include an opaque GAP pointer.

Note that running SYNTAX_TREE on x itself works fine, as we still have the outer function, it' just running SYNTAX_TREE on the inner function by itself.

zickgraf commented 2 years ago

In my applications I explicitly resolve references to variables in the context by using ENVI_FUNC( func ) and ContentsLVars. I put the result in (newly created) global variables and reference those in the syntax tree. Then the code at least runs while I stay in the same session.

In our setting, one always has a category as context. If the references to variables in the context actually reference attributes of this category, I can use some tricks to get them from the category again in a later session. This allows me to also generate code which can be used in later sessions.

Having some kind of "official" support for such cases would of course be nice, but I guess there is no perfect solution for this.

ChrisJefferson commented 2 years ago

I'm glad to hear you are having some success. I was considering just banning HVARS until we make them work properly, but I won't do that as it sounds like you are already using them successfully with care.

zickgraf commented 2 years ago

I was considering just banning HVARS until we make them work properly

Maybe banning them in SYNTAX_TREE_CODE would be a good idea? I assume it's very hard (if not impossible) to call SYNTAX_TREE_CODE in a context where HVARs are actually coded to something useful. That would solve the problem of unprintable functions which give weird answers when called.

but I won't do that as it sounds like you are already using them successfully with care

Yes, in the output of SYNTAX_TREE the HVARs are useful!