The feature of functions having <static>
variables is implemented by making an OBJECT! holding those variables, and then binding the body of the function to that object.
You can give code in a GROUP! after the static to provide its initial value.
foo: func [x <static> s (5 + 5)] [
print ["static is" s]
s: s + x
]
>> foo 20
static is 10
>> foo 100
static is 30
>> foo 0
static is 130
And so on. So effectively there is code here which is:
make object! [
s: (5 + 5)
]
Now, what should the specifier/environment for that GROUP! of code be? We can argue it should be whatever it would be in the spec... the spec block had a context, and then maybe the GROUP! has one that overrides it, but if not it should be the same as the spec.
Under that logic, we expect the following to work:
n: 5
foo: func [x <static> s (n + 5)] [
print ["static is" s]
s: s + x
]
This would seem to mean that the BLOCK! we pass to MAKE OBJECT! doesn't need an environment, relying on MAKE OBJECT! to add the object context so the s: has a binding, but then the GROUP! evaluates however it wishes.
And that appears to work, until the statics try to depend on each other:
n: 5
foo: func [x <static> s1 (5 + 5) s2 (s1 + 5)] [
print ["statics are" s1 s2]
s1: s1 + x
s2: s2 + x
]
(Instances of this were encountered in the HTTP server.)
If this is to work, you have to somehow allow the object's binding to penetrate the groups. One avenue of attack could be to unbind the groups and then move the spec's binding onto the block passed to MAKE OBJECT! instead of leaving it unbound. But if the GROUP! was bound to somewhere in particular vs. just getting the default binding of what was in the spec, you lose that information.
If you're going to try specifically grafting the object's context onto the groups, you might do it more like:
make object! [
s1: do overbind tip of [] [5 + 5]
s2: do overbind tip of [] [s1 + 5] ; s1 + 5 block has established binding
]
I'm using TIP OF there as a way of getting the top thing in the environment, as a way of extracting the object. Perhaps that could be the default behavior of an OVERBIND instruction (that it should know not to try and deeply insinuate all the way down to the user/lib contexts on top of something that already has contexts).
In order to get things to work for now, I'm going to just unbind the groups, and bind the block passed to make object! to match the spec. But a better answer is needed.