google / starlark-go

Starlark in Go: the Starlark configuration language, implemented in Go
BSD 3-Clause "New" or "Revised" License
2.26k stars 204 forks source link

Need a way to know if a variable is updated #550

Closed jayaprabhakar closed 1 month ago

jayaprabhakar commented 1 month ago

I am using Starlark to build a Python'ish formal methods language. To achieve an important feature while keep the language simple, I need a way to know if a variable was updated (the old and the new value might be equal, but still an attempt was made).

For example: If the current values of the predefined/globals are

a=0
b=0
c=0

Now, if I execute the code:

a=1
b=0

I want to find out a and b are updated but c was not.

Is it possible to do this already? If not is there a way to accomplish this. It is not sufficient to find when the value changes, I want to know if there was any attempt to change the value of the variables.

adonovan commented 1 month ago

Is it possible to do this already? If not is there a way to accomplish this? It is not sufficient to find when the value changes, I want to know if there was any attempt to change the value of the variables.

No, and no: not without changing code in the starlark (interpreter) package.

The compiler translates all assignments to global variables to SETGLOBAL instructions. The interpreter code for this instruction simply update the module's global array:

        case compile.SETGLOBAL:
            fn.module.globals[arg] = stack[sp-1]
            sp--

So there is no hook here to detect that it occurred, and it doesn't seem to me like a feature the interpreter should support.

You could easily change the logic here to record the fact that it occurred, but of course then you'd be working on a fork of the interpreter.

jayaprabhakar commented 1 month ago

Thanks @adonovan that makes sense to not support it in starlark directly. That said, I will try a fork or see if there's an alternative. Btw, besides assignments to global variables, how to check if a value like map was updated? Like updates to a map or set? Any pointers would be helpful

adonovan commented 1 month ago

Btw, besides assignments to global variables, how to check if a value like map was updated? Like updates to a map or set? Any pointers would be helpful

Trying to track every place in the interpreter that mutates a data structure is an invasive change. I'm afraid I don't have any good suggestions.